diff options
author | Keith Pitt <me@keithpitt.com> | 2014-10-08 16:33:53 +0800 |
---|---|---|
committer | Keith Pitt <me@keithpitt.com> | 2014-10-08 16:33:53 +0800 |
commit | 4c7da578f200f0bc721cc2cae27eb2b25f96e8dd (patch) | |
tree | 565b5b7746bc2cff8e46883b4d1836dfaa0246ef /spec | |
parent | 76594d474ca6d04c2e608e7b3df1229729288f14 (diff) | |
parent | 928178deb9d582d7537a57983ff9e695f07dab1f (diff) | |
download | gitlab-ce-4c7da578f200f0bc721cc2cae27eb2b25f96e8dd.tar.gz |
Merge branch 'master' into buildbox-service
Conflicts:
app/models/project.rb
Diffstat (limited to 'spec')
-rw-r--r-- | spec/factories/projects.rb | 10 | ||||
-rw-r--r-- | spec/helpers/gitlab_markdown_helper_spec.rb | 203 | ||||
-rw-r--r-- | spec/helpers/notifications_helper_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/git_access_wiki_spec.rb | 22 | ||||
-rw-r--r-- | spec/lib/gitlab/reference_extractor_spec.rb | 52 | ||||
-rw-r--r-- | spec/lib/gitlab/satellite/action_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/commit_spec.rb | 14 | ||||
-rw-r--r-- | spec/models/issue_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/merge_request_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/note_spec.rb | 24 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 1 | ||||
-rw-r--r-- | spec/models/pushover_service_spec.rb | 69 | ||||
-rw-r--r-- | spec/models/slack_service_spec.rb | 34 | ||||
-rw-r--r-- | spec/requests/api/namespaces_spec.rb | 3 | ||||
-rw-r--r-- | spec/requests/api/projects_spec.rb | 11 | ||||
-rw-r--r-- | spec/requests/api/users_spec.rb | 5 | ||||
-rw-r--r-- | spec/support/login_helpers.rb | 2 | ||||
-rw-r--r-- | spec/support/mentionable_shared_examples.rb | 40 | ||||
-rw-r--r-- | spec/support/taskable_shared_examples.rb | 42 |
19 files changed, 485 insertions, 65 deletions
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 5324654c48c..23314b3b1a4 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -47,16 +47,6 @@ FactoryGirl.define do end end - # Generates a test repository from the repository stored under `spec/seed_project.tar.gz`. - # Once you run `rake gitlab:setup`, you can see what the repository looks like under `tmp/repositories/gitlabhq`. - # In order to modify files in the repository, you must untar the seed, modify and remake the tar. - # Before recompressing, do not forget to `git checkout master`. - # After recompressing, you need to run `RAILS_ENV=test bundle exec rake gitlab:setup` to regenerate the seeds under tmp. - # - # If you want to modify the repository only for an specific type of tests, e.g., markdown tests, - # consider using a feature branch to reduce the chances of collision with other tests. - # Create a new commit, and use the same commit message that you will use for the change in the main repo. - # Changing the commig message and SHA of branch `master` may break tests. factory :project, parent: :empty_project do path { 'gitlabhq' } diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 6c865b1e079..15033f07432 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -181,6 +181,76 @@ describe GitlabMarkdownHelper do end end + # Shared examples for referencing an object in a different project + # + # Expects the following attributes to be available in the example group: + # + # - object - The object itself + # - reference - The object reference string (e.g., #1234, $1234, !1234) + # - other_project - The project that owns the target object + # + # Currently limited to Snippets, Issues and MergeRequests + shared_examples 'cross-project referenced object' do + let(:project_path) { @other_project.path_with_namespace } + let(:full_reference) { "#{project_path}#{reference}" } + let(:actual) { "Reference to #{full_reference}" } + let(:expected) do + if object.is_a?(Commit) + project_commit_path(@other_project, object) + else + polymorphic_path([@other_project, object]) + end + end + + it 'should link using a valid id' do + gfm(actual).should match( + /#{expected}.*#{Regexp.escape(full_reference)}/ + ) + end + + it 'should link with adjacent text' do + # Wrap the reference in parenthesis + gfm(actual.gsub(full_reference, "(#{full_reference})")).should( + match(expected) + ) + + # Append some text to the end of the reference + gfm(actual.gsub(full_reference, "#{full_reference}, right?")).should( + match(expected) + ) + end + + it 'should keep whitespace intact' do + actual = "Referenced #{full_reference} already." + expected = /Referenced <a.+>[^\s]+<\/a> already/ + gfm(actual).should match(expected) + end + + it 'should not link with an invalid id' do + # Modify the reference string so it's still parsed, but is invalid + if object.is_a?(Commit) + reference.gsub!(/^(.).+$/, '\1' + '12345abcd') + else + reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2)) + end + gfm(actual).should == actual + end + + it 'should include a title attribute' do + if object.is_a?(Commit) + title = object.link_title + else + title = "#{object.class.to_s.titlecase}: #{object.title}" + end + gfm(actual).should match(/title="#{title}"/) + end + + it 'should include standard gfm classes' do + css = object.class.to_s.underscore + gfm(actual).should match(/class="\s?gfm gfm-#{css}\s?"/) + end + end + describe "referencing an issue" do let(:object) { issue } let(:reference) { "##{issue.iid}" } @@ -188,6 +258,38 @@ describe GitlabMarkdownHelper do include_examples 'referenced object' end + context 'cross-repo references' do + before(:all) do + @other_project = create(:project, :public) + @commit2 = @other_project.repository.commit + @issue2 = create(:issue, project: @other_project) + @merge_request2 = create(:merge_request, + source_project: @other_project, + target_project: @other_project) + end + + describe 'referencing an issue in another project' do + let(:object) { @issue2 } + let(:reference) { "##{@issue2.iid}" } + + include_examples 'cross-project referenced object' + end + + describe 'referencing an merge request in another project' do + let(:object) { @merge_request2 } + let(:reference) { "!#{@merge_request2.iid}" } + + include_examples 'cross-project referenced object' + end + + describe 'referencing a commit in another project' do + let(:object) { @commit2 } + let(:reference) { "@#{@commit2.id}" } + + include_examples 'cross-project referenced object' + end + end + describe "referencing a Jira issue" do let(:actual) { "Reference to JIRA-#{issue.iid}" } let(:expected) { "http://jira.example/browse/JIRA-#{issue.iid}" } @@ -514,7 +616,7 @@ describe GitlabMarkdownHelper do end end - describe "markdwon for empty repository" do + describe 'markdown for empty repository' do before do @project = empty_project @repository = empty_project.repository @@ -550,4 +652,103 @@ describe GitlabMarkdownHelper do helper.render_wiki_content(@wiki) end end + + describe '#gfm_with_tasks' do + before(:all) do + @source_text_asterisk = <<EOT.gsub(/^\s{8}/, '') + * [ ] valid unchecked task + * [x] valid lowercase checked task + * [X] valid uppercase checked task + * [ ] valid unchecked nested task + * [x] valid checked nested task + + [ ] not an unchecked task - no list item + [x] not a checked task - no list item + + * [ ] not an unchecked task - too many spaces + * [x ] not a checked task - too many spaces + * [] not an unchecked task - no spaces + * Not a task [ ] - not at beginning +EOT + + @source_text_dash = <<EOT.gsub(/^\s{8}/, '') + - [ ] valid unchecked task + - [x] valid lowercase checked task + - [X] valid uppercase checked task + - [ ] valid unchecked nested task + - [x] valid checked nested task +EOT + end + + it 'should render checkboxes at beginning of asterisk list items' do + rendered_text = markdown(@source_text_asterisk, parse_tasks: true) + + expect(rendered_text).to match(/<input.*checkbox.*valid unchecked task/) + expect(rendered_text).to match( + /<input.*checkbox.*valid lowercase checked task/ + ) + expect(rendered_text).to match( + /<input.*checkbox.*valid uppercase checked task/ + ) + end + + it 'should render checkboxes at beginning of dash list items' do + rendered_text = markdown(@source_text_dash, parse_tasks: true) + + expect(rendered_text).to match(/<input.*checkbox.*valid unchecked task/) + expect(rendered_text).to match( + /<input.*checkbox.*valid lowercase checked task/ + ) + expect(rendered_text).to match( + /<input.*checkbox.*valid uppercase checked task/ + ) + end + + it 'should not be confused by whitespace before bullets' do + rendered_text_asterisk = markdown(@source_text_asterisk, + parse_tasks: true) + rendered_text_dash = markdown(@source_text_dash, parse_tasks: true) + + expect(rendered_text_asterisk).to match( + /<input.*checkbox.*valid unchecked nested task/ + ) + expect(rendered_text_asterisk).to match( + /<input.*checkbox.*valid checked nested task/ + ) + expect(rendered_text_dash).to match( + /<input.*checkbox.*valid unchecked nested task/ + ) + expect(rendered_text_dash).to match( + /<input.*checkbox.*valid checked nested task/ + ) + end + + it 'should not render checkboxes outside of list items' do + rendered_text = markdown(@source_text_asterisk, parse_tasks: true) + + expect(rendered_text).not_to match( + /<input.*checkbox.*not an unchecked task - no list item/ + ) + expect(rendered_text).not_to match( + /<input.*checkbox.*not a checked task - no list item/ + ) + end + + it 'should not render checkboxes with invalid formatting' do + rendered_text = markdown(@source_text_asterisk, parse_tasks: true) + + expect(rendered_text).not_to match( + /<input.*checkbox.*not an unchecked task - too many spaces/ + ) + expect(rendered_text).not_to match( + /<input.*checkbox.*not a checked task - too many spaces/ + ) + expect(rendered_text).not_to match( + /<input.*checkbox.*not an unchecked task - no spaces/ + ) + expect(rendered_text).not_to match( + /Not a task.*<input.*checkbox.*not at beginning/ + ) + end + end end diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 3ecabbaf045..31ecdacf28e 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -8,7 +8,7 @@ describe NotificationsHelper do before { notification.stub(disabled?: true) } it "has a red icon" do - notification_icon(notification).should match('class="icon-volume-off ns-mute"') + notification_icon(notification).should match('class="fa fa-volume-off ns-mute"') end end @@ -16,7 +16,7 @@ describe NotificationsHelper do before { notification.stub(participating?: true) } it "has a blue icon" do - notification_icon(notification).should match('class="icon-volume-down ns-part"') + notification_icon(notification).should match('class="fa fa-volume-down ns-part"') end end @@ -24,12 +24,12 @@ describe NotificationsHelper do before { notification.stub(watch?: true) } it "has a green icon" do - notification_icon(notification).should match('class="icon-volume-up ns-watch"') + notification_icon(notification).should match('class="fa fa-volume-up ns-watch"') end end it "has a blue icon" do - notification_icon(notification).should match('class="icon-circle-blank ns-default"') + notification_icon(notification).should match('class="fa fa-circle-o ns-default"') end end end diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb new file mode 100644 index 00000000000..ed5785b31e6 --- /dev/null +++ b/spec/lib/gitlab/git_access_wiki_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe Gitlab::GitAccessWiki do + let(:access) { Gitlab::GitAccessWiki.new } + let(:project) { create(:project) } + let(:user) { create(:user) } + + describe 'push_allowed?' do + before do + create(:protected_branch, name: 'master', project: project) + project.team << [user, :developer] + end + + subject { access.push_allowed?(user, project, changes) } + + it { should be_true } + end + + def changes + ['6f6d7e7ed 570e7b2ab refs/heads/master'] + end +end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 99fed27c796..23867df39dd 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -2,45 +2,48 @@ require 'spec_helper' describe Gitlab::ReferenceExtractor do it 'extracts username references' do - subject.analyze "this contains a @user reference" - subject.users.should == ["user"] + subject.analyze('this contains a @user reference', nil) + subject.users.should == [{ project: nil, id: 'user' }] end it 'extracts issue references' do - subject.analyze "this one talks about issue #1234" - subject.issues.should == ["1234"] + subject.analyze('this one talks about issue #1234', nil) + subject.issues.should == [{ project: nil, id: '1234' }] end it 'extracts JIRA issue references' do - Gitlab.config.gitlab.stub(:issues_tracker).and_return("jira") - subject.analyze "this one talks about issue JIRA-1234" - subject.issues.should == ["JIRA-1234"] + Gitlab.config.gitlab.stub(:issues_tracker).and_return('jira') + subject.analyze('this one talks about issue JIRA-1234', nil) + subject.issues.should == [{ project: nil, id: 'JIRA-1234' }] end it 'extracts merge request references' do - subject.analyze "and here's !43, a merge request" - subject.merge_requests.should == ["43"] + subject.analyze("and here's !43, a merge request", nil) + subject.merge_requests.should == [{ project: nil, id: '43' }] end it 'extracts snippet ids' do - subject.analyze "snippets like $12 get extracted as well" - subject.snippets.should == ["12"] + subject.analyze('snippets like $12 get extracted as well', nil) + subject.snippets.should == [{ project: nil, id: '12' }] end it 'extracts commit shas' do - subject.analyze "commit shas 98cf0ae3 are pulled out as Strings" - subject.commits.should == ["98cf0ae3"] + subject.analyze('commit shas 98cf0ae3 are pulled out as Strings', nil) + subject.commits.should == [{ project: nil, id: '98cf0ae3' }] end it 'extracts multiple references and preserves their order' do - subject.analyze "@me and @you both care about this" - subject.users.should == ["me", "you"] + subject.analyze('@me and @you both care about this', nil) + subject.users.should == [ + { project: nil, id: 'me' }, + { project: nil, id: 'you' } + ] end it 'leaves the original note unmodified' do - text = "issue #123 is just the worst, @user" - subject.analyze text - text.should == "issue #123 is just the worst, @user" + text = 'issue #123 is just the worst, @user' + subject.analyze(text, nil) + text.should == 'issue #123 is just the worst, @user' end it 'handles all possible kinds of references' do @@ -59,7 +62,7 @@ describe Gitlab::ReferenceExtractor do project.team << [@u_foo, :reporter] project.team << [@u_bar, :guest] - subject.analyze "@foo, @baduser, @bar, and @offteam" + subject.analyze('@foo, @baduser, @bar, and @offteam', project) subject.users_for(project).should == [@u_foo, @u_bar] end @@ -67,7 +70,7 @@ describe Gitlab::ReferenceExtractor do @i0 = create(:issue, project: project) @i1 = create(:issue, project: project) - subject.analyze "##{@i0.iid}, ##{@i1.iid}, and #999." + subject.analyze("##{@i0.iid}, ##{@i1.iid}, and #999.", project) subject.issues_for(project).should == [@i0, @i1] end @@ -75,7 +78,7 @@ describe Gitlab::ReferenceExtractor do @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa') @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb') - subject.analyze "!999, !#{@m1.iid}, and !#{@m0.iid}." + subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.", project) subject.merge_requests_for(project).should == [@m1, @m0] end @@ -84,14 +87,15 @@ describe Gitlab::ReferenceExtractor do @s1 = create(:project_snippet, project: project) @s2 = create(:project_snippet) - subject.analyze "$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}" + subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}", project) subject.snippets_for(project).should == [@s0, @s1] end it 'accesses valid commits' do - commit = project.repository.commit("master") + commit = project.repository.commit('master') - subject.analyze "this references commits #{commit.sha[0..6]} and 012345" + subject.analyze("this references commits #{commit.sha[0..6]} and 012345", + project) extracted = subject.commits_for(project) extracted.should have(1).item extracted[0].sha.should == commit.sha diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb index 2af1e9e32f9..3eb1258d67e 100644 --- a/spec/lib/gitlab/satellite/action_spec.rb +++ b/spec/lib/gitlab/satellite/action_spec.rb @@ -97,7 +97,7 @@ describe 'Gitlab::Satellite::Action' do end class FileLockStatusChecker < File - def flocked? &block + def flocked?(&block) status = flock LOCK_EX|LOCK_NB case status when false diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 1673184cbe4..6f201adc4e8 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -53,11 +53,23 @@ eos describe '#closes_issues' do let(:issue) { create :issue, project: project } + let(:other_project) { create :project, :public } + let(:other_issue) { create :issue, project: other_project } it 'detects issues that this commit is marked as closing' do - commit.stub(issue_closing_regex: /^([Cc]loses|[Ff]ixes) #\d+/, safe_message: "Fixes ##{issue.iid}") + stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX', + /Fixes #\d+/) + commit.stub(safe_message: "Fixes ##{issue.iid}") commit.closes_issues(project).should == [issue] end + + it 'does not detect issues from other projects' do + ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}" + stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX', + /^([Cc]loses|[Ff]ixes)/) + commit.stub(safe_message: "Fixes #{ext_ref}") + commit.closes_issues(project).should be_empty + end end it_behaves_like 'a mentionable' do diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 8b299cea67c..6b6efe832e5 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -60,4 +60,8 @@ describe Issue do let(:backref_text) { "issue ##{subject.iid}" } let(:set_mentionable_text) { ->(txt){ subject.description = txt } } end + + it_behaves_like 'a Taskable' do + let(:subject) { create :issue } + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index c40f75290ed..7b0d261d72f 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -119,4 +119,8 @@ describe MergeRequest do let(:backref_text) { "merge request !#{subject.iid}" } let(:set_mentionable_text) { ->(txt){ subject.title = txt } } end + + it_behaves_like 'a Taskable' do + let(:subject) { create :merge_request, :simple } + end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index da51100e0d7..eeecd714a28 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -258,14 +258,25 @@ describe Note do its(:commit_id) { should == commit.id } its(:note) { should == "_mentioned in issue ##{issue.iid}_" } end + + context 'commit from commit' do + let(:parent_commit) { commit.parents.first } + subject { Note.create_cross_reference_note(commit, parent_commit, author, project) } + + it { should be_valid } + its(:noteable_type) { should == "Commit" } + its(:noteable_id) { should be_nil } + its(:commit_id) { should == commit.id } + its(:note) { should == "_mentioned in commit #{parent_commit.id[0...6]}_" } + end end describe '#cross_reference_exists?' do let(:project) { create :project } let(:author) { create :user } let(:issue) { create :issue } - let(:commit0) { double 'commit0', gfm_reference: 'commit 123456' } - let(:commit1) { double 'commit1', gfm_reference: 'commit 654321' } + let(:commit0) { project.repository.commit } + let(:commit1) { project.repository.commit('HEAD~2') } before do Note.create_cross_reference_note(issue, commit0, author, project) @@ -278,6 +289,15 @@ describe Note do it 'detects if a mentionable has not already been mentioned' do Note.cross_reference_exists?(issue, commit1).should be_false end + + context 'commit on commit' do + before do + Note.create_cross_reference_note(commit0, commit1, author, project) + end + + it { Note.cross_reference_exists?(commit0, commit1).should be_true } + it { Note.cross_reference_exists?(commit1, commit0).should be_false } + end end describe '#system?' do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 524cab2b925..48b58400a1e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -47,6 +47,7 @@ describe Project do it { should have_many(:protected_branches).dependent(:destroy) } it { should have_one(:forked_project_link).dependent(:destroy) } it { should have_one(:slack_service).dependent(:destroy) } + it { should have_one(:pushover_service).dependent(:destroy) } end describe "Mass assignment" do diff --git a/spec/models/pushover_service_spec.rb b/spec/models/pushover_service_spec.rb new file mode 100644 index 00000000000..59db69d7572 --- /dev/null +++ b/spec/models/pushover_service_spec.rb @@ -0,0 +1,69 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# active :boolean default(FALSE), not null +# properties :text +# + +require 'spec_helper' + +describe PushoverService do + describe 'Associations' do + it { should belong_to :project } + it { should have_one :service_hook } + end + + describe 'Validations' do + context 'active' do + before do + subject.active = true + end + + it { should validate_presence_of :api_key } + it { should validate_presence_of :user_key } + it { should validate_presence_of :priority } + end + end + + describe 'Execute' do + let(:pushover) { PushoverService.new } + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:sample_data) { GitPushService.new.sample_data(project, user) } + + let(:api_key) { 'verySecret' } + let(:user_key) { 'verySecret' } + let(:device) { 'myDevice' } + let(:priority) { 0 } + let(:sound) { 'bike' } + let(:api_url) { 'https://api.pushover.net/1/messages.json' } + + before do + pushover.stub( + project: project, + project_id: project.id, + service_hook: true, + api_key: api_key, + user_key: user_key, + device: device, + priority: priority, + sound: sound + ) + + WebMock.stub_request(:post, api_url) + end + + it 'should call Pushover API' do + pushover.execute(sample_data) + + WebMock.should have_requested(:post, api_url).once + end + end +end diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb index 4576913b473..3e555193b32 100644 --- a/spec/models/slack_service_spec.rb +++ b/spec/models/slack_service_spec.rb @@ -26,31 +26,28 @@ describe SlackService do subject.active = true end - it { should validate_presence_of :room } - it { should validate_presence_of :subdomain } - it { should validate_presence_of :token } + it { should validate_presence_of :webhook } end end describe "Execute" do let(:slack) { SlackService.new } + let(:slack_service) { SlackService.new } let(:user) { create(:user) } let(:project) { create(:project) } let(:sample_data) { GitPushService.new.sample_data(project, user) } - let(:subdomain) { 'gitlab' } - let(:token) { 'verySecret' } + let(:webhook) { 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' } + let(:new_webhook) { 'https://hooks.gitlabhq.slack.com/services/cdIj4r4LfXUOySDUjp0tk3OI' } let(:api_url) { - "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}" + 'https://gitlabhq.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI' } before do slack.stub( project: project, project_id: project.id, - room: '#gitlab', service_hook: true, - subdomain: subdomain, - token: token + webhook: webhook ) WebMock.stub_request(:post, api_url) @@ -61,5 +58,24 @@ describe SlackService do 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 + end end end diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb index d9d52468b15..b8943ea0762 100644 --- a/spec/requests/api/namespaces_spec.rb +++ b/spec/requests/api/namespaces_spec.rb @@ -20,8 +20,7 @@ describe API::API, api: true do response.status.should == 200 json_response.should be_an Array - # Admin namespace + 2 group namespaces - json_response.length.should == 3 + json_response.length.should == Namespace.count end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 571d8506277..aa1437c71aa 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -54,8 +54,15 @@ describe API::API, api: true do get api("/projects/all", admin) response.status.should == 200 json_response.should be_an Array - json_response.first['name'].should == project.name - json_response.first['owner']['username'].should == user.username + project_name = project.name + + json_response.detect { + |project| project['name'] == project_name + }['name'].should == project_name + + json_response.detect { + |project| project['owner']['username'] == user.username + }['owner']['username'].should == user.username end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index b0752ebe43c..bc1598273be 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -20,7 +20,10 @@ describe API::API, api: true do get api("/users", user) response.status.should == 200 json_response.should be_an Array - json_response.first['username'].should == user.username + username = user.username + json_response.detect { + |user| user['username'] == username + }['username'].should == username end end diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index cd8a076318c..791d2a1fd64 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -21,6 +21,6 @@ module LoginHelpers # Requires Javascript driver. def logout - find(:css, ".icon-signout").click + find(:css, ".fa.fa-sign-out").click end end diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb index 0d67e7ee4e6..692834c9f29 100644 --- a/spec/support/mentionable_shared_examples.rb +++ b/spec/support/mentionable_shared_examples.rb @@ -14,13 +14,23 @@ def common_mentionable_setup let(:mentioned_mr) { create :merge_request, :simple, source_project: mproject } let(:mentioned_commit) { double('commit', sha: '1234567890abcdef').as_null_object } + let(:ext_proj) { create :project, :public } + let(:ext_issue) { create :issue, project: ext_proj } + let(:other_ext_issue) { create :issue, project: ext_proj } + let(:ext_mr) { create :merge_request, :simple, source_project: ext_proj } + let(:ext_commit) { ext_proj.repository.commit } + # Override to add known commits to the repository stub. let(:extra_commits) { [] } # A string that mentions each of the +mentioned_.*+ objects above. Mentionables should add a self-reference # to this string and place it in their +mentionable_text+. let(:ref_string) do - "mentions ##{mentioned_issue.iid} twice ##{mentioned_issue.iid}, !#{mentioned_mr.iid}, " + + "mentions ##{mentioned_issue.iid} twice ##{mentioned_issue.iid}, " + + "!#{mentioned_mr.iid}, " + + "#{ext_proj.path_with_namespace}##{ext_issue.iid}, " + + "#{ext_proj.path_with_namespace}!#{ext_mr.iid}, " + + "#{ext_proj.path_with_namespace}@#{ext_commit.id[0..5]}, " + "#{mentioned_commit.sha[0..5]} and itself as #{backref_text}" end @@ -45,14 +55,20 @@ shared_examples 'a mentionable' do # De-duplicate and omit itself refs = subject.references(mproject) - refs.should have(3).items + refs.should have(6).items refs.should include(mentioned_issue) refs.should include(mentioned_mr) refs.should include(mentioned_commit) + refs.should include(ext_issue) + refs.should include(ext_mr) + refs.should include(ext_commit) end it 'creates cross-reference notes' do - [mentioned_issue, mentioned_mr, mentioned_commit].each do |referenced| + mentioned_objects = [mentioned_issue, mentioned_mr, mentioned_commit, + ext_issue, ext_mr, ext_commit] + + mentioned_objects.each do |referenced| Note.should_receive(:create_cross_reference_note).with(referenced, subject.local_reference, mauthor, mproject) end @@ -73,15 +89,25 @@ shared_examples 'an editable mentionable' do it_behaves_like 'a mentionable' it 'creates new cross-reference notes when the mentionable text is edited' do - new_text = "this text still mentions ##{mentioned_issue.iid} and #{mentioned_commit.sha[0..5]}, " + - "but now it mentions ##{other_issue.iid}, too." + new_text = "still mentions ##{mentioned_issue.iid}, " + + "#{mentioned_commit.sha[0..5]}, " + + "#{ext_issue.iid}, " + + "new refs: ##{other_issue.iid}, " + + "#{ext_proj.path_with_namespace}##{other_ext_issue.iid}" - [mentioned_issue, mentioned_commit].each do |oldref| + [mentioned_issue, mentioned_commit, ext_issue].each do |oldref| Note.should_not_receive(:create_cross_reference_note).with(oldref, subject.local_reference, mauthor, mproject) end - Note.should_receive(:create_cross_reference_note).with(other_issue, subject.local_reference, mauthor, mproject) + [other_issue, other_ext_issue].each do |newref| + Note.should_receive(:create_cross_reference_note).with( + newref, + subject.local_reference, + mauthor, + mproject + ) + end subject.save set_mentionable_text.call(new_text) diff --git a/spec/support/taskable_shared_examples.rb b/spec/support/taskable_shared_examples.rb new file mode 100644 index 00000000000..42252675683 --- /dev/null +++ b/spec/support/taskable_shared_examples.rb @@ -0,0 +1,42 @@ +# Specs for task state functionality for issues and merge requests. +# +# Requires a context containing: +# let(:subject) { Issue or MergeRequest } +shared_examples 'a Taskable' do + before do + subject.description = <<EOT.gsub(/ {6}/, '') + * [ ] Task 1 + * [x] Task 2 + * [x] Task 3 + * [ ] Task 4 + * [ ] Task 5 +EOT + end + + it 'updates the Nth task correctly' do + subject.update_nth_task(1, true) + expect(subject.description).to match(/\[x\] Task 1/) + + subject.update_nth_task(2, true) + expect(subject.description).to match('\[x\] Task 2') + + subject.update_nth_task(3, false) + expect(subject.description).to match('\[ \] Task 3') + + subject.update_nth_task(4, false) + expect(subject.description).to match('\[ \] Task 4') + end + + it 'returns the correct task status' do + expect(subject.task_status).to match('5 tasks') + expect(subject.task_status).to match('2 done') + expect(subject.task_status).to match('3 unfinished') + end + + it 'knows if it has tasks' do + expect(subject.tasks?).to be_true + + subject.description = 'Now I have no tasks' + expect(subject.tasks?).to be_false + end +end |