debian-mirror-gitlab/spec/services/merge_requests/rebase_service_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

233 lines
7.6 KiB
Ruby
Raw Normal View History

2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2018-03-17 18:26:18 +05:30
require 'spec_helper'
2023-04-23 21:23:45 +05:30
RSpec.describe MergeRequests::RebaseService, feature_category: :source_code_management do
2018-03-17 18:26:18 +05:30
include ProjectForksHelper
let(:user) { create(:user) }
2019-09-30 21:07:59 +05:30
let(:rebase_jid) { 'fake-rebase-jid' }
2018-03-17 18:26:18 +05:30
let(:merge_request) do
2019-09-30 21:07:59 +05:30
create :merge_request,
2018-03-17 18:26:18 +05:30
source_branch: 'feature_conflict',
2019-09-30 21:07:59 +05:30
target_branch: 'master',
rebase_jid: rebase_jid
2018-03-17 18:26:18 +05:30
end
2020-10-24 23:57:45 +05:30
2018-03-17 18:26:18 +05:30
let(:project) { merge_request.project }
let(:repository) { project.repository.raw }
2020-03-13 15:44:24 +05:30
let(:skip_ci) { false }
2018-03-17 18:26:18 +05:30
2021-06-08 01:23:25 +05:30
subject(:service) { described_class.new(project: project, current_user: user) }
2018-03-17 18:26:18 +05:30
before do
2018-11-18 11:00:15 +05:30
project.add_maintainer(user)
2018-03-17 18:26:18 +05:30
end
2023-03-17 16:20:25 +05:30
describe '#validate' do
subject { service.validate(merge_request) }
it { is_expected.to be_success }
context 'when source branch does not exist' do
before do
merge_request.update!(source_branch: 'does_not_exist')
end
it 'returns an error' do
is_expected.to be_error
expect(subject.message).to eq('Source branch does not exist')
end
end
context 'when user has no permissions to rebase' do
before do
project.add_guest(user)
end
it 'returns an error' do
is_expected.to be_error
expect(subject.message).to eq('Cannot push to source branch')
end
end
context 'when branch is protected' do
before do
create(:protected_branch, project: project, name: merge_request.source_branch, allow_force_push: false)
end
it 'returns an error' do
is_expected.to be_error
expect(subject.message).to eq('Source branch is protected from force push')
end
end
end
2018-03-17 18:26:18 +05:30
describe '#execute' do
2019-09-04 21:01:54 +05:30
shared_examples 'sequence of failure and success' do
it 'properly clears the error message' do
allow(repository).to receive(:gitaly_operation_client).and_raise('Something went wrong')
service.execute(merge_request)
2019-09-30 21:07:59 +05:30
merge_request.reload
2019-09-04 21:01:54 +05:30
2019-09-30 21:07:59 +05:30
expect(merge_request.reload.merge_error).to eq(described_class::REBASE_ERROR)
expect(merge_request.rebase_jid).to eq(nil)
2019-09-04 21:01:54 +05:30
allow(repository).to receive(:gitaly_operation_client).and_call_original
2019-09-30 21:07:59 +05:30
merge_request.update!(rebase_jid: rebase_jid)
2019-09-04 21:01:54 +05:30
service.execute(merge_request)
2019-09-30 21:07:59 +05:30
merge_request.reload
2019-09-04 21:01:54 +05:30
2019-09-30 21:07:59 +05:30
expect(merge_request.merge_error).to eq(nil)
expect(merge_request.rebase_jid).to eq(nil)
2019-09-04 21:01:54 +05:30
end
end
it_behaves_like 'sequence of failure and success'
2018-11-08 19:23:39 +05:30
context 'when unexpected error occurs' do
2020-05-24 23:13:21 +05:30
let(:exception) { RuntimeError.new('Something went wrong') }
let(:merge_request_ref) { merge_request.to_reference(full: true) }
2018-03-17 18:26:18 +05:30
before do
2020-05-24 23:13:21 +05:30
allow(repository).to receive(:gitaly_operation_client).and_raise(exception)
2018-03-17 18:26:18 +05:30
end
it 'saves a generic error message' do
2020-05-24 23:13:21 +05:30
service.execute(merge_request)
2018-03-17 18:26:18 +05:30
2019-09-30 21:07:59 +05:30
expect(merge_request.reload.merge_error).to eq(described_class::REBASE_ERROR)
2018-03-17 18:26:18 +05:30
end
it 'returns an error' do
expect(service.execute(merge_request)).to match(status: :error,
message: described_class::REBASE_ERROR)
end
2020-05-24 23:13:21 +05:30
it 'logs the error' do
expect(service).to receive(:log_error).with(exception: exception, message: described_class::REBASE_ERROR, save_message_on_model: true).and_call_original
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception,
2022-07-16 23:28:13 +05:30
{
class: described_class.to_s,
merge_request: merge_request_ref,
merge_request_id: merge_request.id,
message: described_class::REBASE_ERROR,
save_message_on_model: true
}).and_call_original
2020-05-24 23:13:21 +05:30
service.execute(merge_request)
end
2018-03-17 18:26:18 +05:30
end
2022-01-26 12:08:38 +05:30
context 'with a pre-receive failure' do
let(:pre_receive_error) { "Commit message does not follow the pattern 'ACME'" }
2022-04-04 11:22:00 +05:30
let(:merge_error) { "The rebase pre-receive hook failed: #{pre_receive_error}." }
2022-01-26 12:08:38 +05:30
before do
allow(repository).to receive(:gitaly_operation_client).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{pre_receive_error}")
end
it 'saves a specific message' do
subject.execute(merge_request)
expect(merge_request.reload.merge_error).to eq merge_error
end
it 'returns an error' do
expect(service.execute(merge_request)).to match(
status: :error,
message: merge_error)
end
end
2018-11-08 19:23:39 +05:30
context 'with git command failure' do
2018-03-17 18:26:18 +05:30
before do
2018-11-08 19:23:39 +05:30
allow(repository).to receive(:gitaly_operation_client).and_raise(Gitlab::Git::Repository::GitError, 'Something went wrong')
2018-03-17 18:26:18 +05:30
end
it 'saves a generic error message' do
subject.execute(merge_request)
expect(merge_request.reload.merge_error).to eq described_class::REBASE_ERROR
end
it 'returns an error' do
expect(service.execute(merge_request)).to match(status: :error,
message: described_class::REBASE_ERROR)
end
end
context 'valid params' do
2019-07-31 22:56:46 +05:30
shared_examples_for 'a service that can execute a successful rebase' do
2018-03-17 18:26:18 +05:30
before do
2020-03-13 15:44:24 +05:30
service.execute(merge_request, skip_ci: skip_ci)
2018-03-17 18:26:18 +05:30
end
it 'rebases source branch' do
parent_sha = merge_request.source_project.repository.commit(merge_request.source_branch).parents.first.sha
target_branch_sha = merge_request.target_project.repository.commit(merge_request.target_branch).sha
expect(parent_sha).to eq(target_branch_sha)
end
it 'records the new SHA on the merge request' do
head_sha = merge_request.source_project.repository.commit(merge_request.source_branch).sha
expect(merge_request.reload.rebase_commit_sha).to eq(head_sha)
end
2018-12-05 23:21:45 +05:30
it 'logs correct author and committer' do
2018-03-17 18:26:18 +05:30
head_commit = merge_request.source_project.repository.commit(merge_request.source_branch)
expect(head_commit.author_email).to eq('dmitriy.zaporozhets@gmail.com')
expect(head_commit.author_name).to eq('Dmitriy Zaporozhets')
expect(head_commit.committer_email).to eq(user.email)
expect(head_commit.committer_name).to eq(user.name)
end
end
2020-03-13 15:44:24 +05:30
it_behaves_like 'a service that can execute a successful rebase'
2019-07-31 22:56:46 +05:30
2021-09-30 23:02:18 +05:30
it 'clears rebase_jid' do
expect { service.execute(merge_request) }
.to change(merge_request, :rebase_jid)
.from(rebase_jid)
.to(nil)
end
2020-03-13 15:44:24 +05:30
context 'when skip_ci flag is set' do
let(:skip_ci) { true }
2019-07-31 22:56:46 +05:30
it_behaves_like 'a service that can execute a successful rebase'
end
2018-03-17 18:26:18 +05:30
context 'fork' do
2018-11-08 19:23:39 +05:30
describe 'successful fork rebase' do
2018-03-17 18:26:18 +05:30
let(:forked_project) do
fork_project(project, user, repository: true)
end
let(:merge_request_from_fork) do
forked_project.repository.create_file(
user,
'new-file-to-target',
'',
message: 'Add new file to target',
branch_name: 'master')
create(:merge_request,
source_branch: 'master', source_project: forked_project,
target_branch: 'master', target_project: project)
end
2019-12-26 22:10:19 +05:30
it 'rebases source branch', :sidekiq_might_not_need_inline do
2018-03-17 18:26:18 +05:30
parent_sha = forked_project.repository.commit(merge_request_from_fork.source_branch).parents.first.sha
target_branch_sha = project.repository.commit(merge_request_from_fork.target_branch).sha
expect(parent_sha).to eq(target_branch_sha)
end
end
end
end
end
end