summaryrefslogtreecommitdiff
path: root/spec/models/namespace_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/namespace_spec.rb')
-rw-r--r--spec/models/namespace_spec.rb169
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