Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
371024f5
Commit
371024f5
authored
Nov 18, 2021
by
Jason Goodman
Committed by
Etienne Baqué
Nov 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use ReactiveCaching for Namespace User Cap Banner
parent
df155fcb
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
70 additions
and
110 deletions
+70
-110
ee/app/helpers/ee/namespace_user_cap_reached_alert_helper.rb
ee/app/helpers/ee/namespace_user_cap_reached_alert_helper.rb
+1
-7
ee/app/models/ee/group.rb
ee/app/models/ee/group.rb
+19
-5
ee/app/models/ee/member.rb
ee/app/models/ee/member.rb
+0
-8
ee/spec/features/namespace_user_cap_reached_alert_spec.rb
ee/spec/features/namespace_user_cap_reached_alert_spec.rb
+25
-1
ee/spec/helpers/ee/namespace_user_cap_reached_alert_helper_spec.rb
...elpers/ee/namespace_user_cap_reached_alert_helper_spec.rb
+14
-12
ee/spec/models/member_spec.rb
ee/spec/models/member_spec.rb
+0
-76
ee/spec/views/shared/_namespace_user_cap_reached_alert.html.haml_spec.rb
...hared/_namespace_user_cap_reached_alert.html.haml_spec.rb
+11
-1
No files found.
ee/app/helpers/ee/namespace_user_cap_reached_alert_helper.rb
View file @
371024f5
...
...
@@ -10,7 +10,7 @@ module EE
return
false
if
alert_has_been_dismissed?
(
root_namespace
)
can?
(
current_user
,
:admin_namespace
,
root_namespace
)
&&
user_cap_reached?
(
root_namespac
e
)
can?
(
current_user
,
:admin_namespace
,
root_namespace
)
&&
root_namespace
.
user_cap_reached?
(
use_cache:
tru
e
)
end
def
hide_user_cap_alert_cookie_id
(
root_namespace
)
...
...
@@ -22,11 +22,5 @@ module EE
def
alert_has_been_dismissed?
(
root_namespace
)
cookies
[
hide_user_cap_alert_cookie_id
(
root_namespace
)]
==
'true'
end
def
user_cap_reached?
(
root_namespace
)
Rails
.
cache
.
fetch
(
root_namespace
.
namespace_user_cap_reached_cache_key
,
expires_in:
2
.
hours
)
do
root_namespace
.
user_cap_reached?
end
end
end
end
ee/app/models/ee/group.rb
View file @
371024f5
...
...
@@ -14,6 +14,11 @@ module EE
include
InsightsFeature
include
HasWiki
include
CanMoveRepositoryStorage
include
ReactiveCaching
self
.
reactive_cache_work_type
=
:no_dependency
self
.
reactive_cache_refresh_interval
=
10
.
minutes
self
.
reactive_cache_lifetime
=
1
.
hour
add_authentication_token_field
:saml_discovery_token
,
unique:
false
,
token_generator:
->
{
Devise
.
friendly_token
(
8
)
}
...
...
@@ -305,6 +310,16 @@ module EE
project
end
def
calculate_reactive_cache
billable_members_count
end
def
billable_members_count_with_reactive_cache
with_reactive_cache
do
|
return_value
|
return_value
end
end
override
:billable_members_count
def
billable_members_count
(
requested_hosted_plan
=
nil
)
billable_ids
=
billed_user_ids
(
requested_hosted_plan
)
...
...
@@ -481,17 +496,16 @@ module EE
::
Feature
.
enabled?
(
:iteration_cadences
,
self
,
default_enabled: :yaml
)
end
def
user_cap_reached?
def
user_cap_reached?
(
use_cache:
false
)
return
false
unless
::
Feature
.
enabled?
(
:saas_user_caps
,
root_ancestor
,
default_enabled: :yaml
)
user_cap
=
root_ancestor
.
namespace_settings
&
.
new_user_signups_cap
return
false
unless
user_cap
user_cap
<=
root_ancestor
.
billable_members_count
end
members_count
=
use_cache
?
root_ancestor
.
billable_members_count_with_reactive_cache
:
root_ancestor
.
billable_members_count
return
false
unless
members_count
def
namespace_user_cap_reached_cache_key
"namespace_user_cap_reached:
#{
root_ancestor
.
id
}
"
user_cap
<=
members_count
end
private
...
...
ee/app/models/ee/member.rb
View file @
371024f5
...
...
@@ -30,8 +30,6 @@ module EE
before_create
:set_membership_activation
after_commit
:invalidate_namespace_user_cap_cache
scope
:with_csv_entity_associations
,
->
do
includes
(
:user
,
source:
[
:route
,
:parent
])
end
...
...
@@ -151,11 +149,5 @@ module EE
self
.
state
=
group
.
user_cap_reached?
?
STATE_AWAITING
:
STATE_ACTIVE
end
def
invalidate_namespace_user_cap_cache
return
unless
group
&&
::
Feature
.
enabled?
(
:saas_user_caps
,
group
.
root_ancestor
,
default_enabled: :yaml
)
Rails
.
cache
.
delete
(
group
.
namespace_user_cap_reached_cache_key
)
end
end
end
ee/spec/features/namespace_user_cap_reached_alert_spec.rb
View file @
371024f5
...
...
@@ -2,7 +2,9 @@
require
'spec_helper'
RSpec
.
describe
'Namespace user cap reached alert'
,
:feature
,
:js
do
RSpec
.
describe
'Namespace user cap reached alert'
,
:feature
,
:js
,
:use_clean_rails_memory_store_caching
do
include
ReactiveCachingHelpers
let_it_be
(
:group
,
refind:
true
)
do
create
(
:group
,
:public
,
namespace_settings:
create
(
:namespace_settings
,
new_user_signups_cap:
2
))
...
...
@@ -21,6 +23,10 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
end
context
'with an exceeded user cap'
do
before
do
stub_cache
(
group
)
end
it
'displays the banner to a group owner'
do
sign_in
(
owner
)
visit
group_path
(
group
)
...
...
@@ -101,6 +107,7 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
other_group
=
create
(
:group
,
:public
,
namespace_settings:
create
(
:namespace_settings
,
new_user_signups_cap:
1
))
other_group
.
add_owner
(
owner
)
stub_cache
(
other_group
)
sign_in
(
owner
)
visit
group_path
(
group
)
dismiss_button
.
click
...
...
@@ -121,11 +128,21 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
expect_group_page_for
(
group
)
expect_banner_to_be_absent
end
it
'does not display the banner to a group owner on a reactive cache miss'
do
stub_reactive_cache
(
group
,
nil
)
sign_in
(
owner
)
visit
group_path
(
group
)
expect_group_page_for
(
group
)
expect_banner_to_be_absent
end
end
context
'with a user cap that has not been exceeded'
do
before
do
group
.
namespace_settings
.
update!
(
new_user_signups_cap:
4
)
stub_cache
(
group
)
end
it
'does not display the banner to a group owner'
do
...
...
@@ -140,6 +157,7 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
context
'without a user cap set'
do
before
do
group
.
namespace_settings
.
update!
(
new_user_signups_cap:
nil
)
stub_cache
(
group
)
end
it
'does not display the banner to a group owner'
do
...
...
@@ -184,4 +202,10 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
def
expect_banner_to_be_absent
expect
(
page
).
not_to
have_text
'Your group has reached its billable member limit'
end
def
stub_cache
(
group
)
group_with_fresh_memoization
=
Group
.
find
(
group
.
id
)
result
=
group_with_fresh_memoization
.
calculate_reactive_cache
stub_reactive_cache
(
group
,
result
)
end
end
ee/spec/helpers/ee/namespace_user_cap_reached_alert_helper_spec.rb
View file @
371024f5
...
...
@@ -2,7 +2,9 @@
require
'spec_helper'
RSpec
.
describe
EE
::
NamespaceUserCapReachedAlertHelper
do
RSpec
.
describe
EE
::
NamespaceUserCapReachedAlertHelper
,
:use_clean_rails_memory_store_caching
do
include
ReactiveCachingHelpers
describe
'#display_namespace_user_cap_reached_alert?'
do
let_it_be
(
:group
,
refind:
true
)
do
create
(
:group
,
:public
,
...
...
@@ -21,6 +23,7 @@ RSpec.describe EE::NamespaceUserCapReachedAlertHelper do
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
)
stub_cache
(
group
)
end
it
'returns true when the user cap is reached for a user who can admin the namespace'
do
...
...
@@ -35,24 +38,23 @@ RSpec.describe EE::NamespaceUserCapReachedAlertHelper do
expect
(
helper
.
display_namespace_user_cap_reached_alert?
(
group
)).
to
be
false
end
it
'caches the result'
do
sign_in
(
owner
)
expect
(
Rails
.
cache
).
to
receive
(
:fetch
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
,
expires_in:
2
.
hours
)
helper
.
display_namespace_user_cap_reached_alert?
(
group
)
end
it
'does not trigger reactive caching if there is no user cap set'
do
group
.
namespace_settings
.
update!
(
new_user_signups_cap:
nil
)
it
'caches the result for a subgroup'
do
sign_in
(
owner
)
expect
(
Rails
.
cache
).
to
receive
(
:fetch
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
,
expires_in:
2
.
hours
)
helper
.
display_namespace_user_cap_reached_alert?
(
subgroup
)
expect
(
group
).
not_to
receive
(
:with_reactive_cache
)
expect
(
helper
.
display_namespace_user_cap_reached_alert?
(
group
)).
to
be
false
end
def
sign_in
(
user
)
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
def
stub_cache
(
group
)
group_with_fresh_memoization
=
Group
.
find
(
group
.
id
)
result
=
group_with_fresh_memoization
.
calculate_reactive_cache
stub_reactive_cache
(
group
,
result
)
end
end
end
ee/spec/models/member_spec.rb
View file @
371024f5
...
...
@@ -245,80 +245,4 @@ RSpec.describe Member, type: :model do
end
end
end
describe
'#invalidate_namespace_user_cap_cache'
do
let_it_be
(
:other_user
)
{
create
(
:user
)
}
context
'when the :saas_user_caps feature flag is enabled for the root group'
do
before
do
stub_feature_flags
(
saas_user_caps:
group
)
end
it
'invalidates the namespace user cap reached cache when adding a member to a group'
do
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
group
.
add_developer
(
other_user
)
end
it
'invalidates the cache when adding a member to a subgroup'
do
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
sub_group
.
add_developer
(
other_user
)
end
it
'invalidates the cache when adding a member to a project'
do
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
project
.
add_developer
(
other_user
)
end
it
'invalidates the cache when removing a member from a group'
do
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
member
.
destroy!
end
it
'invalidates the cache when removing a member from a project'
do
project_member
=
project
.
add_developer
(
other_user
)
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
project_member
.
destroy!
end
it
'invalidates the cache when changing the access level'
do
guest_member
=
create
(
:group_member
,
:guest
,
group:
group
,
user:
other_user
)
expect
(
Rails
.
cache
).
to
receive
(
:delete
).
with
(
"namespace_user_cap_reached:
#{
group
.
id
}
"
)
guest_member
.
update!
(
access_level:
GroupMember
::
DEVELOPER
)
end
end
context
'when the :saas_user_caps feature flag is globally enabled'
do
before
do
stub_feature_flags
(
saas_user_caps:
true
)
end
it
'does not try to invalidate the cache for a project with a user namespace'
do
project_owner
=
create
(
:user
)
personal_project
=
create
(
:project
,
namespace:
project_owner
.
namespace
)
expect
(
Rails
.
cache
).
not_to
receive
(
:delete
)
personal_project
.
add_developer
(
other_user
)
end
end
context
'when the :saas_user_caps feature flag is disabled'
do
before
do
stub_feature_flags
(
saas_user_caps:
false
)
end
it
'does not invalidate the namespace user cap reached cache'
do
expect
(
Rails
.
cache
).
not_to
receive
(
:delete
)
group
.
add_developer
(
other_user
)
end
end
end
end
ee/spec/views/shared/_namespace_user_cap_reached_alert.html.haml_spec.rb
View file @
371024f5
...
...
@@ -2,7 +2,9 @@
require
'spec_helper'
RSpec
.
describe
'shared/namespace_user_cap_reached_alert'
do
RSpec
.
describe
'shared/namespace_user_cap_reached_alert'
,
:use_clean_rails_memory_store_caching
do
include
ReactiveCachingHelpers
let_it_be
(
:group
,
refind:
true
)
{
create
(
:group
,
namespace_settings:
create
(
:namespace_settings
,
new_user_signups_cap:
1
))
}
let_it_be
(
:subgroup
)
{
create
(
:group
,
parent:
group
)
}
let_it_be
(
:other_group
)
{
create
(
:group
,
namespace_settings:
create
(
:namespace_settings
,
new_user_signups_cap:
1
))
}
...
...
@@ -18,6 +20,8 @@ RSpec.describe 'shared/namespace_user_cap_reached_alert' do
before
do
allow
(
view
).
to
receive
(
:current_user
).
and_return
(
owner
)
stub_cache
(
group
)
stub_cache
(
other_group
)
end
it
'renders a link to pending user approvals'
do
...
...
@@ -44,4 +48,10 @@ RSpec.describe 'shared/namespace_user_cap_reached_alert' do
expect
(
rendered
).
to
have_link
(
'View pending user approvals'
,
href:
usage_quotas_path
(
project
.
namespace
,
anchor:
'seats-quota-tab'
))
end
def
stub_cache
(
group
)
group_with_fresh_memoization
=
Group
.
find
(
group
.
id
)
result
=
group_with_fresh_memoization
.
calculate_reactive_cache
stub_reactive_cache
(
group
,
result
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment