diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 00:08:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 00:08:44 +0300 |
commit | c75f38907c1b28adf5f57a8ad34df9f86c36d4e7 (patch) | |
tree | 2ddd657750116ea9460f76f439780af3ab255edb /spec/models | |
parent | bc578c5f89ff9d8ec03fbbd014714f9d1e5cb172 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/models')
-rw-r--r-- | spec/models/application_record_spec.rb | 33 | ||||
-rw-r--r-- | spec/models/gpg_signature_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 106 |
3 files changed, 121 insertions, 24 deletions
diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb index dbef71431a2..f9a05c720a3 100644 --- a/spec/models/application_record_spec.rb +++ b/spec/models/application_record_spec.rb @@ -39,13 +39,14 @@ RSpec.describe ApplicationRecord do let(:suggestion_attributes) { attributes_for(:suggestion).merge!(note_id: note.id) } - describe '.safe_find_or_create_by' do + shared_examples '.safe_find_or_create_by' do it 'creates the suggestion avoiding race conditions' do - expect(Suggestion).to receive(:find_or_create_by).and_raise(ActiveRecord::RecordNotUnique) - allow(Suggestion).to receive(:find_or_create_by).and_call_original + existing_suggestion = double(:Suggestion) - expect { Suggestion.safe_find_or_create_by(suggestion_attributes) } - .to change { Suggestion.count }.by(1) + expect(Suggestion).to receive(:find_by).and_return(nil, existing_suggestion) + expect(Suggestion).to receive(:create).and_raise(ActiveRecord::RecordNotUnique) + + expect(Suggestion.safe_find_or_create_by(suggestion_attributes)).to eq(existing_suggestion) end it 'passes a block to find_or_create_by' do @@ -62,10 +63,8 @@ RSpec.describe ApplicationRecord do end end - describe '.safe_find_or_create_by!' do + shared_examples '.safe_find_or_create_by!' do it 'creates a record using safe_find_or_create_by' do - expect(Suggestion).to receive(:find_or_create_by).and_call_original - expect(Suggestion.safe_find_or_create_by!(suggestion_attributes)) .to be_a(Suggestion) end @@ -89,6 +88,24 @@ RSpec.describe ApplicationRecord do .to raise_error(ActiveRecord::RecordNotFound) end end + + context 'when optimized_safe_find_or_create_by is enabled' do + before do + stub_feature_flags(optimized_safe_find_or_create_by: true) + end + + it_behaves_like '.safe_find_or_create_by' + it_behaves_like '.safe_find_or_create_by!' + end + + context 'when optimized_safe_find_or_create_by is disabled' do + before do + stub_feature_flags(optimized_safe_find_or_create_by: false) + end + + it_behaves_like '.safe_find_or_create_by' + it_behaves_like '.safe_find_or_create_by!' + end end describe '.underscore' do diff --git a/spec/models/gpg_signature_spec.rb b/spec/models/gpg_signature_spec.rb index 997d9bbec72..7a1799c670e 100644 --- a/spec/models/gpg_signature_spec.rb +++ b/spec/models/gpg_signature_spec.rb @@ -54,8 +54,10 @@ RSpec.describe GpgSignature do end it 'does not raise an error in case of a race condition' do - expect(described_class).to receive(:find_or_create_by).and_raise(ActiveRecord::RecordNotUnique) - allow(described_class).to receive(:find_or_create_by).and_call_original + expect(described_class).to receive(:find_by).and_return(nil, double(described_class, persisted?: true)) + + expect(described_class).to receive(:create).and_raise(ActiveRecord::RecordNotUnique) + allow(described_class).to receive(:create).and_call_original described_class.safe_create!(attributes) end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 2945a842ebc..d8f3a63d221 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -6,6 +6,7 @@ RSpec.describe Project, factory_default: :keep do include ProjectForksHelper include GitHelpers include ExternalAuthorizationServiceHelpers + include ReloadHelpers using RSpec::Parameterized::TableSyntax let_it_be(:namespace) { create_default(:namespace).freeze } @@ -3021,29 +3022,106 @@ RSpec.describe Project, factory_default: :keep do end end - describe '#ancestors_upto' do - let_it_be(:parent) { create(:group) } - let_it_be(:child) { create(:group, parent: parent) } - let_it_be(:child2) { create(:group, parent: child) } - let_it_be(:project) { create(:project, namespace: child2) } + shared_context 'project with group ancestry' do + let(:parent) { create(:group) } + let(:child) { create(:group, parent: parent) } + let(:child2) { create(:group, parent: child) } + let(:project) { create(:project, namespace: child2) } + + before do + reload_models(parent, child, child2) + end + end + + shared_context 'project with namespace ancestry' do + let(:namespace) { create :namespace } + let(:project) { create :project, namespace: namespace } + end - it 'returns all ancestors when no namespace is given' do - expect(project.ancestors_upto).to contain_exactly(child2, child, parent) + shared_examples 'project with group ancestors' do + it 'returns all ancestors' do + is_expected.to contain_exactly(child2, child, parent) end + end + + shared_examples 'project with ordered group ancestors' do + let(:hierarchy_order) { :desc } - it 'includes ancestors upto but excluding the given ancestor' do - expect(project.ancestors_upto(parent)).to contain_exactly(child2, child) + it 'returns ancestors ordered by descending hierarchy' do + is_expected.to eq([parent, child, child2]) end + end + + shared_examples '#ancestors' do + context 'group ancestory' do + include_context 'project with group ancestry' - describe 'with hierarchy_order' do - it 'returns ancestors ordered by descending hierarchy' do - expect(project.ancestors_upto(hierarchy_order: :desc)).to eq([parent, child, child2]) + it_behaves_like 'project with group ancestors' do + subject { project.ancestors } end - it 'can be used with upto option' do - expect(project.ancestors_upto(parent, hierarchy_order: :desc)).to eq([child, child2]) + it_behaves_like 'project with ordered group ancestors' do + subject { project.ancestors(hierarchy_order: hierarchy_order) } end end + + context 'namespace ancestry' do + include_context 'project with namespace ancestry' + + subject { project.ancestors } + + it { is_expected.to be_empty } + end + end + + describe '#ancestors' do + context 'with linear_project_ancestors feature flag enabled' do + before do + stub_feature_flags(linear_project_ancestors: true) + end + + include_examples '#ancestors' + end + + context 'with linear_project_ancestors feature flag disabled' do + before do + stub_feature_flags(linear_project_ancestors: false) + end + + include_examples '#ancestors' + end + end + + describe '#ancestors_upto' do + context 'group ancestry' do + include_context 'project with group ancestry' + + it_behaves_like 'project with group ancestors' do + subject { project.ancestors_upto } + end + + it_behaves_like 'project with ordered group ancestors' do + subject { project.ancestors_upto(hierarchy_order: hierarchy_order) } + end + + it 'includes ancestors upto but excluding the given ancestor' do + expect(project.ancestors_upto(parent)).to contain_exactly(child2, child) + end + + describe 'with hierarchy_order' do + it 'can be used with upto option' do + expect(project.ancestors_upto(parent, hierarchy_order: :desc)).to eq([child, child2]) + end + end + end + + context 'namespace ancestry' do + include_context 'project with namespace ancestry' + + subject { project.ancestors_upto } + + it { is_expected.to be_empty } + end end describe '#root_ancestor' do |