diff options
Diffstat (limited to 'spec/models/merge_request_spec.rb')
-rw-r--r-- | spec/models/merge_request_spec.rb | 222 |
1 files changed, 212 insertions, 10 deletions
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 9eef08c6d00..3b199f4d98d 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -119,7 +119,8 @@ describe MergeRequest, models: true do before do allow(merge_request).to receive(:commits) { [merge_request.source_project.repository.commit] } - create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.project) + create(:note_on_commit, commit_id: merge_request.commits.first.id, + project: merge_request.project) create(:note, noteable: merge_request, project: merge_request.project) end @@ -129,7 +130,9 @@ describe MergeRequest, models: true do end it "should include notes for commits from target project as well" do - create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.target_project) + create(:note_on_commit, commit_id: merge_request.commits.first.id, + project: merge_request.target_project) + expect(merge_request.commits).not_to be_empty expect(merge_request.mr_and_commit_notes.count).to eq(3) end @@ -260,13 +263,18 @@ describe MergeRequest, models: true do end describe "#reset_merge_when_build_succeeds" do - let(:merge_if_green) { create :merge_request, merge_when_build_succeeds: true, merge_user: create(:user) } + 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 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 + expect(merge_if_green.merge_params["should_remove_source_branch"]).to be_nil + expect(merge_if_green.merge_params["commit_message"]).to be_nil end end @@ -382,19 +390,19 @@ describe MergeRequest, models: true do subject { create :merge_request, :simple } end - describe '#ci_commit' do + describe '#pipeline' do describe 'when the source project exists' do it 'returns the latest commit' do - commit = double(:commit, id: '123abc') - ci_commit = double(:ci_commit, ref: 'master') + commit = double(:commit, id: '123abc') + pipeline = double(:ci_pipeline, ref: 'master') allow(subject).to receive(:last_commit).and_return(commit) - expect(subject.source_project).to receive(:ci_commit). + expect(subject.source_project).to receive(:pipeline). with('123abc', 'master'). - and_return(ci_commit) + and_return(pipeline) - expect(subject.ci_commit).to eq(ci_commit) + expect(subject.pipeline).to eq(pipeline) end end @@ -402,7 +410,201 @@ describe MergeRequest, models: true do it 'returns nil' do allow(subject).to receive(:source_project).and_return(nil) - expect(subject.ci_commit).to be_nil + expect(subject.pipeline).to be_nil + end + end + end + + 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 + + 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 + + describe '#check_if_can_be_merged' do + let(:project) { create(:project, only_allow_merge_if_build_succeeds: true) } + + subject { create(:merge_request, source_project: project, merge_status: :unchecked) } + + context 'when it is not broken and has no conflicts' do + it 'is marked as mergeable' do + allow(subject).to receive(:broken?) { false } + allow(project).to receive_message_chain(:repository, :can_be_merged?) { true } + + expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('can_be_merged') + end + end + + context 'when broken' do + before { allow(subject).to receive(:broken?) { true } } + + it 'becomes unmergeable' do + expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged') + end + end + + context 'when it has conflicts' do + before do + allow(subject).to receive(:broken?) { false } + allow(project).to receive_message_chain(:repository, :can_be_merged?) { false } + end + + it 'becomes unmergeable' do + expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged') + end + end + end + + describe '#mergeable?' do + let(:project) { create(:project) } + + subject { create(:merge_request, source_project: project) } + + it 'returns false if #mergeable_state? is false' do + expect(subject).to receive(:mergeable_state?) { false } + + expect(subject.mergeable?).to be_falsey + end + + it 'return true if #mergeable_state? is true and the MR #can_be_merged? is true' do + allow(subject).to receive(:mergeable_state?) { true } + expect(subject).to receive(:check_if_can_be_merged) + expect(subject).to receive(:can_be_merged?) { true } + + expect(subject.mergeable?).to be_truthy + end + end + + describe '#mergeable_state?' do + let(:project) { create(:project) } + + subject { create(:merge_request, source_project: project) } + + it 'checks if merge request can be merged' do + allow(subject).to receive(:mergeable_ci_state?) { true } + expect(subject).to receive(:check_if_can_be_merged) + + subject.mergeable? + end + + context 'when not open' do + before { subject.close } + + it 'returns false' do + expect(subject.mergeable_state?).to be_falsey + end + end + + context 'when working in progress' do + before { subject.title = 'WIP MR' } + + it 'returns false' do + expect(subject.mergeable_state?).to be_falsey + end + end + + context 'when broken' do + before { allow(subject).to receive(:broken?) { true } } + + it 'returns false' do + expect(subject.mergeable_state?).to be_falsey + end + end + + context 'when failed' do + before { allow(subject).to receive(:broken?) { false } } + + context 'when project settings restrict to merge only if build succeeds and build failed' do + before do + project.only_allow_merge_if_build_succeeds = true + allow(subject).to receive(:mergeable_ci_state?) { false } + end + + it 'returns false' do + expect(subject.mergeable_state?).to be_falsey + end + end + end + end + + describe '#mergeable_ci_state?' do + let(:project) { create(:empty_project, only_allow_merge_if_build_succeeds: true) } + let(:pipeline) { create(:ci_empty_pipeline) } + + subject { build(:merge_request, target_project: project) } + + context 'when it is only allowed to merge when build is green' do + context 'and a failed pipeline is associated' do + before do + pipeline.statuses << create(:commit_status, status: 'failed', project: project) + allow(subject).to receive(:pipeline) { pipeline } + end + + it { expect(subject.mergeable_ci_state?).to be_falsey } + end + + context 'when no pipeline is associated' do + before do + allow(subject).to receive(:pipeline) { nil } + end + + it { expect(subject.mergeable_ci_state?).to be_truthy } + end + end + + context 'when merges are not restricted to green builds' do + subject { build(:merge_request, target_project: build(:empty_project, only_allow_merge_if_build_succeeds: false)) } + + context 'and a failed pipeline is associated' do + before do + pipeline.statuses << create(:commit_status, status: 'failed', project: project) + allow(subject).to receive(:pipeline) { pipeline } + end + + it { expect(subject.mergeable_ci_state?).to be_truthy } + end + + context 'when no pipeline is associated' do + before do + allow(subject).to receive(:pipeline) { nil } + end + + it { expect(subject.mergeable_ci_state?).to be_truthy } end end end |