diff options
Diffstat (limited to 'spec/models/namespace_spec.rb')
-rw-r--r-- | spec/models/namespace_spec.rb | 154 |
1 files changed, 130 insertions, 24 deletions
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index d063f4713c7..a0698ac30f5 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Namespace do +RSpec.describe Namespace, feature_category: :subgroups do include ProjectForksHelper include ReloadHelpers @@ -36,6 +36,8 @@ RSpec.describe Namespace do it { is_expected.to have_many(:work_items) } it { is_expected.to have_many :achievements } it { is_expected.to have_many(:namespace_commit_emails).class_name('Users::NamespaceCommitEmail') } + it { is_expected.to have_many(:cycle_analytics_stages) } + it { is_expected.to have_many(:value_streams) } it do is_expected.to have_one(:ci_cd_settings).class_name('NamespaceCiCdSetting').inverse_of(:namespace).autosave(true) @@ -402,6 +404,62 @@ RSpec.describe Namespace do it { is_expected.to include_module(Namespaces::Traversal::LinearScopes) } end + describe '#traversal_ids' do + let(:namespace) { build(:group) } + + context 'when namespace not persisted' do + it 'returns []' do + expect(namespace.traversal_ids).to eq [] + end + end + + context 'when namespace just saved' do + let(:namespace) { build(:group) } + + before do + namespace.save! + end + + it 'returns value that matches database' do + expect(namespace.traversal_ids).to eq Namespace.find(namespace.id).traversal_ids + end + end + + context 'when namespace loaded from database' do + before do + namespace.save! + namespace.reload + end + + it 'returns database value' do + expect(namespace.traversal_ids).to eq Namespace.find(namespace.id).traversal_ids + end + end + + context 'when made a child group' do + let!(:namespace) { create(:group) } + let!(:parent_namespace) { create(:group, children: [namespace]) } + + it 'returns database value' do + expect(namespace.traversal_ids).to eq [parent_namespace.id, namespace.id] + end + end + + context 'when root_ancestor changes' do + let(:old_root) { create(:group) } + let(:namespace) { create(:group, parent: old_root) } + let(:new_root) { create(:group) } + + it 'resets root_ancestor memo' do + expect(namespace.root_ancestor).to eq old_root + + namespace.update!(parent: new_root) + + expect(namespace.root_ancestor).to eq new_root + end + end + end + context 'traversal scopes' do context 'recursive' do before do @@ -477,36 +535,60 @@ RSpec.describe Namespace do end context 'traversal_ids on create' do - shared_examples 'default traversal_ids' do - let!(:namespace) { create(:group) } - let!(:child_namespace) { create(:group, parent: namespace) } + let(:parent) { create(:group) } + let(:child) { create(:group, parent: parent) } - it { expect(namespace.reload.traversal_ids).to eq [namespace.id] } - it { expect(child_namespace.reload.traversal_ids).to eq [namespace.id, child_namespace.id] } - it { expect(namespace.sync_events.count).to eq 1 } - it { expect(child_namespace.sync_events.count).to eq 1 } - end + it { expect(parent.traversal_ids).to eq [parent.id] } + it { expect(child.traversal_ids).to eq [parent.id, child.id] } + it { expect(parent.sync_events.count).to eq 1 } + it { expect(child.sync_events.count).to eq 1 } - it_behaves_like 'default traversal_ids' + context 'when set_traversal_ids_on_save feature flag is disabled' do + before do + stub_feature_flags(set_traversal_ids_on_save: false) + end + + it 'only sets traversal_ids on reload' do + expect { parent.reload }.to change(parent, :traversal_ids).from([]).to([parent.id]) + expect { child.reload }.to change(child, :traversal_ids).from([]).to([parent.id, child.id]) + end + end end context 'traversal_ids on update' do - let!(:namespace1) { create(:group) } - let!(:namespace2) { create(:group) } + let(:namespace1) { create(:group) } + let(:namespace2) { create(:group) } + + context 'when parent_id is changed' do + subject { namespace1.update!(parent: namespace2) } + + it 'sets the traversal_ids attribute' do + expect { subject }.to change { namespace1.traversal_ids }.from([namespace1.id]).to([namespace2.id, namespace1.id]) + end + + context 'when set_traversal_ids_on_save feature flag is disabled' do + before do + stub_feature_flags(set_traversal_ids_on_save: false) + end - it 'updates the traversal_ids when the parent_id is changed' do - expect do - namespace1.update!(parent: namespace2) - end.to change { namespace1.reload.traversal_ids }.from([namespace1.id]).to([namespace2.id, namespace1.id]) + it 'sets traversal_ids after reload' do + subject + + expect { namespace1.reload }.to change(namespace1, :traversal_ids).from([]).to([namespace2.id, namespace1.id]) + end + end end it 'creates a Namespaces::SyncEvent using triggers' do Namespaces::SyncEvent.delete_all - namespace1.update!(parent: namespace2) - expect(namespace1.reload.sync_events.count).to eq(1) + + expect { namespace1.update!(parent: namespace2) }.to change(namespace1.sync_events, :count).by(1) end it 'creates sync_events using database trigger on the table' do + namespace1.save! + namespace2.save! + expect { Group.update_all(traversal_ids: [-1]) }.to change(Namespaces::SyncEvent, :count).by(2) end @@ -1263,12 +1345,23 @@ RSpec.describe Namespace do end describe ".clean_path" do - let!(:user) { create(:user, username: "johngitlab-etc") } - let!(:namespace) { create(:namespace, path: "JohnGitLab-etc1") } + it "cleans the path and makes sure it's available", time_travel_to: '2023-04-20 00:07 -0700' do + create :user, username: "johngitlab-etc" + create :namespace, path: "JohnGitLab-etc1" + [nil, 1, 2, 3].each do |count| + create :namespace, path: "pickle#{count}" + end - it "cleans the path and makes sure it's available" do expect(described_class.clean_path("-john+gitlab-ETC%.git@gmail.com")).to eq("johngitlab-ETC2") expect(described_class.clean_path("--%+--valid_*&%name=.git.%.atom.atom.@email.com")).to eq("valid_name") + + # when we have more than MAX_TRIES count of a path use a more randomized suffix + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle4") + create(:namespace, path: "pickle4") + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle716") + create(:namespace, path: "pickle716") + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle717") + expect(described_class.clean_path("--$--pickle@gmail.com")).to eq("pickle717") end end @@ -1595,6 +1688,8 @@ RSpec.describe Namespace do end it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do + stub_feature_flags(do_not_run_safety_net_auth_refresh_jobs: false) + expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to( receive(:bulk_perform_in) .with(1.hour, @@ -1992,10 +2087,21 @@ RSpec.describe Namespace do end describe '#emails_enabled?' do - it "is the opposite of emails_disabled" do - group = create(:group, emails_disabled: false) + context 'without a persisted namespace_setting object' do + let(:group) { build(:group, emails_disabled: false) } - expect(group.emails_enabled?).to be_truthy + it "is the opposite of emails_disabled" do + expect(group.emails_enabled?).to be_truthy + end + end + + context 'with a persisted namespace_setting object' do + let(:namespace_settings) { create(:namespace_settings, emails_enabled: true) } + let(:group) { build(:group, emails_disabled: false, namespace_settings: namespace_settings) } + + it "is the opposite of emails_disabled" do + expect(group.emails_enabled?).to be_truthy + end end end |