diff options
Diffstat (limited to 'spec/models/namespace_spec.rb')
-rw-r--r-- | spec/models/namespace_spec.rb | 169 |
1 files changed, 123 insertions, 46 deletions
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 65d787d334b..96ecc9836d4 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -21,6 +21,7 @@ RSpec.describe Namespace do it { is_expected.to have_many :custom_emoji } it { is_expected.to have_one :package_setting_relation } it { is_expected.to have_one :onboarding_progress } + it { is_expected.to have_one :admin_note } end describe 'validations' do @@ -154,6 +155,33 @@ RSpec.describe Namespace do end end + describe 'scopes' do + let_it_be(:namespace1) { create(:group, name: 'Namespace 1', path: 'namespace-1') } + let_it_be(:namespace2) { create(:group, name: 'Namespace 2', path: 'namespace-2') } + let_it_be(:namespace1sub) { create(:group, name: 'Sub Namespace', path: 'sub-namespace', parent: namespace1) } + let_it_be(:namespace2sub) { create(:group, name: 'Sub Namespace', path: 'sub-namespace', parent: namespace2) } + + describe '.by_parent' do + it 'includes correct namespaces' do + expect(described_class.by_parent(namespace1.id)).to eq([namespace1sub]) + expect(described_class.by_parent(namespace2.id)).to eq([namespace2sub]) + expect(described_class.by_parent(nil)).to match_array([namespace, namespace1, namespace2]) + end + end + + describe '.filter_by_path' do + it 'includes correct namespaces' do + expect(described_class.filter_by_path(namespace1.path)).to eq([namespace1]) + expect(described_class.filter_by_path(namespace2.path)).to eq([namespace2]) + expect(described_class.filter_by_path('sub-namespace')).to match_array([namespace1sub, namespace2sub]) + end + + it 'filters case-insensitive' do + expect(described_class.filter_by_path(namespace1.path.upcase)).to eq([namespace1]) + end + end + end + describe 'delegate' do it { is_expected.to delegate_method(:name).to(:owner).with_prefix.with_arguments(allow_nil: true) } it { is_expected.to delegate_method(:avatar_url).to(:owner).with_arguments(allow_nil: true) } @@ -168,27 +196,19 @@ RSpec.describe Namespace do describe 'inclusions' do it { is_expected.to include_module(Gitlab::VisibilityLevel) } it { is_expected.to include_module(Namespaces::Traversal::Recursive) } + it { is_expected.to include_module(Namespaces::Traversal::Linear) } end - describe 'callbacks' do - describe 'before_save :ensure_delayed_project_removal_assigned_to_namespace_settings' do - it 'sets the matching value in namespace_settings' do - expect { namespace.update!(delayed_project_removal: true) }.to change { - namespace.namespace_settings.delayed_project_removal - }.from(false).to(true) - end - - context 'when the feature flag is disabled' do - before do - stub_feature_flags(migrate_delayed_project_removal: false) - end + context 'traversal_ids on create' do + context 'default traversal_ids' do + let(:namespace) { build(:namespace) } - it 'does not set the matching value in namespace_settings' do - expect { namespace.update!(delayed_project_removal: true) }.not_to change { - namespace.namespace_settings.delayed_project_removal - } - end + before do + namespace.save! + namespace.reload end + + it { expect(namespace.traversal_ids).to eq [namespace.id] } end end @@ -859,7 +879,51 @@ RSpec.describe Namespace do end end - it_behaves_like 'recursive namespace traversal' + describe '#use_traversal_ids?' do + let_it_be(:namespace) { build(:namespace) } + + subject { namespace.use_traversal_ids? } + + context 'when use_traversal_ids feature flag is true' do + before do + stub_feature_flags(use_traversal_ids: true) + end + + it { is_expected.to eq true } + end + + context 'when use_traversal_ids feature flag is false' do + before do + stub_feature_flags(use_traversal_ids: false) + end + + it { is_expected.to eq false } + end + end + + context 'when use_traversal_ids feature flag is true' do + it_behaves_like 'namespace traversal' + + describe '#self_and_descendants' do + subject { namespace.self_and_descendants } + + it { expect(subject.to_sql).to include 'traversal_ids @>' } + end + end + + context 'when use_traversal_ids feature flag is false' do + before do + stub_feature_flags(use_traversal_ids: false) + end + + it_behaves_like 'namespace traversal' + + describe '#self_and_descendants' do + subject { namespace.self_and_descendants } + + it { expect(subject.to_sql).not_to include 'traversal_ids @>' } + end + end describe '#users_with_descendants' do let(:user_a) { create(:user) } @@ -897,24 +961,10 @@ RSpec.describe Namespace do it { expect(namespace.all_projects.to_a).to match_array([project2, project1]) } it { expect(child.all_projects.to_a).to match_array([project2]) } - context 'when recursive_namespace_lookup_as_inner_join feature flag is on' do - before do - stub_feature_flags(recursive_namespace_lookup_as_inner_join: true) - end + it 'queries for the namespace and its descendants' do + expect(Project).to receive(:where).with(namespace: [namespace, child]) - it 'queries for the namespace and its descendants' do - expect(namespace.all_projects).to match_array([project1, project2]) - end - end - - context 'when recursive_namespace_lookup_as_inner_join feature flag is off' do - before do - stub_feature_flags(recursive_namespace_lookup_as_inner_join: false) - end - - it 'queries for the namespace and its descendants' do - expect(namespace.all_projects).to match_array([project1, project2]) - end + namespace.all_projects end end @@ -1085,21 +1135,42 @@ RSpec.describe Namespace do end describe '#root_ancestor' do - let!(:root_group) { create(:group) } + context 'with persisted root group' do + let!(:root_group) { create(:group) } - it 'returns root_ancestor for root group without a query' do - expect { root_group.root_ancestor }.not_to exceed_query_limit(0) + it 'returns root_ancestor for root group without a query' do + expect { root_group.root_ancestor }.not_to exceed_query_limit(0) + end + + it 'returns the top most ancestor' do + nested_group = create(:group, parent: root_group) + deep_nested_group = create(:group, parent: nested_group) + very_deep_nested_group = create(:group, parent: deep_nested_group) + + expect(root_group.root_ancestor).to eq(root_group) + expect(nested_group.root_ancestor).to eq(root_group) + expect(deep_nested_group.root_ancestor).to eq(root_group) + expect(very_deep_nested_group.root_ancestor).to eq(root_group) + end end - it 'returns the top most ancestor' do - nested_group = create(:group, parent: root_group) - deep_nested_group = create(:group, parent: nested_group) - very_deep_nested_group = create(:group, parent: deep_nested_group) + context 'with not persisted root group' do + let!(:root_group) { build(:group) } - expect(root_group.root_ancestor).to eq(root_group) - expect(nested_group.root_ancestor).to eq(root_group) - expect(deep_nested_group.root_ancestor).to eq(root_group) - expect(very_deep_nested_group.root_ancestor).to eq(root_group) + it 'returns root_ancestor for root group without a query' do + expect { root_group.root_ancestor }.not_to exceed_query_limit(0) + end + + it 'returns the top most ancestor' do + nested_group = build(:group, parent: root_group) + deep_nested_group = build(:group, parent: nested_group) + very_deep_nested_group = build(:group, parent: deep_nested_group) + + expect(root_group.root_ancestor).to eq(root_group) + expect(nested_group.root_ancestor).to eq(root_group) + expect(deep_nested_group.root_ancestor).to eq(root_group) + expect(very_deep_nested_group.root_ancestor).to eq(root_group) + end end end @@ -1372,6 +1443,12 @@ RSpec.describe Namespace do end end + describe '#paid?' do + it 'returns false for a root namespace with a free plan' do + expect(namespace.paid?).to eq(false) + end + end + describe '#shared_runners_setting' do using RSpec::Parameterized::TableSyntax |