Commit 74bd49b1 authored by Jason Goodman's avatar Jason Goodman Committed by Etienne Baqué

Make User Cap Reached Banner Dismissible

parent eb09de51
...@@ -2,9 +2,11 @@ import 'bootstrap/js/dist/modal'; ...@@ -2,9 +2,11 @@ import 'bootstrap/js/dist/modal';
import initEETrialBanner from 'ee/ee_trial_banner'; import initEETrialBanner from 'ee/ee_trial_banner';
import trackNavbarEvents from 'ee/event_tracking/navbar'; import trackNavbarEvents from 'ee/event_tracking/navbar';
import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert'; import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert';
import initNamespaceUserCapReachedAlert from 'ee/namespace_user_cap_reached_alert';
// EE specific calls // EE specific calls
initEETrialBanner(); initEETrialBanner();
initNamespaceStorageLimitAlert(); initNamespaceStorageLimitAlert();
initNamespaceUserCapReachedAlert();
trackNavbarEvents(); trackNavbarEvents();
import Cookies from 'js-cookie';
const handleOnDismiss = ({ currentTarget }) => {
const {
dataset: { cookieId },
} = currentTarget;
Cookies.set(cookieId, true, { expires: 30 });
};
export default () => {
const alert = document.querySelector('.js-namespace-user-cap-alert-dismiss');
if (alert) {
alert.addEventListener('click', handleOnDismiss);
}
};
...@@ -8,11 +8,21 @@ module EE ...@@ -8,11 +8,21 @@ module EE
return false if root_namespace.user_namespace? return false if root_namespace.user_namespace?
return false if alert_has_been_dismissed?(root_namespace)
can?(current_user, :admin_namespace, root_namespace) && user_cap_reached?(root_namespace) can?(current_user, :admin_namespace, root_namespace) && user_cap_reached?(root_namespace)
end end
def hide_user_cap_alert_cookie_id(root_namespace)
"hide_user_cap_alert_#{root_namespace.id}"
end
private private
def alert_has_been_dismissed?(root_namespace)
cookies[hide_user_cap_alert_cookie_id(root_namespace)] == 'true'
end
def user_cap_reached?(root_namespace) def user_cap_reached?(root_namespace)
Rails.cache.fetch("namespace_user_cap_reached:#{root_namespace.id}", expires_in: 2.hours) do Rails.cache.fetch("namespace_user_cap_reached:#{root_namespace.id}", expires_in: 2.hours) do
root_namespace.user_cap_reached? root_namespace.user_cap_reached?
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
.gl-alert-title .gl-alert-title
%h4.gl-alert-title= s_('NamespaceUserCap|Your group has reached its billable member limit') %h4.gl-alert-title= s_('NamespaceUserCap|Your group has reached its billable member limit')
%button.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss'), data: { level: :warning } } %button.js-namespace-user-cap-alert-dismiss.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss'), data: { cookie_id: hide_user_cap_alert_cookie_id(root_namespace), level: :warning, testid: 'namespace_user_cap_alert_dismiss' } }
= sprite_icon('close', css_class: 'gl-icon') = sprite_icon('close', css_class: 'gl-icon')
.gl-alert-body .gl-alert-body
......
...@@ -25,21 +25,24 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do ...@@ -25,21 +25,24 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
sign_in(owner) sign_in(owner)
visit group_path(group) visit group_path(group)
expect(page).to have_text 'Your group has reached its billable member limit' expect_group_page_for(group)
expect_banner_to_be_present
end end
it 'displays the banner to a group owner on a subgroup page' do it 'displays the banner to a group owner on a subgroup page' do
sign_in(owner) sign_in(owner)
visit group_path(subgroup) visit group_path(subgroup)
expect(page).to have_text 'Your group has reached its billable member limit' expect_group_page_for(subgroup)
expect_banner_to_be_present
end end
it 'displays the banner to a group owner on a project page' do it 'displays the banner to a group owner on a project page' do
sign_in(owner) sign_in(owner)
visit project_path(project) visit project_path(project)
expect(page).to have_text 'Your group has reached its billable member limit' expect_project_page_for(project)
expect_banner_to_be_present
end end
it 'does not display the banner when the feature flag is off' do it 'does not display the banner when the feature flag is off' do
...@@ -47,27 +50,76 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do ...@@ -47,27 +50,76 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
sign_in(owner) sign_in(owner)
visit group_path(group) visit group_path(group)
expect_banner_to_be_absent(group) expect_group_page_for(group)
expect_banner_to_be_absent
end end
it 'does not display the banner to a user who is not a group owner' do it 'does not display the banner to a user who is not a group owner' do
sign_in(developer) sign_in(developer)
visit group_path(group) visit group_path(group)
expect_banner_to_be_absent(group) expect_group_page_for(group)
expect_banner_to_be_absent
end end
it 'does not display the banner to a user who owns a subgroup' do it 'does not display the banner to a user who owns a subgroup' do
sign_in(subgroup_owner) sign_in(subgroup_owner)
visit group_path(subgroup) visit group_path(subgroup)
expect_banner_to_be_absent(subgroup) expect_group_page_for(subgroup)
expect_banner_to_be_absent
end end
it 'does not display the banner to an unauthenticated user' do it 'does not display the banner to an unauthenticated user' do
visit group_path(group) visit group_path(group)
expect_banner_to_be_absent(group) expect_group_page_for(group)
expect_banner_to_be_absent
end
it 'can be dismissed' do
sign_in(owner)
visit group_path(group)
dismiss_button.click
expect_group_page_for(group)
expect_banner_to_be_absent
end
it 'remains dismissed' do
sign_in(owner)
visit group_path(group)
dismiss_button.click
visit group_path(group)
expect_group_page_for(group)
expect_banner_to_be_absent
end
it 'is dismissed independently for each root group' do
other_group = create(:group, :public,
namespace_settings: create(:namespace_settings, new_user_signups_cap: 1))
other_group.add_owner(owner)
sign_in(owner)
visit group_path(group)
dismiss_button.click
visit group_path(other_group)
expect_group_page_for(other_group)
expect_banner_to_be_present
end
it 'is dismissed for a root group when dismissed from a subgroup' do
sign_in(owner)
visit group_path(subgroup)
dismiss_button.click
visit group_path(group)
expect_group_page_for(group)
expect_banner_to_be_absent
end end
end end
...@@ -80,7 +132,8 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do ...@@ -80,7 +132,8 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
sign_in(owner) sign_in(owner)
visit group_path(group) visit group_path(group)
expect_banner_to_be_absent(group) expect_group_page_for(group)
expect_banner_to_be_absent
end end
end end
...@@ -93,7 +146,8 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do ...@@ -93,7 +146,8 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
sign_in(owner) sign_in(owner)
visit group_path(group) visit group_path(group)
expect_banner_to_be_absent(group) expect_group_page_for(group)
expect_banner_to_be_absent
end end
end end
...@@ -104,15 +158,30 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do ...@@ -104,15 +158,30 @@ RSpec.describe 'Namespace user cap reached alert', :feature, :js do
sign_in(owner) sign_in(owner)
visit project_path(personal_project) visit project_path(personal_project)
expect(page).to have_text owner.name expect_project_page_for(personal_project)
expect(page).to have_text personal_project.name expect_banner_to_be_absent
expect(page).not_to have_text 'Your group has reached its billable member limit'
end end
end end
def expect_banner_to_be_absent(group) def dismiss_button
find('button[data-testid="namespace_user_cap_alert_dismiss"]')
end
def expect_group_page_for(group)
expect(page).to have_text group.name expect(page).to have_text group.name
expect(page).to have_text "Group ID: #{group.id}" expect(page).to have_text "Group ID: #{group.id}"
end
def expect_project_page_for(project)
expect(page).to have_text project.namespace.name
expect(page).to have_text project.name
end
def expect_banner_to_be_present
expect(page).to have_text 'Your group has reached its billable member limit'
end
def expect_banner_to_be_absent
expect(page).not_to have_text 'Your group has reached its billable member limit' expect(page).not_to have_text 'Your group has reached its billable member limit'
end end
end end
import Cookies from 'js-cookie';
import initNamespaceUserCapReachedAlert from 'ee/namespace_user_cap_reached_alert';
describe('dismissing the alert', () => {
const clickDismissButton = () => {
const button = document.querySelector('.js-namespace-user-cap-alert-dismiss');
button.click();
};
beforeEach(() => {
setFixtures(`
<div class="js-namespace-user-cap-alert">
<button class="js-namespace-user-cap-alert-dismiss" data-cookie-id="hide_user_cap_alert_1" data-level="info"></button>
</div>
`);
initNamespaceUserCapReachedAlert();
});
it('sets the banner to be hidden for thirty days', () => {
jest.spyOn(Cookies, 'set');
clickDismissButton();
expect(Cookies.set).toHaveBeenCalledWith('hide_user_cap_alert_1', true, { expires: 30 });
});
});
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