2019-04-11 08:17:24 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-01-17 19:34:34 -05:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-07-10 10:24:02 -04:00
|
|
|
describe MergeRequests::MergeService do
|
2020-01-10 04:07:49 -05:00
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
let_it_be(:user2) { create(:user) }
|
2019-04-07 14:35:16 -04:00
|
|
|
let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
|
2015-01-17 19:34:34 -05:00
|
|
|
let(:project) { merge_request.project }
|
|
|
|
|
|
|
|
before do
|
2018-07-11 10:36:08 -04:00
|
|
|
project.add_maintainer(user)
|
2017-12-13 12:14:51 -05:00
|
|
|
project.add_developer(user2)
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
|
|
|
|
2016-07-11 18:12:31 -04:00
|
|
|
describe '#execute' do
|
2019-11-15 10:06:12 -05:00
|
|
|
let(:service) { described_class.new(project, user, merge_params) }
|
|
|
|
let(:merge_params) do
|
|
|
|
{ commit_message: 'Awesome message', sha: merge_request.diff_head_sha }
|
|
|
|
end
|
2015-01-17 19:34:34 -05:00
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'valid params' do
|
2015-01-17 19:34:34 -05:00
|
|
|
before do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(service).to receive(:execute_hooks)
|
2015-01-17 19:34:34 -05:00
|
|
|
|
2015-11-30 11:03:07 -05:00
|
|
|
perform_enqueued_jobs do
|
2015-12-07 04:06:07 -05:00
|
|
|
service.execute(merge_request)
|
2015-11-30 11:03:07 -05:00
|
|
|
end
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
it { expect(merge_request).to be_valid }
|
|
|
|
it { expect(merge_request).to be_merged }
|
2015-01-17 19:34:34 -05:00
|
|
|
|
2020-02-10 07:08:59 -05:00
|
|
|
it 'persists merge_commit_sha and nullifies in_progress_merge_commit_sha' do
|
|
|
|
expect(merge_request.merge_commit_sha).not_to be_nil
|
|
|
|
expect(merge_request.in_progress_merge_commit_sha).to be_nil
|
|
|
|
end
|
|
|
|
|
2016-08-01 11:00:44 -04:00
|
|
|
it 'sends email to user2 about merge of new merge_request' do
|
2015-01-17 19:34:34 -05:00
|
|
|
email = ActionMailer::Base.deliveries.last
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(email.to.first).to eq(user2.email)
|
|
|
|
expect(email.subject).to include(merge_request.title)
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
|
|
|
|
2016-08-01 11:00:44 -04:00
|
|
|
it 'creates system note about merge_request merge' do
|
2015-01-17 19:34:34 -05:00
|
|
|
note = merge_request.notes.last
|
2016-11-23 01:55:23 -05:00
|
|
|
expect(note.note).to include 'merged'
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
2019-11-15 10:06:12 -05:00
|
|
|
|
|
|
|
context 'when squashing' do
|
|
|
|
let(:merge_params) do
|
|
|
|
{ commit_message: 'Merge commit message',
|
|
|
|
squash_commit_message: 'Squash commit message',
|
|
|
|
sha: merge_request.diff_head_sha }
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:merge_request) do
|
|
|
|
# A merge reqeust with 5 commits
|
|
|
|
create(:merge_request, :simple,
|
|
|
|
author: user2,
|
|
|
|
assignees: [user2],
|
|
|
|
squash: true,
|
|
|
|
source_branch: 'improve/awesome',
|
|
|
|
target_branch: 'fix')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'merges the merge request with squashed commits' do
|
|
|
|
expect(merge_request).to be_merged
|
|
|
|
|
|
|
|
merge_commit = merge_request.merge_commit
|
|
|
|
squash_commit = merge_request.merge_commit.parents.last
|
|
|
|
|
|
|
|
expect(merge_commit.message).to eq('Merge commit message')
|
|
|
|
expect(squash_commit.message).to eq("Squash commit message\n")
|
|
|
|
end
|
|
|
|
end
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
2015-10-01 02:31:48 -04:00
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'when an invalid sha is passed' do
|
|
|
|
let(:merge_request) do
|
|
|
|
create(:merge_request, :simple,
|
|
|
|
author: user2,
|
|
|
|
assignees: [user2],
|
|
|
|
squash: true,
|
|
|
|
source_branch: 'improve/awesome',
|
|
|
|
target_branch: 'fix')
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:merge_params) do
|
|
|
|
{ sha: merge_request.commits.second.sha }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not merge the MR' do
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(merge_request).not_to be_merged
|
|
|
|
expect(merge_request.merge_error).to match(/Branch has been updated/)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the `sha` param is missing' do
|
|
|
|
let(:merge_params) { {} }
|
|
|
|
|
|
|
|
it 'returns the error' do
|
|
|
|
merge_error = 'Branch has been updated since the merge was requested. '\
|
|
|
|
'Please review the changes.'
|
|
|
|
|
|
|
|
expect { service.execute(merge_request) }
|
|
|
|
.to change { merge_request.merge_error }
|
|
|
|
.from(nil).to(merge_error)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'closes related issues' do
|
2016-09-30 10:53:44 -04:00
|
|
|
before do
|
|
|
|
allow(project).to receive(:default_branch).and_return(merge_request.target_branch)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'closes GitLab issue tracker issues' do
|
|
|
|
issue = create :issue, project: project
|
2020-05-19 02:08:03 -04:00
|
|
|
commit = instance_double('commit', safe_message: "Fixes #{issue.to_reference}", date: Time.current, authored_date: Time.current)
|
2016-09-30 10:53:44 -04:00
|
|
|
allow(merge_request).to receive(:commits).and_return([commit])
|
2018-07-30 14:52:42 -04:00
|
|
|
merge_request.cache_merge_request_closes_issues!
|
2016-09-30 10:53:44 -04:00
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(issue.reload.closed?).to be_truthy
|
|
|
|
end
|
|
|
|
|
2019-06-28 09:25:56 -04:00
|
|
|
context 'with Jira integration' do
|
2016-09-30 10:53:44 -04:00
|
|
|
include JiraServiceHelper
|
|
|
|
|
|
|
|
let(:jira_tracker) { project.create_jira_service }
|
2016-11-14 16:30:01 -05:00
|
|
|
let(:jira_issue) { ExternalIssue.new('JIRA-123', project) }
|
|
|
|
let(:commit) { double('commit', safe_message: "Fixes #{jira_issue.to_reference}") }
|
2016-09-30 10:53:44 -04:00
|
|
|
|
2016-10-06 17:17:11 -04:00
|
|
|
before do
|
2018-07-02 06:43:06 -04:00
|
|
|
project.update!(has_external_issue_tracker: true)
|
2016-10-06 17:17:11 -04:00
|
|
|
jira_service_settings
|
2016-11-14 16:30:01 -05:00
|
|
|
stub_jira_urls(jira_issue.id)
|
|
|
|
allow(merge_request).to receive(:commits).and_return([commit])
|
2016-10-06 17:17:11 -04:00
|
|
|
end
|
2016-09-30 10:53:44 -04:00
|
|
|
|
2019-06-28 09:25:56 -04:00
|
|
|
it 'closes issues on Jira issue tracker' do
|
2016-09-30 10:53:44 -04:00
|
|
|
jira_issue = ExternalIssue.new('JIRA-123', project)
|
2016-11-09 16:55:21 -05:00
|
|
|
stub_jira_urls(jira_issue)
|
2016-09-30 10:53:44 -04:00
|
|
|
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
|
|
|
|
allow(merge_request).to receive(:commits).and_return([commit])
|
|
|
|
|
2016-12-01 03:45:06 -05:00
|
|
|
expect_any_instance_of(JiraService).to receive(:close_issue).with(merge_request, jira_issue).once
|
2016-09-30 10:53:44 -04:00
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
2016-10-06 18:05:27 -04:00
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'when jira_issue_transition_id is not present' do
|
2017-06-14 14:18:56 -04:00
|
|
|
before do
|
|
|
|
allow_any_instance_of(JIRA::Resource::Issue).to receive(:resolution).and_return(nil)
|
|
|
|
end
|
2016-11-14 16:30:01 -05:00
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
it 'does not close issue' do
|
2020-03-13 02:09:37 -04:00
|
|
|
jira_tracker.update(jira_issue_transition_id: nil)
|
2016-11-14 16:30:01 -05:00
|
|
|
|
|
|
|
expect_any_instance_of(JiraService).not_to receive(:transition_issue)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'wrong issue markdown' do
|
2019-06-28 09:25:56 -04:00
|
|
|
it 'does not close issues on Jira issue tracker' do
|
2016-11-09 16:55:21 -05:00
|
|
|
jira_issue = ExternalIssue.new('#JIRA-123', project)
|
|
|
|
stub_jira_urls(jira_issue)
|
2016-10-06 18:05:27 -04:00
|
|
|
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
|
|
|
|
allow(merge_request).to receive(:commits).and_return([commit])
|
|
|
|
|
|
|
|
expect_any_instance_of(JiraService).not_to receive(:close_issue)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
|
|
|
end
|
2016-09-30 10:53:44 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-22 17:30:37 -04:00
|
|
|
context 'closes related todos' do
|
2019-04-07 14:35:16 -04:00
|
|
|
let(:merge_request) { create(:merge_request, assignees: [user], author: user) }
|
2016-09-22 17:30:37 -04:00
|
|
|
let(:project) { merge_request.project }
|
2019-11-15 10:06:12 -05:00
|
|
|
|
2016-09-22 17:30:37 -04:00
|
|
|
let!(:todo) do
|
|
|
|
create(:todo, :assigned,
|
|
|
|
project: project,
|
|
|
|
author: user,
|
|
|
|
user: user,
|
|
|
|
target: merge_request)
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(service).to receive(:execute_hooks)
|
|
|
|
|
|
|
|
perform_enqueued_jobs do
|
|
|
|
service.execute(merge_request)
|
|
|
|
todo.reload
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(todo).to be_done }
|
|
|
|
end
|
|
|
|
|
2017-06-29 17:48:56 -04:00
|
|
|
context 'source branch removal' do
|
|
|
|
context 'when the source branch is protected' do
|
|
|
|
let(:service) do
|
2019-11-15 10:06:12 -05:00
|
|
|
described_class.new(project, user, merge_params.merge('should_remove_source_branch' => true))
|
2017-06-29 17:48:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
create(:protected_branch, project: project, name: merge_request.source_branch)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not delete the source branch' do
|
2019-12-03 13:06:49 -05:00
|
|
|
expect(::Branches::DeleteService).not_to receive(:new)
|
|
|
|
|
2017-06-29 17:48:56 -04:00
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
2016-02-12 15:41:31 -05:00
|
|
|
end
|
|
|
|
|
2017-06-29 17:48:56 -04:00
|
|
|
context 'when the source branch is the default branch' do
|
|
|
|
let(:service) do
|
2019-11-15 10:06:12 -05:00
|
|
|
described_class.new(project, user, merge_params.merge('should_remove_source_branch' => true))
|
2017-06-29 17:48:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(project).to receive(:root_ref?).with(merge_request.source_branch).and_return(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not delete the source branch' do
|
2019-12-03 13:06:49 -05:00
|
|
|
expect(::Branches::DeleteService).not_to receive(:new)
|
2017-06-29 17:48:56 -04:00
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the source branch can be removed' do
|
|
|
|
context 'when MR author set the source branch to be removed' do
|
2017-10-11 16:06:15 -04:00
|
|
|
before do
|
|
|
|
merge_request.update_attribute(:merge_params, { 'force_remove_source_branch' => '1' })
|
2017-06-29 17:48:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'removes the source branch using the author user' do
|
2019-12-03 13:06:49 -05:00
|
|
|
expect(::Branches::DeleteService).to receive(:new)
|
2017-06-29 17:48:56 -04:00
|
|
|
.with(merge_request.source_project, merge_request.author)
|
|
|
|
.and_call_original
|
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
2017-10-11 16:06:15 -04:00
|
|
|
|
|
|
|
context 'when the merger set the source branch not to be removed' do
|
2019-11-15 10:06:12 -05:00
|
|
|
let(:service) { described_class.new(project, user, merge_params.merge('should_remove_source_branch' => false)) }
|
2017-10-11 16:06:15 -04:00
|
|
|
|
|
|
|
it 'does not delete the source branch' do
|
2019-12-03 13:06:49 -05:00
|
|
|
expect(::Branches::DeleteService).not_to receive(:new)
|
2017-10-11 16:06:15 -04:00
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
|
|
|
end
|
2017-06-29 17:48:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when MR merger set the source branch to be removed' do
|
|
|
|
let(:service) do
|
2019-11-15 10:06:12 -05:00
|
|
|
described_class.new(project, user, merge_params.merge('should_remove_source_branch' => true))
|
2017-06-29 17:48:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'removes the source branch using the current user' do
|
2019-12-03 13:06:49 -05:00
|
|
|
expect(::Branches::DeleteService).to receive(:new)
|
2017-06-29 17:48:56 -04:00
|
|
|
.with(merge_request.source_project, user)
|
|
|
|
.and_call_original
|
|
|
|
service.execute(merge_request)
|
|
|
|
end
|
|
|
|
end
|
2016-02-12 15:41:31 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'error handling' do
|
2017-02-14 09:13:35 -05:00
|
|
|
before do
|
2020-05-21 17:08:31 -04:00
|
|
|
allow(Gitlab::AppLogger).to receive(:error)
|
2017-02-14 09:13:35 -05:00
|
|
|
end
|
2015-10-01 02:31:48 -04:00
|
|
|
|
2019-07-05 15:31:10 -04:00
|
|
|
context 'when source is missing' do
|
|
|
|
it 'logs and saves error' do
|
|
|
|
allow(merge_request).to receive(:diff_head_sha) { nil }
|
|
|
|
|
|
|
|
error_message = 'No source for merge'
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(merge_request.merge_error).to eq(error_message)
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2019-07-05 15:31:10 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-02-14 09:13:35 -05:00
|
|
|
it 'logs and saves error if there is an exception' do
|
|
|
|
error_message = 'error message'
|
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
allow(service).to receive(:repository).and_raise('error message')
|
2015-10-01 02:31:48 -04:00
|
|
|
allow(service).to receive(:execute_hooks)
|
|
|
|
|
2015-11-24 08:59:02 -05:00
|
|
|
service.execute(merge_request)
|
2015-10-01 02:31:48 -04:00
|
|
|
|
2018-04-29 11:30:49 -04:00
|
|
|
expect(merge_request.merge_error).to include('Something went wrong during merge')
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2015-10-01 02:31:48 -04:00
|
|
|
end
|
2016-07-04 13:04:29 -04:00
|
|
|
|
2019-02-11 10:14:11 -05:00
|
|
|
it 'logs and saves error if user is not authorized' do
|
|
|
|
unauthorized_user = create(:user)
|
|
|
|
project.add_reporter(unauthorized_user)
|
|
|
|
|
|
|
|
service = described_class.new(project, unauthorized_user)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(merge_request.merge_error)
|
|
|
|
.to eq('You are not allowed to merge this merge request')
|
|
|
|
end
|
|
|
|
|
2017-02-14 09:13:35 -05:00
|
|
|
it 'logs and saves error if there is an PreReceiveError exception' do
|
|
|
|
error_message = 'error message'
|
2016-07-04 13:04:29 -04:00
|
|
|
|
2019-03-20 00:08:51 -04:00
|
|
|
allow(service).to receive(:repository).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
|
2016-07-04 13:04:29 -04:00
|
|
|
allow(service).to receive(:execute_hooks)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
2019-03-07 16:11:28 -05:00
|
|
|
expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2016-07-04 13:04:29 -04:00
|
|
|
end
|
2016-07-29 14:14:53 -04:00
|
|
|
|
2017-02-14 09:13:35 -05:00
|
|
|
it 'logs and saves error if there is a merge conflict' do
|
|
|
|
error_message = 'Conflicts detected during merge'
|
|
|
|
|
2016-07-29 14:14:53 -04:00
|
|
|
allow_any_instance_of(Repository).to receive(:merge).and_return(false)
|
|
|
|
allow(service).to receive(:execute_hooks)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
2017-02-14 09:13:35 -05:00
|
|
|
expect(merge_request).to be_open
|
2016-07-29 14:14:53 -04:00
|
|
|
expect(merge_request.merge_commit_sha).to be_nil
|
2017-02-14 09:13:35 -05:00
|
|
|
expect(merge_request.merge_error).to include(error_message)
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2016-07-29 14:14:53 -04:00
|
|
|
end
|
2017-11-09 11:55:45 -05:00
|
|
|
|
2018-05-29 05:51:43 -04:00
|
|
|
context 'when squashing' do
|
2017-11-09 11:55:45 -05:00
|
|
|
before do
|
2018-05-29 05:51:43 -04:00
|
|
|
merge_request.update!(source_branch: 'master', target_branch: 'feature')
|
2017-11-09 11:55:45 -05:00
|
|
|
end
|
|
|
|
|
2018-05-29 05:51:43 -04:00
|
|
|
it 'logs and saves error if there is an error when squashing' do
|
|
|
|
error_message = 'Failed to squash. Should be done manually'
|
2017-11-09 11:55:45 -05:00
|
|
|
|
2019-02-06 07:33:11 -05:00
|
|
|
allow_any_instance_of(MergeRequests::SquashService).to receive(:squash!).and_return(nil)
|
2018-05-29 05:51:43 -04:00
|
|
|
merge_request.update(squash: true)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(merge_request).to be_open
|
|
|
|
expect(merge_request.merge_commit_sha).to be_nil
|
|
|
|
expect(merge_request.merge_error).to include(error_message)
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2018-05-29 05:51:43 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'logs and saves error if there is a squash in progress' do
|
|
|
|
error_message = 'another squash is already in progress'
|
|
|
|
|
|
|
|
allow_any_instance_of(MergeRequest).to receive(:squash_in_progress?).and_return(true)
|
|
|
|
merge_request.update(squash: true)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
2017-11-09 11:55:45 -05:00
|
|
|
|
2018-05-29 05:51:43 -04:00
|
|
|
expect(merge_request).to be_open
|
|
|
|
expect(merge_request.merge_commit_sha).to be_nil
|
|
|
|
expect(merge_request.merge_error).to include(error_message)
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2018-05-29 05:51:43 -04:00
|
|
|
end
|
|
|
|
|
2019-11-15 10:06:12 -05:00
|
|
|
context 'when fast-forward merge is not allowed' do
|
2018-05-29 05:51:43 -04:00
|
|
|
before do
|
|
|
|
allow_any_instance_of(Repository).to receive(:ancestor?).and_return(nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
%w(semi-linear ff).each do |merge_method|
|
|
|
|
it "logs and saves error if merge is #{merge_method} only" do
|
|
|
|
merge_method = 'rebase_merge' if merge_method == 'semi-linear'
|
|
|
|
merge_request.project.update(merge_method: merge_method)
|
|
|
|
error_message = 'Only fast-forward merge is allowed for your project. Please update your source branch'
|
|
|
|
allow(service).to receive(:execute_hooks)
|
|
|
|
|
|
|
|
service.execute(merge_request)
|
|
|
|
|
|
|
|
expect(merge_request).to be_open
|
|
|
|
expect(merge_request.merge_commit_sha).to be_nil
|
|
|
|
expect(merge_request.merge_error).to include(error_message)
|
2020-05-21 17:08:31 -04:00
|
|
|
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
|
2018-05-29 05:51:43 -04:00
|
|
|
end
|
2017-11-09 11:55:45 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2015-10-01 02:31:48 -04:00
|
|
|
end
|
2015-01-17 19:34:34 -05:00
|
|
|
end
|
|
|
|
end
|