Commit 2762b458 authored by Dave Pisek's avatar Dave Pisek

Make security training promo banner dismissible

This commit wraps the banner that shows the promotion for the
security training feature dismissible. This happens on a per-user
basis and is stored via GraphQL on the backend.
parent 63dbcadc
......@@ -40,8 +40,9 @@ module Users
profile_personal_access_token_expiry: 37, # EE-only
terraform_notification_dismissed: 38,
security_newsletter_callout: 39,
verification_reminder: 40, # EE-only
ci_deprecation_warning_for_types_keyword: 41
verification_reminder: 40, # EE-only
ci_deprecation_warning_for_types_keyword: 41,
security_training_feature_promotion: 42 # EE-only
}
validates :feature_name,
......
......@@ -17818,6 +17818,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumsecurity_configuration_devops_alert"></a>`SECURITY_CONFIGURATION_DEVOPS_ALERT` | Callout feature name for security_configuration_devops_alert. |
| <a id="usercalloutfeaturenameenumsecurity_configuration_upgrade_banner"></a>`SECURITY_CONFIGURATION_UPGRADE_BANNER` | Callout feature name for security_configuration_upgrade_banner. |
| <a id="usercalloutfeaturenameenumsecurity_newsletter_callout"></a>`SECURITY_NEWSLETTER_CALLOUT` | Callout feature name for security_newsletter_callout. |
| <a id="usercalloutfeaturenameenumsecurity_training_feature_promotion"></a>`SECURITY_TRAINING_FEATURE_PROMOTION` | Callout feature name for security_training_feature_promotion. |
| <a id="usercalloutfeaturenameenumsuggest_pipeline"></a>`SUGGEST_PIPELINE` | Callout feature name for suggest_pipeline. |
| <a id="usercalloutfeaturenameenumsuggest_popover_dismissed"></a>`SUGGEST_POPOVER_DISMISSED` | Callout feature name for suggest_popover_dismissed. |
| <a id="usercalloutfeaturenameenumtabs_position_highlight"></a>`TABS_POSITION_HIGHLIGHT` | Callout feature name for tabs_position_highlight. |
<script>
import { GlBanner } from '@gitlab/ui';
import { __ } from '~/locale';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
export default {
components: {
GlBanner,
UserCalloutDismisser,
},
inject: ['securityConfigurationPath'],
i18n: {
......@@ -23,12 +25,18 @@ export default {
</script>
<template>
<gl-banner
:title="$options.i18n.title"
:button-text="$options.i18n.buttonText"
:button-link="buttonLink"
variant="introduction"
>
<p>{{ $options.i18n.content }}</p>
</gl-banner>
<user-callout-dismisser feature-name="security_training_feature_promotion">
<template #default="{ dismiss, shouldShowCallout }">
<gl-banner
v-if="shouldShowCallout"
:title="$options.i18n.title"
:button-text="$options.i18n.buttonText"
:button-link="buttonLink"
variant="introduction"
@close="dismiss"
>
<p>{{ $options.i18n.content }}</p>
</gl-banner>
</template>
</user-callout-dismisser>
</template>
import { shallowMount } from '@vue/test-utils';
import { GlBanner } from '@gitlab/ui';
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
import SecurityTrainingPromo from 'ee/security_dashboard/components/shared/security_training_promo.vue';
const SECURITY_CONFIGURATION_PATH = 'foo/bar';
......@@ -7,18 +8,21 @@ const VULNERABILITY_MANAGEMENT_TAB_NAME = 'vulnerability-management';
describe('Security training promo component', () => {
let wrapper;
const userCalloutDismissSpy = jest.fn();
const createWrapper = () =>
const createWrapper = ({ shouldShowCallout = true } = {}) =>
shallowMount(SecurityTrainingPromo, {
provide: {
securityConfigurationPath: SECURITY_CONFIGURATION_PATH,
},
stubs: {
UserCalloutDismisser: makeMockUserCalloutDismisser({
dismiss: userCalloutDismissSpy,
shouldShowCallout,
}),
},
});
beforeEach(() => {
wrapper = createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
......@@ -26,6 +30,10 @@ describe('Security training promo component', () => {
const findBanner = () => wrapper.findComponent(GlBanner);
describe('banner', () => {
beforeEach(() => {
wrapper = createWrapper();
});
it('should be an introduction that announces the security training feature', () => {
const { title, buttonText, content } = SecurityTrainingPromo.i18n;
......@@ -43,4 +51,22 @@ describe('Security training promo component', () => {
);
});
});
describe('dismissal', () => {
it('should dismiss the callout when the banner is closed', () => {
wrapper = createWrapper();
expect(userCalloutDismissSpy).not.toHaveBeenCalled();
findBanner().vm.$emit('close');
expect(userCalloutDismissSpy).toHaveBeenCalled();
});
it('should not show the banner once it has been dismissed', () => {
wrapper = createWrapper({ shouldShowCallout: false });
expect(findBanner().exists()).toBe(false);
});
});
});
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