diff options
author | Vinnie Okada <vokada@mrvinn.com> | 2014-12-08 06:25:58 +0300 |
---|---|---|
committer | Vinnie Okada <vokada@mrvinn.com> | 2014-12-08 06:25:58 +0300 |
commit | 742e6eeed221489d5f35bdfde2e6ce55db75d25f (patch) | |
tree | 710c01fbd18e81a7590819161434e19855e35a97 /spec | |
parent | 7a5072c5a8f03cd7342a5f8e74e1fde0250ce360 (diff) | |
parent | bbf9953b99d59801c72dd7b9550ee149ca77bfcf (diff) |
Merge branch 'upstream-master' into markdown-preview
Conflicts:
spec/routing/project_routing_spec.rb
Diffstat (limited to 'spec')
46 files changed, 1016 insertions, 364 deletions
diff --git a/spec/controllers/branches_controller_spec.rb b/spec/controllers/branches_controller_spec.rb new file mode 100644 index 00000000000..610d7a84e31 --- /dev/null +++ b/spec/controllers/branches_controller_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Projects::BranchesController do + let(:project) { create(:project) } + let(:user) { create(:user) } + + before do + sign_in(user) + + project.team << [user, :master] + + project.stub(:branches).and_return(['master', 'foo/bar/baz']) + project.stub(:tags).and_return(['v1.0.0', 'v2.0.0']) + controller.instance_variable_set(:@project, project) + end + + describe "POST create" do + render_views + + before { + post :create, + project_id: project.to_param, + branch_name: branch, + ref: ref + } + + context "valid branch name, valid source" do + let(:branch) { "merge_branch" } + let(:ref) { "master" } + it { should redirect_to("/#{project.path_with_namespace}/tree/merge_branch") } + end + + context "invalid branch name, valid ref" do + let(:branch) { "<script>alert('merge');</script>" } + let(:ref) { "master" } + it { should redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") } + end + + context "valid branch name, invalid ref" do + let(:branch) { "merge_branch" } + let(:ref) { "<script>alert('ref');</script>" } + it { should render_template("new") } + end + + context "invalid branch name, invalid ref" do + let(:branch) { "<script>alert('merge');</script>" } + let(:ref) { "<script>alert('ref');</script>" } + it { should render_template("new") } + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb index 15899d8c3c4..58060131638 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -18,15 +18,24 @@ FactoryGirl.define do password "12345678" password_confirmation { password } confirmed_at { Time.now } - confirmation_token { nil } + confirmation_token { nil } trait :admin do admin true end - trait :ldap do - provider 'ldapmain' - extern_uid 'my-ldap-id' + factory :omniauth_user do + ignore do + extern_uid '123456' + provider 'ldapmain' + end + + after(:create) do |user, evaluator| + user.identities << create(:identity, + provider: evaluator.provider, + extern_uid: evaluator.extern_uid + ) + end end factory :admin, traits: [:admin] @@ -182,4 +191,9 @@ FactoryGirl.define do deploy_key project end + + factory :identity do + provider 'ldapmain' + extern_uid 'my-ldap-id' + end end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 23314b3b1a4..60eb73e4a95 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -27,6 +27,10 @@ # FactoryGirl.define do + # Project without repository + # + # Project does not have bare repository. + # Use this factory if you dont need repository in tests factory :empty_project, class: 'Project' do sequence(:name) { |n| "project#{n}" } path { name.downcase.gsub(/\s/, '_') } @@ -47,6 +51,20 @@ FactoryGirl.define do end end + # Project with empty repository + # + # This is a case when you just created a project + # but not pushed any code there yet + factory :project_empty_repo, parent: :empty_project do + after :create do |project| + project.create_repository + end + end + + # Project with test repository + # + # Test repository source can be found at + # https://gitlab.com/gitlab-org/gitlab-test factory :project, parent: :empty_project do path { 'gitlabhq' } diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb new file mode 100644 index 00000000000..746b6fc1ac9 --- /dev/null +++ b/spec/features/atom/users_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe "User Feed", feature: true do + describe "GET /" do + let!(:user) { create(:user) } + + context "user atom feed via private token" do + it "should render user atom feed" do + visit user_path(user, :atom, private_token: user.private_token) + body.should have_selector("feed title") + end + end + + context 'feed content' do + let(:project) { create(:project) } + let(:issue) { create(:issue, project: project, author: user, description: '') } + let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) } + + before do + project.team << [user, :master] + issue_event(issue, user) + note_event(note, user) + visit user_path(user, :atom, private_token: user.private_token) + end + + it "should have issue opened event" do + body.should have_content("#{user.name} opened issue ##{issue.iid}") + end + + it "should have issue comment event" do + body.should have_content("#{user.name} commented on issue ##{issue.iid}") + end + end + end + + def issue_event(issue, user) + EventCreateService.new.open_issue(issue, user) + end + + def note_event(note, user) + EventCreateService.new.leave_note(note, user) + end +end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 98ba5a47ee5..d291621935b 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe "Projects", feature: true do +describe "Projects", feature: true, js: true do before { login_as :user } describe "DELETE /projects/:id" do @@ -10,12 +10,23 @@ describe "Projects", feature: true do visit edit_project_path(@project) end - it "should be correct path", js: true do - expect { - click_link "Remove project" - fill_in 'confirm_name_input', with: @project.path - click_button 'Confirm' - }.to change {Project.count}.by(-1) + it "should remove project" do + expect { remove_project }.to change {Project.count}.by(-1) end + + it 'should delete the project from disk' do + expect(GitlabShellWorker).to( + receive(:perform_async).with(:remove_repository, + /#{@project.path_with_namespace}/) + ).twice + + remove_project + end + end + + def remove_project + click_link "Remove project" + fill_in 'confirm_name_input', with: @project.path + click_button 'Confirm' end end diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index 7b831c48611..a1206989d39 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -11,7 +11,7 @@ describe 'Users', feature: true do fill_in "user_name", with: "Name Surname" fill_in "user_username", with: "Great" fill_in "user_email", with: "name@mail.com" - fill_in "user_password", with: "password1234" + fill_in "user_password_sign_up", with: "password1234" fill_in "user_password_confirmation", with: "password1234" expect { click_button "Sign up" }.to change {User.count}.by(1) end diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index 7489e56f423..06e247aea61 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -5,9 +5,10 @@ describe IssuesFinder do let(:user2) { create :user } let(:project1) { create(:project) } let(:project2) { create(:project) } - let(:issue1) { create(:issue, assignee: user, project: project1) } - let(:issue2) { create(:issue, assignee: user, project: project2) } - let(:issue3) { create(:issue, assignee: user2, project: project2) } + let(:milestone) { create(:milestone, project: project1) } + let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) } + let(:issue2) { create(:issue, author: user, assignee: user, project: project2) } + let(:issue3) { create(:issue, author: user2, assignee: user2, project: project2) } before do project1.team << [user, :master] @@ -22,37 +23,59 @@ describe IssuesFinder do issue3 end - it 'should filter by all' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - issues.size.should == 3 - end + context 'scope: all' do + it 'should filter by all' do + params = { scope: "all", state: 'opened' } + issues = IssuesFinder.new.execute(user, params) + issues.size.should == 3 + end - it 'should filter by assignee' do - params = { scope: "assigned-to-me", state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - issues.size.should == 2 - end + it 'should filter by assignee id' do + params = { scope: "all", assignee_id: user.id, state: 'opened' } + issues = IssuesFinder.new.execute(user, params) + issues.size.should == 2 + end - it 'should filter by project' do - params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } - issues = IssuesFinder.new.execute(user, params) - issues.size.should == 1 - end + it 'should filter by author id' do + params = { scope: "all", author_id: user2.id, state: 'opened' } + issues = IssuesFinder.new.execute(user, params) + issues.should == [issue3] + end - it 'should be empty for unauthorized user' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(nil, params) - issues.size.should be_zero + it 'should filter by milestone id' do + params = { scope: "all", milestone_id: milestone.id, state: 'opened' } + issues = IssuesFinder.new.execute(user, params) + issues.should == [issue1] + end + + it 'should be empty for unauthorized user' do + params = { scope: "all", state: 'opened' } + issues = IssuesFinder.new.execute(nil, params) + issues.size.should be_zero + end + + it 'should not include unauthorized issues' do + params = { scope: "all", state: 'opened' } + issues = IssuesFinder.new.execute(user2, params) + issues.size.should == 2 + issues.should_not include(issue1) + issues.should include(issue2) + issues.should include(issue3) + end end - it 'should not include unauthorized issues' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(user2, params) - issues.size.should == 2 - issues.should_not include(issue1) - issues.should include(issue2) - issues.should include(issue3) + context 'personal scope' do + it 'should filter by assignee' do + params = { scope: "assigned-to-me", state: 'opened' } + issues = IssuesFinder.new.execute(user, params) + issues.size.should == 2 + end + + it 'should filter by project' do + params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } + issues = IssuesFinder.new.execute(user, params) + issues.size.should == 1 + end end end end diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb index 5af76968183..c645cbc964c 100644 --- a/spec/finders/snippets_finder_spec.rb +++ b/spec/finders/snippets_finder_spec.rb @@ -64,6 +64,13 @@ describe SnippetsFinder do snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user) snippets.should include(@snippet1, @snippet2, @snippet3) end + + it "returns only public snippets if unauthenticated user" do + snippets = SnippetsFinder.new.execute(nil, filter: :by_user, user: user) + snippets.should include(@snippet3) + snippets.should_not include(@snippet2, @snippet1) + end + end context 'by_project filter' do diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 2db67cfdf95..07dd33b211b 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -66,6 +66,16 @@ describe ApplicationHelper do avatar_icon(user.email).to_s.should match("/uploads/user/avatar/#{ user.id }/gitlab_logo.png") end + it "should return an url for the avatar with relative url" do + Gitlab.config.gitlab.stub(relative_url_root: "/gitlab") + Gitlab.config.gitlab.stub(url: Settings.send(:build_gitlab_url)) + + user = create(:user) + user.avatar = File.open(avatar_file_path) + user.save! + avatar_icon(user.email).to_s.should match("/gitlab//uploads/user/avatar/#{ user.id }/gitlab_logo.png") + end + it "should call gravatar_icon when no avatar is present" do user = create(:user, email: 'test@example.com') user.save! diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 61751a82369..3c636b747d1 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -594,7 +594,9 @@ describe GitlabMarkdownHelper do end it "should generate absolute urls for emoji" do - markdown(":smile:").should include("src=\"http://localhost/assets/emoji/smile.png") + markdown(':smile:').should( + include(%(src="#{Gitlab.config.gitlab.url}/assets/emoji/smile.png)) + ) end it "should generate absolute urls for emoji if relative url is present" do diff --git a/spec/helpers/oauth_helper_spec.rb b/spec/helpers/oauth_helper_spec.rb new file mode 100644 index 00000000000..453699136e9 --- /dev/null +++ b/spec/helpers/oauth_helper_spec.rb @@ -0,0 +1,20 @@ +require "spec_helper" + +describe OauthHelper do + describe "additional_providers" do + it 'returns all enabled providers' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :github] } + helper.additional_providers.should include(*[:twitter, :github]) + end + + it 'does not return ldap provider' do + allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :ldapmain] } + helper.additional_providers.should include(:twitter) + end + + it 'returns empty array' do + allow(helper).to receive(:enabled_oauth_providers) { [] } + helper.additional_providers.should == [] + end + end +end
\ No newline at end of file diff --git a/spec/lib/disable_email_interceptor_spec.rb b/spec/lib/disable_email_interceptor_spec.rb new file mode 100644 index 00000000000..8bf6ee2ed50 --- /dev/null +++ b/spec/lib/disable_email_interceptor_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe DisableEmailInterceptor do + before do + ActionMailer::Base.register_interceptor(DisableEmailInterceptor) + end + + it 'should not send emails' do + Gitlab.config.gitlab.stub(:email_enabled).and_return(false) + expect { + deliver_mail + }.not_to change(ActionMailer::Base.deliveries, :count) + end + + after do + # Removing interceptor from the list because unregister_interceptor is + # implemented in later version of mail gem + # See: https://github.com/mikel/mail/pull/705 + Mail.class_variable_set(:@@delivery_interceptors, []) + end + + def deliver_mail + key = create :personal_key + Notify.new_ssh_key_email(key.id) + end +end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 1f3e1a4a3c1..95fc7e16a11 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -10,13 +10,21 @@ describe Gitlab::Auth do password: password, password_confirmation: password) end - let(:username) { 'john' } + let(:username) { 'John' } # username isn't lowercase, test this let(:password) { 'my-secret' } it "should find user by valid login/password" do expect( gl_auth.find(username, password) ).to eql user end + it 'should find user by valid email/password with case-insensitive email' do + expect(gl_auth.find(user.email.upcase, password)).to eql user + end + + it 'should find user by valid username/password with case-insensitive username' do + expect(gl_auth.find(username.upcase, password)).to eql user + end + it "should not find user with invalid password" do password = 'wrong' expect( gl_auth.find(username, password) ).to_not eql user diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 570b03827a8..66e87e57cbc 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -5,14 +5,14 @@ describe Gitlab::GitAccess do let(:project) { create(:project) } let(:user) { create(:user) } - describe 'download_allowed?' do + describe 'download_access_check' do describe 'master permissions' do before { project.team << [user, :master] } context 'pull code' do - subject { access.download_allowed?(user, project) } + subject { access.download_access_check(user, project) } - it { should be_true } + it { subject.allowed?.should be_true } end end @@ -20,9 +20,9 @@ describe Gitlab::GitAccess do before { project.team << [user, :guest] } context 'pull code' do - subject { access.download_allowed?(user, project) } + subject { access.download_access_check(user, project) } - it { should be_false } + it { subject.allowed?.should be_false } end end @@ -33,34 +33,54 @@ describe Gitlab::GitAccess do end context 'pull code' do - subject { access.download_allowed?(user, project) } + subject { access.download_access_check(user, project) } - it { should be_false } + it { subject.allowed?.should be_false } end end describe 'without acccess to project' do context 'pull code' do - subject { access.download_allowed?(user, project) } + subject { access.download_access_check(user, project) } - it { should be_false } + it { subject.allowed?.should be_false } + end + end + + describe 'deploy key permissions' do + let(:key) { create(:deploy_key) } + + context 'pull code' do + context 'allowed' do + before { key.projects << project } + subject { access.download_access_check(key, project) } + + it { subject.allowed?.should be_true } + end + + context 'denied' do + subject { access.download_access_check(key, project) } + + it { subject.allowed?.should be_false } + end end end end - describe 'push_allowed?' do + describe 'push_access_check' do def protect_feature_branch create(:protected_branch, name: 'feature', project: project) end def changes { - push_new_branch: '000000000 570e7b2ab refs/heads/wow', + push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow", push_master: '6f6d7e7ed 570e7b2ab refs/heads/master', push_protected_branch: '6f6d7e7ed 570e7b2ab refs/heads/feature', - push_remove_protected_branch: '570e7b2ab 000000000 refs/heads/feature', + push_remove_protected_branch: "570e7b2ab #{Gitlab::Git::BLANK_SHA} "\ + 'refs/heads/feature', push_tag: '6f6d7e7ed 570e7b2ab refs/tags/v1.0.0', - push_new_tag: '000000000 570e7b2ab refs/tags/v7.8.9', + push_new_tag: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/tags/v7.8.9", push_all: ['6f6d7e7ed 570e7b2ab refs/heads/master', '6f6d7e7ed 570e7b2ab refs/heads/feature'] } end @@ -116,9 +136,9 @@ describe Gitlab::GitAccess do permissions_matrix[role].each do |action, allowed| context action do - subject { access.push_allowed?(user, project, changes[action]) } + subject { access.push_access_check(user, project, changes[action]) } - it { should allowed ? be_true : be_false } + it { subject.allowed?.should allowed ? be_true : be_false } end end end diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb index ed5785b31e6..4ff45c0c616 100644 --- a/spec/lib/gitlab/git_access_wiki_spec.rb +++ b/spec/lib/gitlab/git_access_wiki_spec.rb @@ -11,9 +11,9 @@ describe Gitlab::GitAccessWiki do project.team << [user, :developer] end - subject { access.push_allowed?(user, project, changes) } + subject { access.push_access_check(user, project, changes) } - it { should be_true } + it { subject.allowed?.should be_true } end def changes diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb index f4d5a927396..4573b8696c4 100644 --- a/spec/lib/gitlab/ldap/access_spec.rb +++ b/spec/lib/gitlab/ldap/access_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::LDAP::Access do let(:access) { Gitlab::LDAP::Access.new user } - let(:user) { create(:user, :ldap) } + let(:user) { create(:omniauth_user) } describe :allowed? do subject { access.allowed? } diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb index 0eb7c443b8b..11fdf108756 100644 --- a/spec/lib/gitlab/ldap/authentication_spec.rb +++ b/spec/lib/gitlab/ldap/authentication_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::LDAP::Authentication do let(:klass) { Gitlab::LDAP::Authentication } - let(:user) { create(:user, :ldap, extern_uid: dn) } + let(:user) { create(:omniauth_user, extern_uid: dn) } let(:dn) { 'uid=john,ou=people,dc=example,dc=com' } let(:login) { 'john' } let(:password) { 'password' } diff --git a/spec/lib/gitlab/ldap/config_spec.rb b/spec/lib/gitlab/ldap/config_spec.rb index 76cc7f95c47..3ebb8aae243 100644 --- a/spec/lib/gitlab/ldap/config_spec.rb +++ b/spec/lib/gitlab/ldap/config_spec.rb @@ -16,5 +16,19 @@ describe Gitlab::LDAP::Config do it "raises an error if a unknow provider is used" do expect{ Gitlab::LDAP::Config.new 'unknown' }.to raise_error end + + context "if 'ldap' is the provider name" do + let(:provider) { 'ldap' } + + context "and 'ldap' is not in defined as a provider" do + before { Gitlab::LDAP::Config.stub(providers: %w{ldapmain}) } + + it "uses the first provider" do + # Fetch the provider_name attribute from 'options' so that we know + # that the 'options' Hash is not empty/nil. + expect(config.options['provider_name']).to eq('ldapmain') + end + end + end end -end
\ No newline at end of file +end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 726c9764e3d..f73884e6441 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -15,18 +15,18 @@ describe Gitlab::LDAP::User do describe :find_or_create do it "finds the user if already existing" do - existing_user = create(:user, extern_uid: 'my-uid', provider: 'ldapmain') + existing_user = create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain') expect{ gl_user.save }.to_not change{ User.count } end it "connects to existing non-ldap user if the email matches" do - existing_user = create(:user, email: 'john@example.com') + existing_user = create(:omniauth_user, email: 'john@example.com', provider: "twitter") expect{ gl_user.save }.to_not change{ User.count } existing_user.reload - expect(existing_user.extern_uid).to eql 'my-uid' - expect(existing_user.provider).to eql 'ldapmain' + expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid' + expect(existing_user.ldap_identity.provider).to eql 'ldapmain' end it "creates a new user if not found" do diff --git a/spec/lib/gitlab/oauth/user_spec.rb b/spec/lib/gitlab/oauth/user_spec.rb index e4e96fd9f49..88307515789 100644 --- a/spec/lib/gitlab/oauth/user_spec.rb +++ b/spec/lib/gitlab/oauth/user_spec.rb @@ -15,7 +15,7 @@ describe Gitlab::OAuth::User do end describe :persisted? do - let!(:existing_user) { create(:user, extern_uid: 'my-uid', provider: 'my-provider') } + let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') } it "finds an existing user based on uid and provider (facebook)" do auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider') @@ -29,26 +29,80 @@ describe Gitlab::OAuth::User do end describe :save do - context "LDAP" do - let(:provider) { 'ldap' } - it "creates a user from LDAP" do - oauth_user.save - - expect(gl_user).to be_valid - expect(gl_user.extern_uid).to eql uid - expect(gl_user.provider).to eql 'ldap' + let(:provider) { 'twitter' } + + describe 'signup' do + context "with allow_single_sign_on enabled" do + before { Gitlab.config.omniauth.stub allow_single_sign_on: true } + + it "creates a user from Omniauth" do + oauth_user.save + + expect(gl_user).to be_valid + identity = gl_user.identities.first + expect(identity.extern_uid).to eql uid + expect(identity.provider).to eql 'twitter' + end + end + + context "with allow_single_sign_on disabled (Default)" do + it "throws an error" do + expect{ oauth_user.save }.to raise_error StandardError + end end end - context "twitter" do + describe 'blocking' do let(:provider) { 'twitter' } + before { Gitlab.config.omniauth.stub allow_single_sign_on: true } + + context 'signup' do + context 'dont block on create' do + before { Gitlab.config.omniauth.stub block_auto_created_users: false } + + it do + oauth_user.save + gl_user.should be_valid + gl_user.should_not be_blocked + end + end + + context 'block on create' do + before { Gitlab.config.omniauth.stub block_auto_created_users: true } + + it do + oauth_user.save + gl_user.should be_valid + gl_user.should be_blocked + end + end + end + + context 'sign-in' do + before do + oauth_user.save + oauth_user.gl_user.activate + end + + context 'dont block on create' do + before { Gitlab.config.omniauth.stub block_auto_created_users: false } + + it do + oauth_user.save + gl_user.should be_valid + gl_user.should_not be_blocked + end + end - it "creates a user from Omniauth" do - oauth_user.save + context 'block on create' do + before { Gitlab.config.omniauth.stub block_auto_created_users: true } - expect(gl_user).to be_valid - expect(gl_user.extern_uid).to eql uid - expect(gl_user.provider).to eql 'twitter' + it do + oauth_user.save + gl_user.should be_valid + gl_user.should_not be_blocked + end + end end end end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index e06e8826e5c..a0c37587b23 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -46,7 +46,7 @@ describe Notify do token = 'kETLwRaayvigPq_x3SNM' - subject { Notify.new_user_email(new_user.id, new_user.password, token) } + subject { Notify.new_user_email(new_user.id, token) } it_behaves_like 'an email sent from GitLab' @@ -83,7 +83,7 @@ describe Notify do let(:example_site_path) { root_path } let(:new_user) { create(:user, email: 'newguy@example.com', password: "securePassword") } - subject { Notify.new_user_email(new_user.id, new_user.password) } + subject { Notify.new_user_email(new_user.id) } it_behaves_like 'an email sent from GitLab' diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb new file mode 100644 index 00000000000..ca6f11b2a4d --- /dev/null +++ b/spec/models/concerns/mentionable_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Issue, "Mentionable" do + describe :mentioned_users do + let!(:user) { create(:user, username: 'stranger') } + let!(:user2) { create(:user, username: 'john') } + let!(:issue) { create(:issue, description: '@stranger mentioned') } + + subject { issue.mentioned_users } + + it { should include(user) } + it { should_not include(user2) } + end +end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 1fdd959da9d..204ae9da704 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -36,7 +36,7 @@ describe Event do @user = project.owner data = { - before: "0000000000000000000000000000000000000000", + before: Gitlab::Git::BLANK_SHA, after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", ref: "refs/heads/master", user_id: @user.id, @@ -60,7 +60,6 @@ describe Event do it { @event.push?.should be_true } it { @event.proper?.should be_true } - it { @event.new_branch?.should be_true } it { @event.tag?.should be_false } it { @event.branch_name.should == "master" } it { @event.author.should == @user } diff --git a/spec/models/gitlab_ci_service_spec.rb b/spec/models/gitlab_ci_service_spec.rb index ebc377047be..83277058fbb 100644 --- a/spec/models/gitlab_ci_service_spec.rb +++ b/spec/models/gitlab_ci_service_spec.rb @@ -34,11 +34,11 @@ describe GitlabCiService do end describe :commit_status_path do - it { @service.commit_status_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/builds/2ab7834c/status.json?token=verySecret"} + it { @service.commit_status_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/commits/2ab7834c/status.json?token=verySecret"} end describe :build_page do - it { @service.build_page("2ab7834c").should == "http://ci.gitlab.org/projects/2/builds/2ab7834c"} + it { @service.build_page("2ab7834c").should == "http://ci.gitlab.org/projects/2/commits/2ab7834c"} end end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 2d839e9611b..6ab7162c15c 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -249,6 +249,12 @@ describe Note do its(:note) { should == "_mentioned in merge request !#{mergereq.iid}_" } end + context 'commit contained in a merge request' do + subject { Note.create_cross_reference_note(mergereq.commits.first, mergereq, author, project) } + + it { should be_nil } + end + context 'commit from issue' do subject { Note.create_cross_reference_note(commit, issue, author, project) } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 48b58400a1e..70a15cac1a8 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -145,63 +145,6 @@ describe Project do end end - describe 'comment merge requests with commits' do - before do - @user = create(:user) - group = create(:group) - group.add_owner(@user) - - @project = create(:project, namespace: group) - @fork_project = Projects::ForkService.new(@project, @user).execute - @merge_request = create(:merge_request, source_project: @project, - source_branch: 'master', - target_branch: 'feature', - target_project: @project) - @fork_merge_request = create(:merge_request, source_project: @fork_project, - source_branch: 'master', - target_branch: 'feature', - target_project: @project) - - @commits = @merge_request.commits - end - - context 'push to origin repo source branch' do - before do - @project.comment_mr_with_commits('master', @commits, @user) - end - - it { @merge_request.notes.should_not be_empty } - it { @fork_merge_request.notes.should be_empty } - end - - context 'push to origin repo target branch' do - before do - @project.comment_mr_with_commits('feature', @commits, @user) - end - - it { @merge_request.notes.should be_empty } - it { @fork_merge_request.notes.should be_empty } - end - - context 'push to fork repo source branch' do - before do - @fork_project.comment_mr_with_commits('master', @commits, @user) - end - - it { @merge_request.notes.should be_empty } - it { @fork_merge_request.notes.should_not be_empty } - end - - context 'push to fork repo target branch' do - before do - @fork_project.comment_mr_with_commits('feature', @commits, @user) - end - - it { @merge_request.notes.should be_empty } - it { @fork_merge_request.notes.should be_empty } - end - end - describe :find_with_namespace do context 'with namespace' do before do diff --git a/spec/models/slack_message_spec.rb b/spec/models/slack_message_spec.rb index 1cd58534702..c530fad619b 100644 --- a/spec/models/slack_message_spec.rb +++ b/spec/models/slack_message_spec.rb @@ -1,4 +1,4 @@ -require_relative '../../app/models/project_services/slack_message' +require 'spec_helper' describe SlackMessage do subject { SlackMessage.new(args) } @@ -26,11 +26,11 @@ describe SlackMessage do it 'returns a message regarding pushes' do subject.pretext.should == - 'user_name pushed to branch <url/commits/master|master> of ' << + 'user_name pushed to branch <url/commits/master|master> of '\ '<url|project_name> (<url/compare/before...after|Compare changes>)' subject.attachments.should == [ { - text: "<url1|abcdefghi>: message1 - author1\n" << + text: "<url1|abcdefghi>: message1 - author1\n"\ "<url2|123456789>: message2 - author2", color: color, } @@ -45,7 +45,7 @@ describe SlackMessage do it 'returns a message regarding a new branch' do subject.pretext.should == - 'user_name pushed new branch <url/commits/master|master> to ' << + 'user_name pushed new branch <url/commits/master|master> to '\ '<url|project_name>' subject.attachments.should be_empty end diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb index 95df38d9400..d4840391967 100644 --- a/spec/models/slack_service_spec.rb +++ b/spec/models/slack_service_spec.rb @@ -31,51 +31,27 @@ describe SlackService do end describe "Execute" do - let(:slack) { SlackService.new } - let(:slack_service) { SlackService.new } - let(:user) { create(:user) } + let(:slack) { SlackService.new } + let(:user) { create(:user) } let(:project) { create(:project) } let(:sample_data) { GitPushService.new.sample_data(project, user) } - let(:webhook) { 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' } - let(:new_webhook) { 'https://hooks.gitlabhq.slack.com/services/cdIj4r4LfXUOySDUjp0tk3OI' } - let(:api_url) { - 'https://gitlabhq.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI' - } + let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' } before do slack.stub( project: project, project_id: project.id, service_hook: true, - webhook: webhook + webhook: webhook_url ) - WebMock.stub_request(:post, api_url) + WebMock.stub_request(:post, webhook_url) end it "should call Slack API" do slack.execute(sample_data) - WebMock.should have_requested(:post, api_url).once - end - - context 'with new webhook syntax' do - before do - slack_service.stub( - project: project, - project_id: project.id, - service_hook: true, - webhook: new_webhook - ) - - WebMock.stub_request(:post, api_url) - end - - it "should call Slack API" do - slack_service.execute(sample_data) - - WebMock.should have_requested(:post, api_url).once - end + WebMock.should have_requested(:post, webhook_url).once end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6ad57b06e06..8be7f733a5b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -62,6 +62,7 @@ describe User do it { should have_many(:assigned_issues).dependent(:destroy) } it { should have_many(:merge_requests).dependent(:destroy) } it { should have_many(:assigned_merge_requests).dependent(:destroy) } + it { should have_many(:identities).dependent(:destroy) } end describe "Mass assignment" do @@ -287,6 +288,20 @@ describe User do end end + describe '.by_login' do + let(:username) { 'John' } + let!(:user) { create(:user, username: username) } + + it 'should get the correct user' do + expect(User.by_login(user.email.upcase)).to eq user + expect(User.by_login(user.email)).to eq user + expect(User.by_login(username.downcase)).to eq user + expect(User.by_login(username)).to eq user + expect(User.by_login(nil)).to be_nil + expect(User.by_login('')).to be_nil + end + end + describe 'all_ssh_keys' do it { should have_many(:keys).dependent(:destroy) } @@ -347,24 +362,29 @@ describe User do end describe :ldap_user? do - let(:user) { build(:user, :ldap) } - it "is true if provider name starts with ldap" do - user.provider = 'ldapmain' + user = create(:omniauth_user, provider: 'ldapmain') expect( user.ldap_user? ).to be_true end it "is false for other providers" do - user.provider = 'other-provider' + user = create(:omniauth_user, provider: 'other-provider') expect( user.ldap_user? ).to be_false end it "is false if no extern_uid is provided" do - user.extern_uid = nil + user = create(:omniauth_user, extern_uid: nil) expect( user.ldap_user? ).to be_false end end + describe :ldap_identity do + it "returns ldap identity" do + user = create :omniauth_user + user.ldap_identity.provider.should_not be_empty + end + end + describe '#full_website_url' do let(:user) { create(:user) } diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb index 8834a6cfa83..b45572c39fd 100644 --- a/spec/requests/api/branches_spec.rb +++ b/spec/requests/api/branches_spec.rb @@ -146,6 +146,7 @@ describe API::API, api: true do it "should remove branch" do delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user) response.status.should == 200 + json_response['branch_name'].should == branch_name end it 'should return 404 if branch not exists' do diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index 38e0a284c36..a3f58f50913 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -8,6 +8,7 @@ describe API::API, api: true do let!(:project) { create(:project, creator_id: user.id) } let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) } + let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } before { project.team << [user, :reporter] } @@ -81,4 +82,68 @@ describe API::API, api: true do end end end + + describe 'GET /projects:id/repository/commits/:sha/comments' do + context 'authorized user' do + it 'should return merge_request comments' do + get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) + response.status.should == 200 + json_response.should be_an Array + json_response.length.should == 1 + json_response.first['note'].should == 'a comment on a commit' + json_response.first['author']['id'].should == user.id + end + + it 'should return a 404 error if merge_request_id not found' do + get api("/projects/#{project.id}/repository/commits/1234ab/comments", user) + response.status.should == 404 + end + end + + context 'unauthorized user' do + it 'should not return the diff of the selected commit' do + get api("/projects/#{project.id}/repository/commits/1234ab/comments") + response.status.should == 401 + end + end + end + + describe 'POST /projects:id/repository/commits/:sha/comments' do + context 'authorized user' do + it 'should return comment' do + post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment' + response.status.should == 201 + json_response['note'].should == 'My comment' + json_response['path'].should be_nil + json_response['line'].should be_nil + json_response['line_type'].should be_nil + end + + it 'should return the inline comment' do + post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.diffs.first.new_path, line: 7, line_type: 'new' + response.status.should == 201 + json_response['note'].should == 'My comment' + json_response['path'].should == project.repository.commit.diffs.first.new_path + json_response['line'].should == 7 + json_response['line_type'].should == 'new' + end + + it 'should return 400 if note is missing' do + post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) + response.status.should == 400 + end + + it 'should return 404 if note is attached to non existent commit' do + post api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment' + response.status.should == 404 + end + end + + context 'unauthorized user' do + it 'should not return the diff of the selected commit' do + post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments") + response.status.should == 401 + end + end + end end diff --git a/spec/requests/api/group_members_spec.rb b/spec/requests/api/group_members_spec.rb new file mode 100644 index 00000000000..4957186f605 --- /dev/null +++ b/spec/requests/api/group_members_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +describe API::API, api: true do + include ApiHelpers + + let(:owner) { create(:user) } + let(:reporter) { create(:user) } + let(:developer) { create(:user) } + let(:master) { create(:user) } + let(:guest) { create(:user) } + let(:stranger) { create(:user) } + + let!(:group_with_members) do + group = create(:group) + group.add_users([reporter.id], GroupMember::REPORTER) + group.add_users([developer.id], GroupMember::DEVELOPER) + group.add_users([master.id], GroupMember::MASTER) + group.add_users([guest.id], GroupMember::GUEST) + group + end + + let!(:group_no_members) { create(:group) } + + before do + group_with_members.add_owner owner + group_no_members.add_owner owner + end + + describe "GET /groups/:id/members" do + context "when authenticated as user that is part or the group" do + it "each user: should return an array of members groups of group3" do + [owner, master, developer, reporter, guest].each do |user| + get api("/groups/#{group_with_members.id}/members", user) + response.status.should == 200 + json_response.should be_an Array + json_response.size.should == 5 + json_response.find { |e| e['id']==owner.id }['access_level'].should == GroupMember::OWNER + json_response.find { |e| e['id']==reporter.id }['access_level'].should == GroupMember::REPORTER + json_response.find { |e| e['id']==developer.id }['access_level'].should == GroupMember::DEVELOPER + json_response.find { |e| e['id']==master.id }['access_level'].should == GroupMember::MASTER + json_response.find { |e| e['id']==guest.id }['access_level'].should == GroupMember::GUEST + end + end + + it "users not part of the group should get access error" do + get api("/groups/#{group_with_members.id}/members", stranger) + response.status.should == 403 + end + end + end + + describe "POST /groups/:id/members" do + context "when not a member of the group" do + it "should not add guest as member of group_no_members when adding being done by person outside the group" do + post api("/groups/#{group_no_members.id}/members", reporter), user_id: guest.id, access_level: GroupMember::MASTER + response.status.should == 403 + end + end + + context "when a member of the group" do + it "should return ok and add new member" do + new_user = create(:user) + + expect { + post api("/groups/#{group_no_members.id}/members", owner), + user_id: new_user.id, access_level: GroupMember::MASTER + }.to change { group_no_members.members.count }.by(1) + + response.status.should == 201 + json_response['name'].should == new_user.name + json_response['access_level'].should == GroupMember::MASTER + end + + it "should not allow guest to modify group members" do + new_user = create(:user) + + expect { + post api("/groups/#{group_with_members.id}/members", guest), + user_id: new_user.id, access_level: GroupMember::MASTER + }.not_to change { group_with_members.members.count } + + response.status.should == 403 + end + + it "should return error if member already exists" do + post api("/groups/#{group_with_members.id}/members", owner), user_id: master.id, access_level: GroupMember::MASTER + response.status.should == 409 + end + + it "should return a 400 error when user id is not given" do + post api("/groups/#{group_no_members.id}/members", owner), access_level: GroupMember::MASTER + response.status.should == 400 + end + + it "should return a 400 error when access level is not given" do + post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id + response.status.should == 400 + end + + it "should return a 422 error when access level is not known" do + post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id, access_level: 1234 + response.status.should == 422 + end + end + end + + describe "DELETE /groups/:id/members/:user_id" do + context "when not a member of the group" do + it "should not delete guest's membership of group_with_members" do + random_user = create(:user) + delete api("/groups/#{group_with_members.id}/members/#{owner.id}", random_user) + response.status.should == 403 + end + end + + context "when a member of the group" do + it "should delete guest's membership of group" do + expect { + delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner) + }.to change { group_with_members.members.count }.by(-1) + + response.status.should == 200 + end + + it "should return a 404 error when user id is not known" do + delete api("/groups/#{group_with_members.id}/members/1328", owner) + response.status.should == 404 + end + + it "should not allow guest to modify group members" do + delete api("/groups/#{group_with_members.id}/members/#{master.id}", guest) + response.status.should == 403 + end + end + end +end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 42ccad71aaf..8dfd2cd650e 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -165,114 +165,4 @@ describe API::API, api: true do end end end - - describe "members" do - let(:owner) { create(:user) } - let(:reporter) { create(:user) } - let(:developer) { create(:user) } - let(:master) { create(:user) } - let(:guest) { create(:user) } - let!(:group_with_members) do - group = create(:group) - group.add_users([reporter.id], GroupMember::REPORTER) - group.add_users([developer.id], GroupMember::DEVELOPER) - group.add_users([master.id], GroupMember::MASTER) - group.add_users([guest.id], GroupMember::GUEST) - group - end - let!(:group_no_members) { create(:group) } - - before do - group_with_members.add_owner owner - group_no_members.add_owner owner - end - - describe "GET /groups/:id/members" do - context "when authenticated as user that is part or the group" do - it "each user: should return an array of members groups of group3" do - [owner, master, developer, reporter, guest].each do |user| - get api("/groups/#{group_with_members.id}/members", user) - response.status.should == 200 - json_response.should be_an Array - json_response.size.should == 5 - json_response.find { |e| e['id']==owner.id }['access_level'].should == GroupMember::OWNER - json_response.find { |e| e['id']==reporter.id }['access_level'].should == GroupMember::REPORTER - json_response.find { |e| e['id']==developer.id }['access_level'].should == GroupMember::DEVELOPER - json_response.find { |e| e['id']==master.id }['access_level'].should == GroupMember::MASTER - json_response.find { |e| e['id']==guest.id }['access_level'].should == GroupMember::GUEST - end - end - - it "users not part of the group should get access error" do - get api("/groups/#{group_with_members.id}/members", user1) - response.status.should == 403 - end - end - end - - describe "POST /groups/:id/members" do - context "when not a member of the group" do - it "should not add guest as member of group_no_members when adding being done by person outside the group" do - post api("/groups/#{group_no_members.id}/members", reporter), user_id: guest.id, access_level: GroupMember::MASTER - response.status.should == 403 - end - end - - context "when a member of the group" do - it "should return ok and add new member" do - count_before=group_no_members.group_members.count - new_user = create(:user) - post api("/groups/#{group_no_members.id}/members", owner), user_id: new_user.id, access_level: GroupMember::MASTER - response.status.should == 201 - json_response['name'].should == new_user.name - json_response['access_level'].should == GroupMember::MASTER - group_no_members.group_members.count.should == count_before + 1 - end - - it "should return error if member already exists" do - post api("/groups/#{group_with_members.id}/members", owner), user_id: master.id, access_level: GroupMember::MASTER - response.status.should == 409 - end - - it "should return a 400 error when user id is not given" do - post api("/groups/#{group_no_members.id}/members", owner), access_level: GroupMember::MASTER - response.status.should == 400 - end - - it "should return a 400 error when access level is not given" do - post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id - response.status.should == 400 - end - - it "should return a 422 error when access level is not known" do - post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id, access_level: 1234 - response.status.should == 422 - end - end - end - - describe "DELETE /groups/:id/members/:user_id" do - context "when not a member of the group" do - it "should not delete guest's membership of group_with_members" do - random_user = create(:user) - delete api("/groups/#{group_with_members.id}/members/#{owner.id}", random_user) - response.status.should == 403 - end - end - - context "when a member of the group" do - it "should delete guest's membership of group" do - count_before=group_with_members.group_members.count - delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner) - response.status.should == 200 - group_with_members.group_members.count.should == count_before - 1 - end - - it "should return a 404 error when user id is not known" do - delete api("/groups/#{group_with_members.id}/members/1328", owner) - response.status.should == 404 - end - end - end - end end diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index 6df5ef38961..4faa1f9b964 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -5,10 +5,11 @@ describe API::API, api: true do let(:user) { create(:user) } let(:key) { create(:key, user: user) } let(:project) { create(:project) } + let(:secret_token) { File.read Rails.root.join('.gitlab_shell_secret') } describe "GET /internal/check", no_db: true do it do - get api("/internal/check") + get api("/internal/check"), secret_token: secret_token response.status.should == 200 json_response['api_version'].should == API::API.version @@ -17,7 +18,7 @@ describe API::API, api: true do describe "GET /internal/discover" do it do - get(api("/internal/discover"), key_id: key.id) + get(api("/internal/discover"), key_id: key.id, secret_token: secret_token) response.status.should == 200 @@ -25,7 +26,7 @@ describe API::API, api: true do end end - describe "GET /internal/allowed" do + describe "POST /internal/allowed" do context "access granted" do before do project.team << [user, :developer] @@ -36,7 +37,7 @@ describe API::API, api: true do pull(key, project) response.status.should == 200 - response.body.should == 'true' + JSON.parse(response.body)["status"].should be_true end end @@ -45,7 +46,7 @@ describe API::API, api: true do push(key, project) response.status.should == 200 - response.body.should == 'true' + JSON.parse(response.body)["status"].should be_true end end end @@ -60,7 +61,7 @@ describe API::API, api: true do pull(key, project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end @@ -69,7 +70,7 @@ describe API::API, api: true do push(key, project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end end @@ -86,7 +87,7 @@ describe API::API, api: true do pull(key, personal_project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end @@ -95,7 +96,7 @@ describe API::API, api: true do push(key, personal_project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end end @@ -113,7 +114,7 @@ describe API::API, api: true do pull(key, project) response.status.should == 200 - response.body.should == 'true' + JSON.parse(response.body)["status"].should be_true end end @@ -122,7 +123,7 @@ describe API::API, api: true do push(key, project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end end @@ -139,7 +140,7 @@ describe API::API, api: true do archive(key, project) response.status.should == 200 - response.body.should == 'true' + JSON.parse(response.body)["status"].should be_true end end @@ -148,10 +149,28 @@ describe API::API, api: true do archive(key, project) response.status.should == 200 - response.body.should == 'false' + JSON.parse(response.body)["status"].should be_false end end end + + context 'project does not exist' do + it do + pull(key, OpenStruct.new(path_with_namespace: 'gitlab/notexists')) + + response.status.should == 200 + JSON.parse(response.body)["status"].should be_false + end + end + + context 'user does not exist' do + it do + pull(OpenStruct.new(id: 0), project) + + response.status.should == 200 + JSON.parse(response.body)["status"].should be_false + end + end end def pull(key, project) @@ -159,7 +178,8 @@ describe API::API, api: true do api("/internal/allowed"), key_id: key.id, project: project.path_with_namespace, - action: 'git-upload-pack' + action: 'git-upload-pack', + secret_token: secret_token ) end @@ -169,7 +189,8 @@ describe API::API, api: true do changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master', key_id: key.id, project: project.path_with_namespace, - action: 'git-receive-pack' + action: 'git-receive-pack', + secret_token: secret_token ) end @@ -179,7 +200,8 @@ describe API::API, api: true do ref: 'master', key_id: key.id, project: project.path_with_namespace, - action: 'git-upload-archive' + action: 'git-upload-archive', + secret_token: secret_token ) end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index aa1437c71aa..2c4b68c10b6 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -203,15 +203,12 @@ describe API::API, api: true do json_response['message']['name'].should == [ 'can\'t be blank', 'is too short (minimum is 0 characters)', - 'can contain only letters, digits, \'_\', \'-\' and \'.\' and '\ - 'space. It must start with letter, digit or \'_\'.' + Gitlab::Regex.project_regex_message ] json_response['message']['path'].should == [ 'can\'t be blank', 'is too short (minimum is 0 characters)', - 'can contain only letters, digits, \'_\', \'-\' and \'.\'. It must '\ - 'start with letter, digit or \'_\', optionally preceeded by \'.\'. '\ - 'It must not end in \'.git\'.' + Gitlab::Regex.send(:default_regex_message) ] end @@ -339,6 +336,7 @@ describe API::API, api: true do json_event['action_name'].should == 'joined' json_event['project_id'].to_i.should == project.id + json_event['author_username'].should == user.username end it "should return a 404 error if not found" do @@ -632,6 +630,11 @@ describe API::API, api: true do describe "DELETE /projects/:id" do context "when authenticated as user" do it "should remove project" do + expect(GitlabShellWorker).to( + receive(:perform_async).with(:remove_repository, + /#{project.path_with_namespace}/) + ).twice + delete api("/projects/#{project.id}", user) response.status.should == 200 end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index 6e54839b677..beae71c02d9 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -34,21 +34,23 @@ describe API::API, api: true do end end - # TODO: fix this test for CI - #context 'annotated tag' do - #it 'should create a new annotated tag' do - #post api("/projects/#{project.id}/repository/tags", user), - #tag_name: 'v7.1.0', - #ref: 'master', - #message: 'tag message' - - #response.status.should == 201 - #json_response['name'].should == 'v7.1.0' - # The message is not part of the JSON response. - # Additional changes to the gitlab_git gem may be required. - # json_response['message'].should == 'tag message' - #end - #end + context 'annotated tag' do + it 'should create a new annotated tag' do + # Identity must be set in .gitconfig to create annotated tag. + repo_path = project.repository.path_to_repo + system(*%W(git --git-dir=#{repo_path} config user.name #{user.name})) + system(*%W(git --git-dir=#{repo_path} config user.email #{user.email})) + + post api("/projects/#{project.id}/repository/tags", user), + tag_name: 'v7.1.0', + ref: 'master', + message: 'Release 7.1.0' + + response.status.should == 201 + json_response['name'].should == 'v7.1.0' + json_response['message'].should == 'Release 7.1.0' + end + end it 'should deny for user without push access' do post api("/projects/#{project.id}/repository/tags", user2), diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index f883c9e028a..d8282d0696b 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -27,4 +27,30 @@ describe API::API, api: true do project.gitlab_ci_service.should be_nil end end + + describe 'PUT /projects/:id/services/hipchat' do + it 'should update hipchat settings' do + put api("/projects/#{project.id}/services/hipchat", user), + token: 'secret-token', room: 'test' + + response.status.should == 200 + project.hipchat_service.should_not be_nil + end + + it 'should return if required fields missing' do + put api("/projects/#{project.id}/services/gitlab-ci", user), + token: 'secret-token', active: true + + response.status.should == 400 + end + end + + describe 'DELETE /projects/:id/services/hipchat' do + it 'should delete hipchat settings' do + delete api("/projects/#{project.id}/services/hipchat", user) + + response.status.should == 200 + project.hipchat_service.should be_nil + end + end end diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb index 013f425d6ce..57b2e6cbd6a 100644 --- a/spec/requests/api/session_spec.rb +++ b/spec/requests/api/session_spec.rb @@ -19,6 +19,32 @@ describe API::API, api: true do end end + context 'when email has case-typo and password is valid' do + it 'should return private token' do + post api('/session'), email: user.email.upcase, password: '12345678' + expect(response.status).to eq 201 + + expect(json_response['email']).to eq user.email + expect(json_response['private_token']).to eq user.private_token + expect(json_response['is_admin']).to eq user.is_admin? + expect(json_response['can_create_project']).to eq user.can_create_project? + expect(json_response['can_create_group']).to eq user.can_create_group? + end + end + + context 'when login has case-typo and password is valid' do + it 'should return private token' do + post api('/session'), login: user.username.upcase, password: '12345678' + expect(response.status).to eq 201 + + expect(json_response['email']).to eq user.email + expect(json_response['private_token']).to eq user.private_token + expect(json_response['is_admin']).to eq user.is_admin? + expect(json_response['can_create_project']).to eq user.can_create_project? + expect(json_response['can_create_group']).to eq user.can_create_group? + end + end + context "when invalid password" do it "should return authentication error" do post api("/session"), email: user.email, password: '123' diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index bc1598273be..1ecc79ea7ef 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -33,7 +33,7 @@ describe API::API, api: true do response.status.should == 200 json_response.should be_an Array json_response.first.keys.should include 'email' - json_response.first.keys.should include 'extern_uid' + json_response.first.keys.should include 'identities' json_response.first.keys.should include 'can_create_project' end end @@ -140,9 +140,7 @@ describe API::API, api: true do json_response['message']['projects_limit']. should == ['must be greater than or equal to 0'] json_response['message']['username']. - should == ['can contain only letters, digits, '\ - '\'_\', \'-\' and \'.\'. It must start with letter, digit or '\ - '\'_\', optionally preceeded by \'.\'. It must not end in \'.git\'.'] + should == [Gitlab::Regex.send(:default_regex_message)] end it "shouldn't available for non admin users" do @@ -284,9 +282,7 @@ describe API::API, api: true do json_response['message']['projects_limit']. should == ['must be greater than or equal to 0'] json_response['message']['username']. - should == ['can contain only letters, digits, '\ - '\'_\', \'-\' and \'.\'. It must start with letter, digit or '\ - '\'_\', optionally preceeded by \'.\'. It must not end in \'.git\'.'] + should == [Gitlab::Regex.send(:default_regex_message)] end context "with existing user" do @@ -433,6 +429,7 @@ describe API::API, api: true do json_response['is_admin'].should == user.is_admin? json_response['can_create_project'].should == user.can_create_project? json_response['can_create_group'].should == user.can_create_group? + json_response['projects_limit'].should == user.projects_limit end it "should return 401 error if user is unauthenticated" do diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index f1f5ac96a62..e4652d1f836 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -55,7 +55,6 @@ end # projects POST /projects(.:format) projects#create # new_project GET /projects/new(.:format) projects#new -# fork_project POST /:id/fork(.:format) projects#fork # files_project GET /:id/files(.:format) projects#files # edit_project GET /:id/edit(.:format) projects#edit # project GET /:id(.:format) projects#show @@ -71,10 +70,6 @@ describe ProjectsController, "routing" do get("/projects/new").should route_to('projects#new') end - it "to #fork" do - post("/gitlab/gitlabhq/fork").should route_to('projects#fork', id: 'gitlab/gitlabhq') - end - it "to #edit" do get("/gitlab/gitlabhq/edit").should route_to('projects#edit', id: 'gitlab/gitlabhq') end @@ -464,3 +459,13 @@ describe Projects::GraphsController, "routing" do get("/gitlab/gitlabhq/graphs/master").should route_to('projects/graphs#show', project_id: 'gitlab/gitlabhq', id: 'master') end end + +describe Projects::ForksController, "routing" do + it "to #new" do + get("/gitlab/gitlabhq/fork/new").should route_to("projects/forks#new", project_id: 'gitlab/gitlabhq') + end + + it "to #create" do + post("/gitlab/gitlabhq/fork").should route_to("projects/forks#create", project_id: 'gitlab/gitlabhq') + end +end diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 4ef053a767f..19b442573f4 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -8,7 +8,7 @@ describe GitPushService do let (:service) { GitPushService.new } before do - @blankrev = '0000000000000000000000000000000000000000' + @blankrev = Gitlab::Git::BLANK_SHA @oldrev = sample_commit.parent_id @newrev = sample_commit.id @ref = 'refs/heads/master' diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb new file mode 100644 index 00000000000..9f294152053 --- /dev/null +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -0,0 +1,98 @@ +require 'spec_helper' + +describe MergeRequests::RefreshService do + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:service) { MergeRequests::RefreshService } + + describe :execute do + before do + @user = create(:user) + group = create(:group) + group.add_owner(@user) + + @project = create(:project, namespace: group) + @fork_project = Projects::ForkService.new(@project, @user).execute + @merge_request = create(:merge_request, source_project: @project, + source_branch: 'master', + target_branch: 'feature', + target_project: @project) + + @fork_merge_request = create(:merge_request, source_project: @fork_project, + source_branch: 'master', + target_branch: 'feature', + target_project: @project) + + @commits = @merge_request.commits + + @oldrev = @commits.last.id + @newrev = @commits.first.id + end + + context 'push to origin repo source branch' do + before do + service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') + reload_mrs + end + + it { @merge_request.notes.should_not be_empty } + it { @merge_request.should be_open } + it { @fork_merge_request.should be_open } + it { @fork_merge_request.notes.should be_empty } + end + + context 'push to origin repo target branch' do + before do + service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') + reload_mrs + end + + it { @merge_request.notes.should be_empty } + it { @merge_request.should be_merged } + it { @fork_merge_request.should be_merged } + it { @fork_merge_request.notes.should be_empty } + end + + context 'push to fork repo source branch' do + before do + service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/master') + reload_mrs + end + + it { @merge_request.notes.should be_empty } + it { @merge_request.should be_open } + it { @fork_merge_request.notes.should_not be_empty } + it { @fork_merge_request.should be_open } + end + + context 'push to fork repo target branch' do + before do + service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') + reload_mrs + end + + it { @merge_request.notes.should be_empty } + it { @merge_request.should be_open } + it { @fork_merge_request.notes.should be_empty } + it { @fork_merge_request.should be_open } + end + + context 'push to origin repo target branch after fork project was removed' do + before do + @fork_project.destroy + service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') + reload_mrs + end + + it { @merge_request.notes.should be_empty } + it { @merge_request.should be_merged } + it { @fork_merge_request.should be_open } + it { @fork_merge_request.notes.should be_empty } + end + + def reload_mrs + @merge_request.reload + @fork_merge_request.reload + end + end +end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index 0edc3a8e807..5c80345c2b3 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -42,10 +42,54 @@ describe Projects::ForkService do end end - def fork_project(from_project, user, fork_success = true) - context = Projects::ForkService.new(from_project, user) - shell = double("gitlab_shell") - shell.stub(fork_repository: fork_success) + describe :fork_to_namespace do + before do + @group_owner = create(:user) + @developer = create(:user) + @project = create(:project, creator_id: @group_owner.id, + star_count: 777, + description: 'Wow, such a cool project!') + @group = create(:group) + @group.add_user(@group_owner, GroupMember::OWNER) + @group.add_user(@developer, GroupMember::DEVELOPER) + @opts = { namespace: @group } + end + + context 'fork project for group' do + it 'group owner successfully forks project into the group' do + to_project = fork_project(@project, @group_owner, true, @opts) + to_project.owner.should == @group + to_project.namespace.should == @group + to_project.name.should == @project.name + to_project.path.should == @project.path + to_project.description.should == @project.description + to_project.star_count.should be_zero + end + end + + context 'fork project for group when user not owner' do + it 'group developer should fail to fork project into the group' do + to_project = fork_project(@project, @developer, true, @opts) + to_project.errors[:namespace].should == ['insufficient access rights'] + end + end + + context 'project already exists in group' do + it 'should fail due to validation, not transaction failure' do + existing_project = create(:project, name: @project.name, + namespace: @group) + to_project = fork_project(@project, @group_owner, true, @opts) + existing_project.persisted?.should be_true + to_project.errors[:base].should == ['Invalid fork destination'] + to_project.errors[:name].should == ['has already been taken'] + to_project.errors[:path].should == ['has already been taken'] + end + end + end + + def fork_project(from_project, user, fork_success = true, params = {}) + context = Projects::ForkService.new(from_project, user, params) + shell = double('gitlab_shell').stub(fork_repository: fork_success) context.stub(gitlab_shell: shell) context.execute end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 2508dfc4565..79d0526ff89 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -3,15 +3,12 @@ require 'spec_helper' describe Projects::TransferService do let(:user) { create(:user) } let(:group) { create(:group) } - let(:group2) { create(:group) } let(:project) { create(:project, namespace: user.namespace) } context 'namespace -> namespace' do before do group.add_owner(user) - @service = Projects::TransferService.new(project, user, namespace_id: group.id) - @service.gitlab_shell.stub(mv_repository: true) - @result = @service.execute + @result = transfer_project(project, user, namespace_id: group.id) end it { @result.should be_true } @@ -20,24 +17,25 @@ describe Projects::TransferService do context 'namespace -> no namespace' do before do - group.add_owner(user) - @service = Projects::TransferService.new(project, user, namespace_id: nil) - @service.gitlab_shell.stub(mv_repository: true) - @result = @service.execute + @result = transfer_project(project, user, namespace_id: nil) end + it { @result.should_not be_nil } # { result.should be_false } passes on nil it { @result.should be_false } it { project.namespace.should == user.namespace } end context 'namespace -> not allowed namespace' do before do - @service = Projects::TransferService.new(project, user, namespace_id: group2.id) - @service.gitlab_shell.stub(mv_repository: true) - @result = @service.execute + @result = transfer_project(project, user, namespace_id: group.id) end + it { @result.should_not be_nil } # { result.should be_false } passes on nil it { @result.should be_false } it { project.namespace.should == user.namespace } end + + def transfer_project(project, user, params) + Projects::TransferService.new(project, user, params).execute + end end diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 5f55871dc4a..e6db410fb1c 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -3,6 +3,16 @@ require 'rspec/mocks' module TestEnv extend self + # When developing the seed repository, comment out the branch you will modify. + BRANCH_SHA = { + 'feature' => '0b4bc9a', + 'feature_conflict' => 'bb5206f', + 'fix' => '12d65c8', + 'improve/awesome' => '5937ac0', + 'markdown' => '0ed8c6c', + 'master' => '5937ac0' + } + # Test environment # # See gitlab.yml.example test section for paths @@ -18,13 +28,13 @@ module TestEnv if File.directory?(tmp_test_path) Dir.entries(tmp_test_path).each do |entry| - unless ['.', '..', 'gitlab-shell'].include?(entry) + unless ['.', '..', 'gitlab-shell', factory_repo_name].include?(entry) FileUtils.rm_r(File.join(tmp_test_path, entry)) end end end - FileUtils.mkdir_p(tmp_test_path) + FileUtils.mkdir_p(repos_path) # Setup GitLab shell for test instance setup_gitlab_shell @@ -49,13 +59,32 @@ module TestEnv clone_url = "https://gitlab.com/gitlab-org/#{factory_repo_name}.git" unless File.directory?(factory_repo_path) - git_cmd = %W(git clone --bare #{clone_url} #{factory_repo_path}) - system(*git_cmd) + system(*%W(git clone #{clone_url} #{factory_repo_path})) + end + + Dir.chdir(factory_repo_path) do + BRANCH_SHA.each do |branch, sha| + # Try to reset without fetching to avoid using the network. + reset = %W(git update-ref refs/heads/#{branch} #{sha}) + unless system(*reset) + if system(*%w(git fetch origin)) + unless system(*reset) + raise 'The fetched test seed '\ + 'does not contain the required revision.' + end + else + raise 'Could not fetch test seed repository.' + end + end + end end + + # We must copy bare repositories because we will push to them. + system(*%W(git clone --bare #{factory_repo_path} #{factory_repo_path_bare})) end def copy_repo(project) - base_repo_path = File.expand_path(factory_repo_path) + base_repo_path = File.expand_path(factory_repo_path_bare) target_repo_path = File.expand_path(repos_path + "/#{project.namespace.path}/#{project.path}.git") FileUtils.mkdir_p(target_repo_path) FileUtils.cp_r("#{base_repo_path}/.", target_repo_path) @@ -69,7 +98,11 @@ module TestEnv private def factory_repo_path - @factory_repo_path ||= repos_path + "/root/#{factory_repo_name}.git" + @factory_repo_path ||= Rails.root.join('tmp', 'tests', factory_repo_name) + end + + def factory_repo_path_bare + factory_repo_path.to_s + '_bare' end def factory_repo_name diff --git a/spec/tasks/gitlab/mail_google_schema_whitelisting.rb b/spec/tasks/gitlab/mail_google_schema_whitelisting.rb new file mode 100644 index 00000000000..45aaf0fc90b --- /dev/null +++ b/spec/tasks/gitlab/mail_google_schema_whitelisting.rb @@ -0,0 +1,27 @@ +require 'spec_helper' +require 'rake' + +describe 'gitlab:mail_google_schema_whitelisting rake task' do + before :all do + Rake.application.rake_require "tasks/gitlab/task_helpers" + Rake.application.rake_require "tasks/gitlab/mail_google_schema_whitelisting" + # empty task as env is already loaded + Rake::Task.define_task :environment + end + + describe 'call' do + before do + # avoid writing task output to spec progress + $stdout.stub :write + end + + let :run_rake_task do + Rake::Task["gitlab:mail_google_schema_whitelisting"].reenable + Rake.application.invoke_task "gitlab:mail_google_schema_whitelisting" + end + + it 'should run the task without errors' do + expect { run_rake_task }.to_not raise_error + end + end +end |