2011-11-28 02:39:43 -05:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2015-12-09 04:50:51 -05:00
|
|
|
describe MergeRequest, models: true do
|
2015-05-02 23:11:21 -04:00
|
|
|
subject { create(:merge_request) }
|
|
|
|
|
2015-05-02 23:14:31 -04:00
|
|
|
describe 'associations' do
|
|
|
|
it { is_expected.to belong_to(:target_project).with_foreign_key(:target_project_id).class_name('Project') }
|
|
|
|
it { is_expected.to belong_to(:source_project).with_foreign_key(:source_project_id).class_name('Project') }
|
2015-11-18 05:17:41 -05:00
|
|
|
it { is_expected.to belong_to(:merge_user).class_name("User") }
|
2015-05-02 23:14:31 -04:00
|
|
|
it { is_expected.to have_one(:merge_request_diff).dependent(:destroy) }
|
|
|
|
end
|
|
|
|
|
2015-05-02 23:11:21 -04:00
|
|
|
describe 'modules' do
|
|
|
|
subject { described_class }
|
|
|
|
|
|
|
|
it { is_expected.to include_module(InternalId) }
|
|
|
|
it { is_expected.to include_module(Issuable) }
|
|
|
|
it { is_expected.to include_module(Referable) }
|
|
|
|
it { is_expected.to include_module(Sortable) }
|
|
|
|
it { is_expected.to include_module(Taskable) }
|
|
|
|
end
|
|
|
|
|
2016-02-26 03:55:43 -05:00
|
|
|
describe "act_as_paranoid" do
|
|
|
|
it { is_expected.to have_db_column(:deleted_at) }
|
|
|
|
it { is_expected.to have_db_index(:deleted_at) }
|
|
|
|
end
|
|
|
|
|
2015-05-02 23:11:21 -04:00
|
|
|
describe 'validation' do
|
2015-02-12 13:17:35 -05:00
|
|
|
it { is_expected.to validate_presence_of(:target_branch) }
|
|
|
|
it { is_expected.to validate_presence_of(:source_branch) }
|
2015-12-03 04:27:34 -05:00
|
|
|
|
|
|
|
context "Validation of merge user with Merge When Build succeeds" do
|
|
|
|
it "allows user to be nil when the feature is disabled" do
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "is invalid without merge user" do
|
|
|
|
subject.merge_when_build_succeeds = true
|
|
|
|
expect(subject).not_to be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "is valid with merge user" do
|
|
|
|
subject.merge_when_build_succeeds = true
|
|
|
|
subject.merge_user = build(:user)
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
end
|
2011-11-28 16:24:08 -05:00
|
|
|
end
|
|
|
|
|
2015-05-02 23:14:31 -04:00
|
|
|
describe 'respond to' do
|
2015-02-12 13:17:35 -05:00
|
|
|
it { is_expected.to respond_to(:unchecked?) }
|
|
|
|
it { is_expected.to respond_to(:can_be_merged?) }
|
|
|
|
it { is_expected.to respond_to(:cannot_be_merged?) }
|
2015-11-18 05:17:41 -05:00
|
|
|
it { is_expected.to respond_to(:merge_params) }
|
|
|
|
it { is_expected.to respond_to(:merge_when_build_succeeds) }
|
2013-02-20 08:15:01 -05:00
|
|
|
end
|
2013-03-20 17:46:30 -04:00
|
|
|
|
2016-03-07 06:56:46 -05:00
|
|
|
describe '.in_projects' do
|
|
|
|
it 'returns the merge requests for a set of projects' do
|
|
|
|
expect(described_class.in_projects(Project.all)).to eq([subject])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-18 13:16:04 -04:00
|
|
|
describe '#target_sha' do
|
|
|
|
context 'when the target branch does not exist anymore' do
|
2016-04-26 18:57:37 -04:00
|
|
|
let(:project) { create(:project) }
|
|
|
|
|
|
|
|
subject { create(:merge_request, source_project: project, target_project: project) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
project.repository.raw_repository.delete_branch(subject.target_branch)
|
|
|
|
end
|
2016-03-18 13:16:04 -04:00
|
|
|
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(subject.target_sha).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-09 01:51:52 -05:00
|
|
|
describe '#source_sha' do
|
|
|
|
let(:last_branch_commit) { subject.source_project.repository.commit(subject.source_branch) }
|
|
|
|
|
|
|
|
context 'with diffs' do
|
|
|
|
subject { create(:merge_request, :with_diffs) }
|
|
|
|
it 'returns the sha of the source branch last commit' do
|
|
|
|
expect(subject.source_sha).to eq(last_branch_commit.sha)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-09 02:19:54 -05:00
|
|
|
context 'without diffs' do
|
|
|
|
subject { create(:merge_request, :without_diffs) }
|
|
|
|
it 'returns the sha of the source branch last commit' do
|
|
|
|
expect(subject.source_sha).to eq(last_branch_commit.sha)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-09 01:51:52 -05:00
|
|
|
context 'when the merge request is being created' do
|
|
|
|
subject { build(:merge_request, source_branch: nil, compare_commits: []) }
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(subject.source_sha).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-05-02 23:11:21 -04:00
|
|
|
describe '#to_reference' do
|
|
|
|
it 'returns a String reference to the object' do
|
|
|
|
expect(subject.to_reference).to eq "!#{subject.iid}"
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'supports a cross-project reference' do
|
|
|
|
cross = double('project')
|
|
|
|
expect(subject.to_reference(cross)).to eq "#{subject.source_project.to_reference}!#{subject.iid}"
|
|
|
|
end
|
2012-08-09 13:45:12 -04:00
|
|
|
end
|
2012-10-04 18:25:40 -04:00
|
|
|
|
|
|
|
describe "#mr_and_commit_notes" do
|
2012-11-05 22:31:55 -05:00
|
|
|
let!(:merge_request) { create(:merge_request) }
|
2012-10-04 18:25:40 -04:00
|
|
|
|
|
|
|
before do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(merge_request).to receive(:commits) { [merge_request.source_project.repository.commit] }
|
2016-04-26 07:52:18 -04:00
|
|
|
create(:note_on_commit, commit_id: merge_request.commits.first.id,
|
|
|
|
project: merge_request.project)
|
2013-10-07 12:42:59 -04:00
|
|
|
create(:note, noteable: merge_request, project: merge_request.project)
|
2012-10-04 18:25:40 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "should include notes for commits" do
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(merge_request.commits).not_to be_empty
|
|
|
|
expect(merge_request.mr_and_commit_notes.count).to eq(2)
|
2012-10-04 18:25:40 -04:00
|
|
|
end
|
2015-10-22 12:38:00 -04:00
|
|
|
|
|
|
|
it "should include notes for commits from target project as well" do
|
2016-04-26 07:52:18 -04:00
|
|
|
create(:note_on_commit, commit_id: merge_request.commits.first.id,
|
|
|
|
project: merge_request.target_project)
|
|
|
|
|
2015-10-22 12:38:00 -04:00
|
|
|
expect(merge_request.commits).not_to be_empty
|
|
|
|
expect(merge_request.mr_and_commit_notes.count).to eq(3)
|
|
|
|
end
|
2012-10-04 18:25:40 -04:00
|
|
|
end
|
2012-10-09 18:25:29 -04:00
|
|
|
|
|
|
|
describe '#is_being_reassigned?' do
|
|
|
|
it 'returns true if the merge_request assignee has changed' do
|
2012-11-05 22:31:55 -05:00
|
|
|
subject.assignee = create(:user)
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.is_being_reassigned?).to be_truthy
|
2012-10-09 18:25:29 -04:00
|
|
|
end
|
|
|
|
it 'returns false if the merge request assignee has not changed' do
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.is_being_reassigned?).to be_falsey
|
2012-10-09 18:25:29 -04:00
|
|
|
end
|
|
|
|
end
|
2013-04-25 10:15:33 -04:00
|
|
|
|
|
|
|
describe '#for_fork?' do
|
|
|
|
it 'returns true if the merge request is for a fork' do
|
2014-01-23 06:24:25 -05:00
|
|
|
subject.source_project = create(:project, namespace: create(:group))
|
|
|
|
subject.target_project = create(:project, namespace: create(:group))
|
2013-04-25 10:15:33 -04:00
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.for_fork?).to be_truthy
|
2013-04-25 10:15:33 -04:00
|
|
|
end
|
2014-01-23 06:24:25 -05:00
|
|
|
|
2013-04-25 10:15:33 -04:00
|
|
|
it 'returns false if is not for a fork' do
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.for_fork?).to be_falsey
|
2013-04-25 10:15:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-05-30 19:16:49 -04:00
|
|
|
describe 'detection of issues to be closed' do
|
|
|
|
let(:issue0) { create :issue, project: subject.project }
|
|
|
|
let(:issue1) { create :issue, project: subject.project }
|
2016-01-27 08:09:58 -05:00
|
|
|
|
|
|
|
let(:commit0) { double('commit0', safe_message: "Fixes #{issue0.to_reference}") }
|
|
|
|
let(:commit1) { double('commit1', safe_message: "Fixes #{issue0.to_reference}") }
|
|
|
|
let(:commit2) { double('commit2', safe_message: "Fixes #{issue1.to_reference}") }
|
2013-05-30 19:16:49 -04:00
|
|
|
|
|
|
|
before do
|
2016-03-17 16:39:50 -04:00
|
|
|
subject.project.team << [subject.author, :developer]
|
2015-05-21 17:49:06 -04:00
|
|
|
allow(subject).to receive(:commits).and_return([commit0, commit1, commit2])
|
2013-05-30 19:16:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'accesses the set of issues that will be closed on acceptance' do
|
2015-05-21 17:49:06 -04:00
|
|
|
allow(subject.project).to receive(:default_branch).
|
|
|
|
and_return(subject.target_branch)
|
2013-05-30 19:16:49 -04:00
|
|
|
|
2016-01-27 08:09:58 -05:00
|
|
|
closed = subject.closes_issues
|
|
|
|
|
|
|
|
expect(closed).to include(issue0, issue1)
|
2013-05-30 19:16:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'only lists issues as to be closed if it targets the default branch' do
|
2015-05-21 17:49:06 -04:00
|
|
|
allow(subject.project).to receive(:default_branch).and_return('master')
|
2013-05-30 19:16:49 -04:00
|
|
|
subject.target_branch = 'something-else'
|
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.closes_issues).to be_empty
|
2013-05-30 19:16:49 -04:00
|
|
|
end
|
2014-06-13 10:19:08 -04:00
|
|
|
|
|
|
|
it 'detects issues mentioned in the description' do
|
|
|
|
issue2 = create(:issue, project: subject.project)
|
2015-05-21 16:35:15 -04:00
|
|
|
subject.description = "Closes #{issue2.to_reference}"
|
2015-05-21 17:49:06 -04:00
|
|
|
allow(subject.project).to receive(:default_branch).
|
|
|
|
and_return(subject.target_branch)
|
2014-06-13 10:19:08 -04:00
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(subject.closes_issues).to include(issue2)
|
2014-06-13 10:19:08 -04:00
|
|
|
end
|
2013-05-30 19:16:49 -04:00
|
|
|
end
|
|
|
|
|
2015-04-30 09:43:32 -04:00
|
|
|
describe "#work_in_progress?" do
|
2016-03-18 18:27:35 -04:00
|
|
|
['WIP ', 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', ' [WIP] WIP [WIP] WIP: WIP '].each do |wip_prefix|
|
|
|
|
it "detects the '#{wip_prefix}' prefix" do
|
|
|
|
subject.title = "#{wip_prefix}#{subject.title}"
|
2016-03-28 19:41:00 -04:00
|
|
|
expect(subject.work_in_progress?).to eq true
|
2016-03-18 18:27:35 -04:00
|
|
|
end
|
2015-11-23 13:36:47 -05:00
|
|
|
end
|
|
|
|
|
2015-04-30 09:43:32 -04:00
|
|
|
it "doesn't detect WIP for words starting with WIP" do
|
|
|
|
subject.title = "Wipwap #{subject.title}"
|
2016-03-28 19:41:00 -04:00
|
|
|
expect(subject.work_in_progress?).to eq false
|
2015-04-30 09:43:32 -04:00
|
|
|
end
|
|
|
|
|
2016-03-18 18:27:35 -04:00
|
|
|
it "doesn't detect WIP for words containing with WIP" do
|
|
|
|
subject.title = "WupWipwap #{subject.title}"
|
2016-03-28 19:41:00 -04:00
|
|
|
expect(subject.work_in_progress?).to eq false
|
2016-03-18 18:27:35 -04:00
|
|
|
end
|
|
|
|
|
2015-04-30 09:43:32 -04:00
|
|
|
it "doesn't detect WIP by default" do
|
2016-03-28 19:41:00 -04:00
|
|
|
expect(subject.work_in_progress?).to eq false
|
2015-04-30 09:43:32 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-12-07 03:59:04 -05:00
|
|
|
describe '#can_remove_source_branch?' do
|
2015-12-03 04:27:34 -05:00
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:user2) { create(:user) }
|
2015-11-24 08:59:02 -05:00
|
|
|
|
|
|
|
before do
|
|
|
|
subject.source_project.team << [user, :master]
|
|
|
|
|
2015-12-03 04:27:34 -05:00
|
|
|
subject.source_branch = "feature"
|
|
|
|
subject.target_branch = "master"
|
|
|
|
subject.save!
|
|
|
|
end
|
2015-11-24 08:59:02 -05:00
|
|
|
|
2015-12-03 04:27:34 -05:00
|
|
|
it "can't be removed when its a protected branch" do
|
|
|
|
allow(subject.source_project).to receive(:protected_branch?).and_return(true)
|
2015-11-24 08:59:02 -05:00
|
|
|
expect(subject.can_remove_source_branch?(user)).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it "cant remove a root ref" do
|
2015-12-03 04:27:34 -05:00
|
|
|
subject.source_branch = "master"
|
|
|
|
subject.target_branch = "feature"
|
2015-11-24 08:59:02 -05:00
|
|
|
|
|
|
|
expect(subject.can_remove_source_branch?(user)).to be_falsey
|
|
|
|
end
|
|
|
|
|
2015-12-03 04:27:34 -05:00
|
|
|
it "is unable to remove the source branch for a project the user cannot push to" do
|
|
|
|
expect(subject.can_remove_source_branch?(user2)).to be_falsey
|
|
|
|
end
|
|
|
|
|
2016-02-04 05:51:12 -05:00
|
|
|
it "can be removed if the last commit is the head of the source branch" do
|
|
|
|
allow(subject.source_project).to receive(:commit).and_return(subject.last_commit)
|
|
|
|
|
2015-12-03 04:27:34 -05:00
|
|
|
expect(subject.can_remove_source_branch?(user)).to be_truthy
|
2015-11-24 08:59:02 -05:00
|
|
|
end
|
2016-02-04 05:51:12 -05:00
|
|
|
|
|
|
|
it "cannot be removed if the last commit is not also the head of the source branch" do
|
|
|
|
expect(subject.can_remove_source_branch?(user)).to be_falsey
|
|
|
|
end
|
2015-11-24 08:59:02 -05:00
|
|
|
end
|
|
|
|
|
2015-11-18 05:17:41 -05:00
|
|
|
describe "#reset_merge_when_build_succeeds" do
|
2016-02-12 15:41:31 -05:00
|
|
|
let(:merge_if_green) do
|
|
|
|
create :merge_request, merge_when_build_succeeds: true, merge_user: create(:user),
|
|
|
|
merge_params: { "should_remove_source_branch" => "1", "commit_message" => "msg" }
|
|
|
|
end
|
2015-12-03 04:27:34 -05:00
|
|
|
|
2015-11-18 05:17:41 -05:00
|
|
|
it "sets the item to false" do
|
|
|
|
merge_if_green.reset_merge_when_build_succeeds
|
|
|
|
merge_if_green.reload
|
|
|
|
|
|
|
|
expect(merge_if_green.merge_when_build_succeeds).to be_falsey
|
2016-02-12 15:41:31 -05:00
|
|
|
expect(merge_if_green.merge_params["should_remove_source_branch"]).to be_nil
|
|
|
|
expect(merge_if_green.merge_params["commit_message"]).to be_nil
|
2015-11-18 05:17:41 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-09-25 16:07:08 -04:00
|
|
|
describe "#hook_attrs" do
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
let(:attrs_hash) { subject.hook_attrs.to_h }
|
|
|
|
|
|
|
|
[:source, :target].each do |key|
|
|
|
|
describe "#{key} key" do
|
|
|
|
include_examples 'project hook data', project_key: key do
|
|
|
|
let(:data) { attrs_hash }
|
|
|
|
let(:project) { subject.send("#{key}_project") }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-09-25 16:07:08 -04:00
|
|
|
it "has all the required keys" do
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
expect(attrs_hash).to include(:source)
|
|
|
|
expect(attrs_hash).to include(:target)
|
|
|
|
expect(attrs_hash).to include(:last_commit)
|
|
|
|
expect(attrs_hash).to include(:work_in_progress)
|
2015-09-25 16:07:08 -04:00
|
|
|
end
|
2016-02-04 13:23:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
describe '#diverged_commits_count' do
|
|
|
|
let(:project) { create(:project) }
|
|
|
|
let(:fork_project) { create(:project, forked_from_project: project) }
|
|
|
|
|
2016-03-18 13:16:04 -04:00
|
|
|
context 'when the target branch does not exist anymore' do
|
2016-04-26 18:57:37 -04:00
|
|
|
subject { create(:merge_request, source_project: project, target_project: project) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
project.repository.raw_repository.delete_branch(subject.target_branch)
|
|
|
|
subject.reload
|
|
|
|
end
|
2016-03-18 13:16:04 -04:00
|
|
|
|
|
|
|
it 'does not crash' do
|
|
|
|
expect{ subject.diverged_commits_count }.not_to raise_error
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns 0' do
|
|
|
|
expect(subject.diverged_commits_count).to eq(0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-04 13:23:58 -05:00
|
|
|
context 'diverged on same repository' do
|
|
|
|
subject(:merge_request_with_divergence) { create(:merge_request, :diverged, source_project: project, target_project: project) }
|
|
|
|
|
|
|
|
it 'counts commits that are on target branch but not on source branch' do
|
|
|
|
expect(subject.diverged_commits_count).to eq(5)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'diverged on fork' do
|
|
|
|
subject(:merge_request_fork_with_divergence) { create(:merge_request, :diverged, source_project: fork_project, target_project: project) }
|
|
|
|
|
|
|
|
it 'counts commits that are on target branch but not on source branch' do
|
|
|
|
expect(subject.diverged_commits_count).to eq(5)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'rebased on fork' do
|
|
|
|
subject(:merge_request_rebased) { create(:merge_request, :rebased, source_project: fork_project, target_project: project) }
|
|
|
|
|
|
|
|
it 'counts commits that are on target branch but not on source branch' do
|
|
|
|
expect(subject.diverged_commits_count).to eq(0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'caching' do
|
|
|
|
before(:example) do
|
|
|
|
allow(Rails).to receive(:cache).and_return(ActiveSupport::Cache::MemoryStore.new)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'caches the output' do
|
|
|
|
expect(subject).to receive(:compute_diverged_commits_count).
|
|
|
|
once.
|
|
|
|
and_return(2)
|
|
|
|
|
|
|
|
subject.diverged_commits_count
|
|
|
|
subject.diverged_commits_count
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'invalidates the cache when the source sha changes' do
|
|
|
|
expect(subject).to receive(:compute_diverged_commits_count).
|
|
|
|
twice.
|
|
|
|
and_return(2)
|
|
|
|
|
|
|
|
subject.diverged_commits_count
|
|
|
|
allow(subject).to receive(:source_sha).and_return('123abc')
|
|
|
|
subject.diverged_commits_count
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'invalidates the cache when the target sha changes' do
|
|
|
|
expect(subject).to receive(:compute_diverged_commits_count).
|
|
|
|
twice.
|
|
|
|
and_return(2)
|
|
|
|
|
|
|
|
subject.diverged_commits_count
|
|
|
|
allow(subject).to receive(:target_sha).and_return('123abc')
|
|
|
|
subject.diverged_commits_count
|
|
|
|
end
|
|
|
|
end
|
2015-09-25 16:07:08 -04:00
|
|
|
end
|
|
|
|
|
2013-05-30 19:16:49 -04:00
|
|
|
it_behaves_like 'an editable mentionable' do
|
2015-08-11 08:33:31 -04:00
|
|
|
subject { create(:merge_request) }
|
2015-04-16 16:25:25 -04:00
|
|
|
|
2015-06-17 20:40:26 -04:00
|
|
|
let(:backref_text) { "merge request #{subject.to_reference}" }
|
|
|
|
let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
|
2013-05-30 19:16:49 -04:00
|
|
|
end
|
2014-10-05 22:17:28 -04:00
|
|
|
|
|
|
|
it_behaves_like 'a Taskable' do
|
2015-04-16 16:25:25 -04:00
|
|
|
subject { create :merge_request, :simple }
|
2014-10-05 22:17:28 -04:00
|
|
|
end
|
2015-11-20 17:43:10 -05:00
|
|
|
|
2016-06-03 08:46:17 -04:00
|
|
|
describe '#pipeline' do
|
2015-11-20 17:43:10 -05:00
|
|
|
describe 'when the source project exists' do
|
|
|
|
it 'returns the latest commit' do
|
2016-06-03 08:46:17 -04:00
|
|
|
commit = double(:commit, id: '123abc')
|
2016-06-03 10:22:26 -04:00
|
|
|
pipeline = double(:ci_pipeline, ref: 'master')
|
2015-11-20 17:43:10 -05:00
|
|
|
|
|
|
|
allow(subject).to receive(:last_commit).and_return(commit)
|
|
|
|
|
2016-06-03 08:46:17 -04:00
|
|
|
expect(subject.source_project).to receive(:pipeline).
|
2016-04-11 10:55:40 -04:00
|
|
|
with('123abc', 'master').
|
2016-06-03 08:46:17 -04:00
|
|
|
and_return(pipeline)
|
2015-11-20 17:43:10 -05:00
|
|
|
|
2016-06-03 08:46:17 -04:00
|
|
|
expect(subject.pipeline).to eq(pipeline)
|
2015-11-20 17:43:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'when the source project does not exist' do
|
|
|
|
it 'returns nil' do
|
|
|
|
allow(subject).to receive(:source_project).and_return(nil)
|
|
|
|
|
2016-06-02 10:19:18 -04:00
|
|
|
expect(subject.pipeline).to be_nil
|
2015-11-20 17:43:10 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-05-26 07:38:28 -04:00
|
|
|
|
|
|
|
describe '#participants' do
|
|
|
|
let(:project) { create(:project, :public) }
|
|
|
|
|
|
|
|
let(:mr) do
|
|
|
|
create(:merge_request, source_project: project, target_project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
let!(:note1) do
|
|
|
|
create(:note_on_merge_request, noteable: mr, project: project, note: 'a')
|
|
|
|
end
|
|
|
|
|
|
|
|
let!(:note2) do
|
|
|
|
create(:note_on_merge_request, noteable: mr, project: project, note: 'b')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes the merge request author' do
|
|
|
|
expect(mr.participants).to include(mr.author)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes the authors of the notes' do
|
|
|
|
expect(mr.participants).to include(note1.author, note2.author)
|
|
|
|
end
|
|
|
|
end
|
2016-06-02 09:25:40 -04:00
|
|
|
|
|
|
|
describe 'cached counts' do
|
|
|
|
it 'updates when assignees change' do
|
|
|
|
user1 = create(:user)
|
|
|
|
user2 = create(:user)
|
|
|
|
mr = create(:merge_request, assignee: user1)
|
|
|
|
|
|
|
|
expect(user1.assigned_open_merge_request_count).to eq(1)
|
|
|
|
expect(user2.assigned_open_merge_request_count).to eq(0)
|
|
|
|
|
|
|
|
mr.assignee = user2
|
|
|
|
mr.save
|
|
|
|
|
|
|
|
expect(user1.assigned_open_merge_request_count).to eq(0)
|
|
|
|
expect(user2.assigned_open_merge_request_count).to eq(1)
|
|
|
|
end
|
|
|
|
end
|
2011-11-28 02:39:43 -05:00
|
|
|
end
|