Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/merge_request_spec.rb')
-rw-r--r--spec/models/merge_request_spec.rb273
1 files changed, 253 insertions, 20 deletions
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index ebe2cd2ac03..8c7289adbcc 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe MergeRequest, factory_default: :keep do
using RSpec::Parameterized::TableSyntax
- let_it_be(:namespace) { create_default(:namespace) }
- let_it_be(:project, refind: true) { create_default(:project, :repository) }
+ let_it_be(:namespace) { create_default(:namespace).freeze }
+ let_it_be(:project, refind: true) { create_default(:project, :repository).freeze }
subject { create(:merge_request) }
@@ -1366,6 +1366,10 @@ RSpec.describe MergeRequest, factory_default: :keep do
it "doesn't detect WIP by default" do
expect(subject.work_in_progress?).to eq false
end
+
+ it "is aliased to #draft?" do
+ expect(subject.method(:work_in_progress?)).to eq(subject.method(:draft?))
+ end
end
describe "#wipless_title" do
@@ -2895,6 +2899,14 @@ RSpec.describe MergeRequest, factory_default: :keep do
expect(subject.mergeable?).to be_truthy
end
+ it 'return true if #mergeable_state? is true and the MR #can_be_merged? is false' do
+ allow(subject).to receive(:mergeable_state?) { true }
+ expect(subject).to receive(:check_mergeability)
+ expect(subject).to receive(:can_be_merged?) { false }
+
+ expect(subject.mergeable?).to be_falsey
+ end
+
context 'with skip_ci_check option' do
before do
allow(subject).to receive_messages(check_mergeability: nil,
@@ -3072,6 +3084,7 @@ RSpec.describe MergeRequest, factory_default: :keep do
where(:status, :public_status) do
'cannot_be_merged_rechecking' | 'checking'
+ 'preparing' | 'checking'
'checking' | 'checking'
'cannot_be_merged' | 'cannot_be_merged'
end
@@ -3082,32 +3095,83 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
describe "#head_pipeline_active? " do
- it do
- is_expected
- .to delegate_method(:active?)
- .to(:head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks a head_pipeline relation' do
+ before do
+ subject.head_pipeline = nil
+ end
+
+ it 'returns false' do
+ expect(subject.head_pipeline_active?).to be false
+ end
+ end
+
+ context 'when project has a head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the head_pipeline' do
+ expect(subject.head_pipeline)
+ .to receive(:active?)
+
+ subject.head_pipeline_active?
+ end
end
end
describe "#actual_head_pipeline_success? " do
- it do
- is_expected
- .to delegate_method(:success?)
- .to(:actual_head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks an actual_head_pipeline relation' do
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { nil }
+ end
+
+ it 'returns false' do
+ expect(subject.actual_head_pipeline_success?).to be false
+ end
+ end
+
+ context 'when project has a actual_head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the actual_head_pipeline' do
+ expect(subject.actual_head_pipeline)
+ .to receive(:success?)
+
+ subject.actual_head_pipeline_success?
+ end
end
end
describe "#actual_head_pipeline_active? " do
- it do
- is_expected
- .to delegate_method(:active?)
- .to(:actual_head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks an actual_head_pipeline relation' do
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { nil }
+ end
+
+ it 'returns false' do
+ expect(subject.actual_head_pipeline_active?).to be false
+ end
+ end
+
+ context 'when project has a actual_head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the actual_head_pipeline' do
+ expect(subject.actual_head_pipeline)
+ .to receive(:active?)
+
+ subject.actual_head_pipeline_active?
+ end
end
end
@@ -3784,6 +3848,87 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
+ describe '#use_merge_base_pipeline_for_comparison?' do
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, :with_codequality_reports, source_project: project) }
+
+ subject { merge_request.use_merge_base_pipeline_for_comparison?(service_class) }
+
+ context 'when service class is Ci::CompareCodequalityReportsService' do
+ let(:service_class) { 'Ci::CompareCodequalityReportsService' }
+
+ context 'when feature flag is enabled' do
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(codequality_backend_comparison: false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'when service class is different' do
+ let(:service_class) { 'Ci::GenerateCoverageReportsService' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#comparison_base_pipeline' do
+ subject(:pipeline) { merge_request.comparison_base_pipeline(service_class) }
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, :with_codequality_reports, source_project: project) }
+ let!(:base_pipeline) do
+ create(:ci_pipeline,
+ :with_test_reports,
+ project: project,
+ ref: merge_request.target_branch,
+ sha: merge_request.diff_base_sha
+ )
+ end
+
+ context 'when service class is Ci::CompareCodequalityReportsService' do
+ let(:service_class) { 'Ci::CompareCodequalityReportsService' }
+
+ context 'when merge request has a merge request pipeline' do
+ let(:merge_request) do
+ create(:merge_request, :with_merge_request_pipeline)
+ end
+
+ let(:merge_base_pipeline) do
+ create(:ci_pipeline, ref: merge_request.target_branch, sha: merge_request.target_branch_sha)
+ end
+
+ before do
+ merge_base_pipeline
+ merge_request.update_head_pipeline
+ end
+
+ it 'returns the merge_base_pipeline' do
+ expect(pipeline).to eq(merge_base_pipeline)
+ end
+ end
+
+ context 'when merge does not have a merge request pipeline' do
+ it 'returns the base_pipeline' do
+ expect(pipeline).to eq(base_pipeline)
+ end
+ end
+ end
+
+ context 'when service_class is different' do
+ let(:service_class) { 'Ci::GenerateCoverageReportsService' }
+
+ it 'returns the base_pipeline' do
+ expect(pipeline).to eq(base_pipeline)
+ end
+ end
+ end
+
describe '#base_pipeline' do
let(:pipeline_arguments) do
{
@@ -3963,6 +4108,65 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
+ describe '#mark_as_unchecked' do
+ subject { create(:merge_request, source_project: project, merge_status: merge_status) }
+
+ shared_examples 'for an invalid state transition' do
+ it 'is not a valid state transition' do
+ expect { subject.mark_as_unchecked! }.to raise_error(StateMachines::InvalidTransition)
+ end
+ end
+
+ shared_examples 'for an valid state transition' do
+ it 'is a valid state transition' do
+ expect { subject.mark_as_unchecked! }
+ .to change { subject.merge_status }
+ .from(merge_status.to_s)
+ .to(expected_merge_status)
+ end
+ end
+
+ context 'when the status is unchecked' do
+ let(:merge_status) { :unchecked }
+
+ include_examples 'for an invalid state transition'
+ end
+
+ context 'when the status is checking' do
+ let(:merge_status) { :checking }
+ let(:expected_merge_status) { 'unchecked' }
+
+ include_examples 'for an valid state transition'
+ end
+
+ context 'when the status is can_be_merged' do
+ let(:merge_status) { :can_be_merged }
+ let(:expected_merge_status) { 'unchecked' }
+
+ include_examples 'for an valid state transition'
+ end
+
+ context 'when the status is cannot_be_merged_recheck' do
+ let(:merge_status) { :cannot_be_merged_recheck }
+
+ include_examples 'for an invalid state transition'
+ end
+
+ context 'when the status is cannot_be_merged' do
+ let(:merge_status) { :cannot_be_merged }
+ let(:expected_merge_status) { 'cannot_be_merged_recheck' }
+
+ include_examples 'for an valid state transition'
+ end
+
+ context 'when the status is cannot_be_merged' do
+ let(:merge_status) { :cannot_be_merged }
+ let(:expected_merge_status) { 'cannot_be_merged_recheck' }
+
+ include_examples 'for an valid state transition'
+ end
+ end
+
describe 'transition to cannot_be_merged' do
let(:notification_service) { double(:notification_service) }
let(:todo_service) { double(:todo_service) }
@@ -4661,4 +4865,33 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
end
+
+ describe '#includes_ci_config?' do
+ let(:merge_request) { build(:merge_request) }
+ let(:project) { merge_request.project }
+
+ subject(:result) { merge_request.includes_ci_config? }
+
+ before do
+ allow(merge_request).to receive(:diff_stats).and_return(diff_stats)
+ end
+
+ context 'when diff_stats is nil' do
+ let(:diff_stats) {}
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when diff_stats does not include the ci config path of the project' do
+ let(:diff_stats) { [double(path: 'abc.txt')] }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when diff_stats includes the ci config path of the project' do
+ let(:diff_stats) { [double(path: '.gitlab-ci.yml')] }
+
+ it { is_expected.to eq(true) }
+ end
+ end
end