summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorKeith Pitt <me@keithpitt.com>2014-10-08 16:33:53 +0800
committerKeith Pitt <me@keithpitt.com>2014-10-08 16:33:53 +0800
commit4c7da578f200f0bc721cc2cae27eb2b25f96e8dd (patch)
tree565b5b7746bc2cff8e46883b4d1836dfaa0246ef /spec
parent76594d474ca6d04c2e608e7b3df1229729288f14 (diff)
parent928178deb9d582d7537a57983ff9e695f07dab1f (diff)
downloadgitlab-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.rb10
-rw-r--r--spec/helpers/gitlab_markdown_helper_spec.rb203
-rw-r--r--spec/helpers/notifications_helper_spec.rb8
-rw-r--r--spec/lib/gitlab/git_access_wiki_spec.rb22
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb52
-rw-r--r--spec/lib/gitlab/satellite/action_spec.rb2
-rw-r--r--spec/models/commit_spec.rb14
-rw-r--r--spec/models/issue_spec.rb4
-rw-r--r--spec/models/merge_request_spec.rb4
-rw-r--r--spec/models/note_spec.rb24
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/models/pushover_service_spec.rb69
-rw-r--r--spec/models/slack_service_spec.rb34
-rw-r--r--spec/requests/api/namespaces_spec.rb3
-rw-r--r--spec/requests/api/projects_spec.rb11
-rw-r--r--spec/requests/api/users_spec.rb5
-rw-r--r--spec/support/login_helpers.rb2
-rw-r--r--spec/support/mentionable_shared_examples.rb40
-rw-r--r--spec/support/taskable_shared_examples.rb42
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