summaryrefslogtreecommitdiff
path: root/spec/models/group_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/group_spec.rb')
-rw-r--r--spec/models/group_spec.rb196
1 files changed, 193 insertions, 3 deletions
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index dfba0470d35..4605c086763 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Group do
+RSpec.describe Group, feature_category: :subgroups do
include ReloadHelpers
include StubGitlabCalls
@@ -11,9 +11,11 @@ RSpec.describe Group do
describe 'associations' do
it { is_expected.to have_many :projects }
it { is_expected.to have_many(:group_members).dependent(:destroy) }
+ it { is_expected.to have_many(:namespace_members) }
it { is_expected.to have_many(:users).through(:group_members) }
it { is_expected.to have_many(:owners).through(:group_members) }
it { is_expected.to have_many(:requesters).dependent(:destroy) }
+ it { is_expected.to have_many(:namespace_requesters) }
it { is_expected.to have_many(:members_and_requesters) }
it { is_expected.to have_many(:project_group_links).dependent(:destroy) }
it { is_expected.to have_many(:shared_projects).through(:project_group_links) }
@@ -45,7 +47,7 @@ RSpec.describe Group do
it { is_expected.to have_one(:group_feature) }
it { is_expected.to have_one(:harbor_integration) }
- describe '#members & #requesters' do
+ describe '#namespace_members' do
let(:requester) { create(:user) }
let(:developer) { create(:user) }
@@ -54,6 +56,98 @@ RSpec.describe Group do
group.add_developer(developer)
end
+ it 'includes the correct users' do
+ expect(group.namespace_members).to include Member.find_by(user: developer)
+ expect(group.namespace_members).not_to include Member.find_by(user: requester)
+ end
+
+ it 'is equivelent to #group_members' do
+ expect(group.namespace_members).to eq group.group_members
+ end
+
+ it_behaves_like 'query without source filters' do
+ subject { group.namespace_members }
+ end
+ end
+
+ describe '#namespace_requesters' do
+ let(:requester) { create(:user) }
+ let(:developer) { create(:user) }
+
+ before do
+ group.request_access(requester)
+ group.add_developer(developer)
+ end
+
+ it 'includes the correct users' do
+ expect(group.namespace_requesters).to include Member.find_by(user: requester)
+ expect(group.namespace_requesters).not_to include Member.find_by(user: developer)
+ end
+
+ it 'is equivalent to #requesters' do
+ expect(group.namespace_requesters).to eq group.requesters
+ end
+
+ it_behaves_like 'query without source filters' do
+ subject { group.namespace_requesters }
+ end
+ end
+
+ shared_examples 'polymorphic membership relationship' do
+ it do
+ expect(membership.attributes).to include(
+ 'source_type' => 'Namespace',
+ 'source_id' => group.id
+ )
+ end
+ end
+
+ shared_examples 'member_namespace membership relationship' do
+ it do
+ expect(membership.attributes).to include(
+ 'member_namespace_id' => group.id
+ )
+ end
+ end
+
+ describe '#namespace_members setters' do
+ let(:user) { create(:user) }
+ let(:membership) { group.namespace_members.create!(user: user, access_level: Gitlab::Access::DEVELOPER) }
+
+ it { expect(membership).to be_instance_of(GroupMember) }
+ it { expect(membership.user).to eq user }
+ it { expect(membership.group).to eq group }
+ it { expect(membership.requested_at).to be_nil }
+
+ it_behaves_like 'polymorphic membership relationship'
+ it_behaves_like 'member_namespace membership relationship'
+ end
+
+ describe '#namespace_requesters setters' do
+ let(:requested_at) { Time.current }
+ let(:user) { create(:user) }
+ let(:membership) do
+ group.namespace_requesters.create!(user: user, requested_at: requested_at, access_level: Gitlab::Access::DEVELOPER)
+ end
+
+ it { expect(membership).to be_instance_of(GroupMember) }
+ it { expect(membership.user).to eq user }
+ it { expect(membership.group).to eq group }
+ it { expect(membership.requested_at).to eq requested_at }
+
+ it_behaves_like 'polymorphic membership relationship'
+ it_behaves_like 'member_namespace membership relationship'
+ end
+
+ describe '#members & #requesters' do
+ let_it_be(:requester) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+
+ before do
+ group.request_access(requester)
+ group.add_developer(developer)
+ end
+
it_behaves_like 'members and requesters associations' do
let(:namespace) { group }
end
@@ -2648,7 +2742,81 @@ RSpec.describe Group do
end
end
- context 'disabled_with_override' do
+ context 'disabled_and_overridable' do
+ subject { group.update_shared_runners_setting!(Namespace::SR_DISABLED_AND_OVERRIDABLE) }
+
+ context 'top level group' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled) }
+ let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
+ let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
+
+ it 'enables allow descendants to override only for itself' do
+ expect { subject_and_reload(group, sub_group, project) }
+ .to change { group.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
+ .and not_change { group.shared_runners_enabled }
+ .and not_change { sub_group.allow_descendants_override_disabled_shared_runners }
+ .and not_change { sub_group.shared_runners_enabled }
+ .and not_change { project.shared_runners_enabled }
+ end
+ end
+
+ context 'group that its ancestors have shared Runners disabled but allows to override' do
+ let_it_be(:parent) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners) }
+ let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
+ let_it_be(:project) { create(:project, shared_runners_enabled: false, group: group) }
+
+ it 'enables allow descendants to override' do
+ expect { subject_and_reload(parent, group, project) }
+ .to not_change { parent.allow_descendants_override_disabled_shared_runners }
+ .and not_change { parent.shared_runners_enabled }
+ .and change { group.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
+ .and not_change { group.shared_runners_enabled }
+ .and not_change { project.shared_runners_enabled }
+ end
+ end
+
+ context 'when parent does not allow' do
+ let_it_be(:parent, reload: true) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false) }
+ let_it_be(:group, reload: true) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
+
+ it 'raises exception' do
+ expect { subject }
+ .to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Allow descendants override disabled shared runners cannot be enabled because parent group does not allow it')
+ end
+
+ it 'does not allow descendants to override' do
+ expect do
+ begin
+ subject
+ rescue StandardError
+ nil
+ end
+
+ parent.reload
+ group.reload
+ end.to not_change { parent.allow_descendants_override_disabled_shared_runners }
+ .and not_change { parent.shared_runners_enabled }
+ .and not_change { group.allow_descendants_override_disabled_shared_runners }
+ .and not_change { group.shared_runners_enabled }
+ end
+ end
+
+ context 'top level group that has shared Runners enabled' do
+ let_it_be(:group) { create(:group, shared_runners_enabled: true) }
+ let_it_be(:sub_group) { create(:group, shared_runners_enabled: true, parent: group) }
+ let_it_be(:project) { create(:project, shared_runners_enabled: true, group: sub_group) }
+
+ it 'enables allow descendants to override & disables shared runners everywhere' do
+ expect { subject_and_reload(group, sub_group, project) }
+ .to change { group.shared_runners_enabled }.from(true).to(false)
+ .and change { group.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
+ .and change { sub_group.shared_runners_enabled }.from(true).to(false)
+ .and change { project.shared_runners_enabled }.from(true).to(false)
+ end
+ end
+ end
+
+ context 'disabled_with_override (deprecated)' do
subject { group.update_shared_runners_setting!(Namespace::SR_DISABLED_WITH_OVERRIDE) }
context 'top level group' do
@@ -3486,4 +3654,26 @@ RSpec.describe Group do
it { is_expected.to be_nil }
end
end
+
+ describe '#usage_quotas_enabled?', feature_category: :subscription_cost_management, unless: Gitlab.ee? do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:feature_enabled, :root_group, :result) do
+ false | true | false
+ false | false | false
+ true | false | false
+ true | true | true
+ end
+
+ with_them do
+ before do
+ stub_feature_flags(usage_quotas_for_all_editions: feature_enabled)
+ allow(group).to receive(:root?).and_return(root_group)
+ end
+
+ it 'returns the expected result' do
+ expect(group.usage_quotas_enabled?).to eq result
+ end
+ end
+ end
end