Commit c4fa6214 authored by Vijay Hawoldar's avatar Vijay Hawoldar Committed by Etienne Baqué

Add more verification for namespace UserCap availability

parent c827d97b
......@@ -19,7 +19,7 @@ class Groups::UsageQuotasController < Groups::ApplicationController
end
def pending_members
render_404 unless ::Feature.enabled?(:saas_user_caps, @group.root_ancestor, default_enabled: :yaml)
render_404 unless @group.user_cap_available?
@hide_search_settings = true
end
......
......@@ -4,10 +4,8 @@ module EE
module NamespaceUserCapReachedAlertHelper
def display_namespace_user_cap_reached_alert?(namespace)
root_namespace = namespace.root_ancestor
return false unless ::Feature.enabled?(:saas_user_caps, root_namespace, default_enabled: :yaml)
return false if root_namespace.user_namespace?
return false unless root_namespace.user_cap_available?
return false if alert_has_been_dismissed?(root_namespace)
can?(current_user, :admin_namespace, root_namespace) && root_namespace.user_cap_reached?(use_cache: true)
......
......@@ -512,7 +512,7 @@ module EE
end
def user_cap_reached?(use_cache: false)
return false unless ::Feature.enabled?(:saas_user_caps, root_ancestor, default_enabled: :yaml)
return false unless user_cap_available?
user_cap = root_ancestor.namespace_settings&.new_user_signups_cap
return false unless user_cap
......
......@@ -447,6 +447,13 @@ module EE
klass.new(self)
end
def user_cap_available?
return false unless group_namespace?
return false unless ::Gitlab.com?
::Feature.enabled?(:saas_user_caps, root_ancestor, default_enabled: :yaml)
end
private
def any_project_with_shared_runners_enabled_with_cte?
......
- return unless Feature.enabled?(:saas_user_caps, group.root_ancestor)
- return unless group.user_cap_available?
.form-group
= f.label :new_user_signups_cap, _('User cap'), class: 'gl-font-weight-bold'
......
- page_title s_("UsageQuota|Usage")
- url_to_purchase_storage = buy_storage_path(@group) if purchase_storage_link_enabled?(@group)
- pending_members_page_path = pending_members_group_usage_quotas_path(@group) if Feature.enabled?(:saas_user_caps, @group.root_ancestor)
- pending_members_page_path = pending_members_group_usage_quotas_path(@group) if @group.user_cap_available?
- pending_members_count = Member.in_hierarchy(@group).with_state("awaiting").count
- if show_product_purchase_success_alert?
......
......@@ -37,4 +37,30 @@ RSpec.describe Groups::UsageQuotasController do
end
end
end
describe 'GET #pending_members' do
let(:feature_available) { true }
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:user_cap_available?).and_return(feature_available)
end
end
it 'renders the pending members index' do
get :pending_members, params: { group_id: group }
expect(response).to render_template 'groups/usage_quotas/pending_members'
end
context 'when user cap feature is unavailable' do
let(:feature_available) { false }
it 'returns 404' do
get :pending_members, params: { group_id: group }
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
......@@ -409,9 +409,18 @@ RSpec.describe 'Edit group settings' do
end
describe 'user caps settings' do
context 'when :saas_user_caps feature flag is off' do
let(:user_cap_available) { true }
before do
allow_next_found_instance_of(Group) do |instance|
allow(instance).to receive(:user_cap_available?).and_return user_cap_available
end
end
context 'when user cap feature is unavailable' do
let(:user_cap_available) { false }
before do
stub_feature_flags(saas_user_caps: false)
visit edit_group_path(group)
end
......@@ -420,11 +429,10 @@ RSpec.describe 'Edit group settings' do
end
end
context 'when :saas_user_caps feature flag is on', :js do
context 'when user cap feature is available', :js do
let(:user_caps_selector) { '[name="group[new_user_signups_cap]"]' }
before do
stub_feature_flags(saas_user_caps: true)
visit edit_group_path(group)
end
......@@ -479,7 +487,6 @@ RSpec.describe 'Edit group settings' do
end
before do
stub_feature_flags(saas_user_caps: true)
group.namespace_settings.update!(new_user_signups_cap: group.group_members.count)
end
......
......@@ -24,6 +24,8 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js, :use_clean_rai
context 'with an exceeded user cap' do
before do
allow(Gitlab).to receive(:com?).and_return(true)
stub_cache(group)
end
......
......@@ -23,19 +23,23 @@ RSpec.describe EE::NamespaceUserCapReachedAlertHelper, :use_clean_rails_memory_s
before do
allow(helper).to receive(:can?).with(owner, :admin_namespace, group).and_return(true)
allow(helper).to receive(:can?).with(developer, :admin_namespace, group).and_return(false)
allow(group).to receive(:user_cap_available?).and_return(true)
stub_cache(group)
end
subject(:display_alert?) { helper.display_namespace_user_cap_reached_alert?(group) }
it 'returns true when the user cap is reached for a user who can admin the namespace' do
sign_in(owner)
expect(helper.display_namespace_user_cap_reached_alert?(group)).to be true
expect(display_alert?).to be true
end
it 'returns false when the user cap is reached for a user who cannot admin the namespace' do
sign_in(developer)
expect(helper.display_namespace_user_cap_reached_alert?(group)).to be false
expect(display_alert?).to be false
end
it 'does not trigger reactive caching if there is no user cap set' do
......@@ -44,7 +48,15 @@ RSpec.describe EE::NamespaceUserCapReachedAlertHelper, :use_clean_rails_memory_s
sign_in(owner)
expect(group).not_to receive(:with_reactive_cache)
expect(helper.display_namespace_user_cap_reached_alert?(group)).to be false
expect(display_alert?).to be false
end
it 'returns false when the user cap feature is unavailable' do
allow(group).to receive(:user_cap_available?).and_return(false)
sign_in(owner)
expect(display_alert?).to be false
end
def sign_in(user)
......
......@@ -1495,63 +1495,77 @@ RSpec.describe Group do
describe '#user_cap_reached?' do
subject(:user_cap_reached_for_group?) { group.user_cap_reached? }
context 'when the :saas_user_caps feature flag is not enabled' do
context 'when user cap feature is not available' do
before do
allow(group).to receive(:user_cap_available?).and_return(false)
end
it { is_expected.to be_falsey }
end
context 'when the :saas_user_caps feature flag is enabled' do
context 'when user cap feature is available' do
before do
stub_feature_flags(saas_user_caps: true)
allow(group).to receive(:user_cap_available?).and_return(true)
end
let(:new_user_signups_cap) { nil }
context 'when the :saas_user_caps feature flag is not enabled' do
it { is_expected.to be_falsey }
end
shared_context 'returning the right value for user_cap_reached?' do
context 'when the :saas_user_caps feature flag is enabled' do
before do
root_group.namespace_settings.update!(new_user_signups_cap: new_user_signups_cap)
stub_feature_flags(saas_user_caps: true)
end
context 'when no user cap has been set to that root ancestor' do
it { is_expected.to be_falsey }
end
context 'when a user cap has been set to that root ancestor' do
let(:new_user_signups_cap) { 100 }
let(:new_user_signups_cap) { nil }
shared_examples 'returning the right value for user_cap_reached?' do
before do
allow(root_group).to receive(:billable_members_count).and_return(billable_members_count)
allow(group).to receive(:root_ancestor).and_return(root_group)
root_group.namespace_settings.update!(new_user_signups_cap: new_user_signups_cap)
end
context 'when this cap is higher than the number of billable members' do
let(:billable_members_count) { new_user_signups_cap - 10 }
context 'when no user cap has been set to that root ancestor' do
it { is_expected.to be_falsey }
end
context 'when this cap is the same as the number of billable members' do
let(:billable_members_count) { new_user_signups_cap }
context 'when a user cap has been set to that root ancestor' do
let(:new_user_signups_cap) { 100 }
it { is_expected.to be_truthy }
end
before do
allow(root_group).to receive(:billable_members_count).and_return(billable_members_count)
allow(group).to receive(:root_ancestor).and_return(root_group)
end
context 'when this cap is lower than the number of billable members' do
let(:billable_members_count) { new_user_signups_cap + 10 }
context 'when this cap is higher than the number of billable members' do
let(:billable_members_count) { new_user_signups_cap - 10 }
it { is_expected.to be_truthy }
it { is_expected.to be_falsey }
end
context 'when this cap is the same as the number of billable members' do
let(:billable_members_count) { new_user_signups_cap }
it { is_expected.to be_truthy }
end
context 'when this cap is lower than the number of billable members' do
let(:billable_members_count) { new_user_signups_cap + 10 }
it { is_expected.to be_truthy }
end
end
end
end
context 'when this group has no root ancestor' do
it_behaves_like 'returning the right value for user_cap_reached?' do
let(:root_group) { group }
context 'when this group has no root ancestor' do
it_behaves_like 'returning the right value for user_cap_reached?' do
let(:root_group) { group }
end
end
end
context 'when this group has a root ancestor' do
it_behaves_like 'returning the right value for user_cap_reached?' do
let(:root_group) { create(:group, children: [group]) }
context 'when this group has a root ancestor' do
it_behaves_like 'returning the right value for user_cap_reached?' do
let(:root_group) { create(:group, children: [group]) }
end
end
end
end
......
......@@ -1960,6 +1960,48 @@ RSpec.describe Namespace do
end
end
describe '#user_cap_available?' do
let_it_be(:namespace) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: namespace) }
let(:gitlab_com?) { true }
subject(:user_cap_available?) { namespace.user_cap_available? }
before do
allow(::Gitlab).to receive(:com?).and_return(gitlab_com?)
end
context 'when not on Gitlab.com' do
let(:gitlab_com?) { false }
it { is_expected.to be false }
end
context 'when :saas_user_caps is disabled' do
before do
stub_feature_flags(saas_user_caps: false)
end
it { is_expected.to be false }
end
context 'when :saas_user_caps is enabled' do
before do
stub_feature_flags(saas_user_caps: true)
end
it { is_expected.to be true }
context 'when the namespace is not a group' do
let(:user) { create(:user) }
let(:namespace) { user.namespace }
it { is_expected.to be false }
end
end
end
def create_project(repository_size:, lfs_objects_size:, repository_size_limit:)
create(:project, namespace: namespace, repository_size_limit: repository_size_limit).tap do |project|
create(:project_statistics, project: project, repository_size: repository_size, lfs_objects_size: lfs_objects_size)
......
......@@ -20,6 +20,7 @@ RSpec.describe 'shared/namespace_user_cap_reached_alert', :use_clean_rails_memor
before do
allow(view).to receive(:current_user).and_return(owner)
allow(Gitlab).to receive(:com?).and_return(true)
stub_cache(group)
stub_cache(other_group)
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment