diff options
Diffstat (limited to 'spec/models/group_spec.rb')
-rw-r--r-- | spec/models/group_spec.rb | 196 |
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 |