debian-mirror-gitlab/spec/services/merge_requests/after_create_service_spec.rb
2023-07-09 08:55:56 +05:30

235 lines
7.8 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe MergeRequests::AfterCreateService, feature_category: :code_review_workflow do
let_it_be(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
subject(:after_create_service) do
described_class.new(project: merge_request.target_project, current_user: merge_request.author)
end
describe '#execute' do
let(:event_service) { instance_double('EventCreateService', open_mr: true) }
let(:notification_service) { instance_double('NotificationService', new_merge_request: true) }
before do
allow(after_create_service).to receive(:event_service).and_return(event_service)
allow(after_create_service).to receive(:notification_service).and_return(notification_service)
end
subject(:execute_service) { after_create_service.execute(merge_request) }
it 'creates a merge request open event' do
expect(event_service)
.to receive(:open_mr).with(merge_request, merge_request.author)
execute_service
end
it 'calls the merge request activity counter' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_create_mr_action)
.with(user: merge_request.author, merge_request: merge_request)
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_mr_including_ci_config)
.with(user: merge_request.author, merge_request: merge_request)
execute_service
end
it 'creates a new merge request notification' do
expect(notification_service)
.to receive(:new_merge_request).with(merge_request, merge_request.author)
execute_service
end
it 'writes diffs to the cache' do
expect(merge_request)
.to receive_message_chain(:diffs, :write_cache)
execute_service
end
it 'creates cross references' do
expect(merge_request)
.to receive(:create_cross_references!).with(merge_request.author)
execute_service
end
it 'creates a pipeline and updates the HEAD pipeline' do
expect(after_create_service)
.to receive(:create_pipeline_for).with(merge_request, merge_request.author)
expect(merge_request).to receive(:update_head_pipeline)
execute_service
end
it 'executes hooks with default action' do
expect(project).to receive(:execute_hooks)
execute_service
end
it_behaves_like 'records an onboarding progress action', :merge_request_created do
let(:namespace) { merge_request.target_project.namespace }
end
context 'when merge request is in unchecked state' do
before do
merge_request.mark_as_unchecked!
execute_service
end
it 'does not change its state' do
expect(merge_request.reload).to be_unchecked
end
end
context 'when merge request is in preparing state' do
before do
merge_request.mark_as_unchecked! unless merge_request.unchecked?
merge_request.mark_as_preparing!
end
it 'checks for mergeability' do
expect(merge_request).to receive(:check_mergeability).with(async: true)
execute_service
end
context 'when preparing for mergeability fails' do
before do
# This is only one of the possible cases that can fail. This is to
# simulate a failure that happens during the service call.
allow(merge_request)
.to receive(:update_head_pipeline)
.and_raise(StandardError)
end
it 'does not mark the merge request as unchecked' do
expect { execute_service }.to raise_error(StandardError)
expect(merge_request.reload).to be_preparing
end
end
context 'when preparing merge request fails' do
before do
# This is only one of the possible cases that can fail. This is to
# simulate a failure that happens during the service call.
allow(merge_request)
.to receive_message_chain(:diffs, :write_cache)
.and_raise(StandardError)
end
it 'still checks for mergeability' do
expect(merge_request).to receive(:check_mergeability).with(async: true)
expect { execute_service }.to raise_error(StandardError)
end
end
end
it 'updates the prepared_at' do
# Need to reset the `prepared_at` since it can be already set in preceding tests.
merge_request.update!(prepared_at: nil)
freeze_time do
expect { execute_service }.to change { merge_request.prepared_at }
.from(nil)
.to(Time.current)
end
end
it 'increments the usage data counter of create event' do
counter = Gitlab::UsageDataCounters::MergeRequestCounter
expect { execute_service }.to change { counter.read(:create) }.by(1)
end
context 'todos' do
it 'does not creates todos' do
attributes = {
project: merge_request.target_project,
target_id: merge_request.id,
target_type: merge_request.class.name
}
expect { execute_service }.not_to change { Todo.where(attributes).count }
end
context 'when merge request is assigned to someone' do
let_it_be(:assignee) { create(:user) }
let_it_be(:merge_request) { create(:merge_request, assignees: [assignee]) }
it 'creates a todo for new assignee' do
attributes = {
project: merge_request.target_project,
author: merge_request.author,
user: assignee,
target_id: merge_request.id,
target_type: merge_request.class.name,
action: Todo::ASSIGNED,
state: :pending
}
expect { execute_service }.to change { Todo.where(attributes).count }.by(1)
end
end
context 'when reviewer is assigned' do
let_it_be(:reviewer) { create(:user) }
let_it_be(:merge_request) { create(:merge_request, reviewers: [reviewer]) }
it 'creates a todo for new reviewer' do
attributes = {
project: merge_request.target_project,
author: merge_request.author,
user: reviewer,
target_id: merge_request.id,
target_type: merge_request.class.name,
action: Todo::REVIEW_REQUESTED,
state: :pending
}
expect { execute_service }.to change { Todo.where(attributes).count }.by(1)
end
end
end
context 'when saving references to issues that the created merge request closes' do
let_it_be(:first_issue) { create(:issue, project: merge_request.target_project) }
let_it_be(:second_issue) { create(:issue, project: merge_request.target_project) }
it 'creates a `MergeRequestsClosingIssues` record for each issue' do
merge_request.description = "Closes #{first_issue.to_reference} and #{second_issue.to_reference}"
merge_request.source_branch = "feature"
merge_request.target_branch = merge_request.target_project.default_branch
merge_request.save!
execute_service
issue_ids = MergeRequestsClosingIssues.where(merge_request: merge_request).pluck(:issue_id)
expect(issue_ids).to match_array([first_issue.id, second_issue.id])
end
end
it 'tracks merge request creation in usage data' do
expect(Gitlab::UsageDataCounters::MergeRequestCounter).to receive(:count).with(:create)
execute_service
end
it 'calls MergeRequests::LinkLfsObjectsService#execute' do
service = instance_spy(MergeRequests::LinkLfsObjectsService)
allow(MergeRequests::LinkLfsObjectsService).to receive(:new).with(project: merge_request.target_project).and_return(service)
execute_service
expect(service).to have_received(:execute).with(merge_request)
end
end
end