Commit 711a1342 authored by Dallas Reedy's avatar Dallas Reedy

Add structured event tracking to the Security upgrade banner

- Track when the banner is rendered (mounted)
- Track when the banner is closed (dismissed)
- Track when the banner CTA is clicked
- Update associated tests
parent 1fc9595b
<script> <script>
import { GlBanner } from '@gitlab/ui'; import { GlBanner } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import Tracking from '~/tracking';
export const SECURITY_UPGRADE_BANNER = 'security_upgrade_banner';
export const UPGRADE_OR_FREE_TRIAL = 'upgrade_or_free_trial';
export default { export default {
components: { components: {
GlBanner, GlBanner,
}, },
mixins: [Tracking.mixin({ property: SECURITY_UPGRADE_BANNER })],
inject: ['upgradePath'], inject: ['upgradePath'],
i18n: { i18n: {
title: s__('SecurityConfiguration|Secure your project'), title: s__('SecurityConfiguration|Secure your project'),
...@@ -22,6 +27,17 @@ export default { ...@@ -22,6 +27,17 @@ export default {
], ],
buttonText: s__('SecurityConfiguration|Upgrade or start a free trial'), buttonText: s__('SecurityConfiguration|Upgrade or start a free trial'),
}, },
mounted() {
this.track('display_banner', { label: SECURITY_UPGRADE_BANNER });
},
methods: {
bannerClosed() {
this.track('dismiss_banner', { label: SECURITY_UPGRADE_BANNER });
},
bannerButtonClicked() {
this.track('click_button', { label: UPGRADE_OR_FREE_TRIAL });
},
},
}; };
</script> </script>
...@@ -31,6 +47,8 @@ export default { ...@@ -31,6 +47,8 @@ export default {
:button-text="$options.i18n.buttonText" :button-text="$options.i18n.buttonText"
:button-link="upgradePath" :button-link="upgradePath"
variant="introduction" variant="introduction"
@close="bannerClosed"
@primary="bannerButtonClicked"
v-on="$listeners" v-on="$listeners"
> >
<p>{{ $options.i18n.bodyStart }}</p> <p>{{ $options.i18n.bodyStart }}</p>
......
import { GlBanner } from '@gitlab/ui'; import { GlBanner } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import UpgradeBanner from '~/security_configuration/components/upgrade_banner.vue'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import UpgradeBanner, {
SECURITY_UPGRADE_BANNER,
UPGRADE_OR_FREE_TRIAL,
} from '~/security_configuration/components/upgrade_banner.vue';
const upgradePath = '/upgrade'; const upgradePath = '/upgrade';
describe('UpgradeBanner component', () => { describe('UpgradeBanner component', () => {
let wrapper; let wrapper;
let closeSpy; let closeSpy;
let primarySpy;
let trackingSpy;
const createComponent = (propsData) => { const createComponent = (propsData) => {
closeSpy = jest.fn(); closeSpy = jest.fn();
primarySpy = jest.fn();
wrapper = shallowMountExtended(UpgradeBanner, { wrapper = shallowMountExtended(UpgradeBanner, {
provide: { provide: {
...@@ -18,18 +25,43 @@ describe('UpgradeBanner component', () => { ...@@ -18,18 +25,43 @@ describe('UpgradeBanner component', () => {
propsData, propsData,
listeners: { listeners: {
close: closeSpy, close: closeSpy,
primary: primarySpy,
}, },
}); });
}; };
const findGlBanner = () => wrapper.findComponent(GlBanner); const findGlBanner = () => wrapper.findComponent(GlBanner);
const expectTracking = (action, label) => {
return expect(trackingSpy).toHaveBeenCalledWith(undefined, action, {
label,
property: SECURITY_UPGRADE_BANNER,
});
};
beforeEach(() => { beforeEach(() => {
createComponent(); trackingSpy = mockTracking(undefined, undefined, jest.spyOn);
}); });
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
unmockTracking();
});
describe('when the component renders', () => {
it('tracks an event', () => {
expect(trackingSpy).not.toHaveBeenCalled();
createComponent();
expectTracking('display_banner', SECURITY_UPGRADE_BANNER);
});
});
describe('when ready', () => {
beforeEach(() => {
createComponent();
trackingSpy.mockClear();
}); });
it('passes the expected props to GlBanner', () => { it('passes the expected props to GlBanner', () => {
...@@ -50,11 +82,26 @@ describe('UpgradeBanner component', () => { ...@@ -50,11 +82,26 @@ describe('UpgradeBanner component', () => {
expect(wrapperText).toContain('More scan types, including Container Scanning,'); expect(wrapperText).toContain('More scan types, including Container Scanning,');
}); });
it(`re-emits GlBanner's close event`, () => { describe('when user interacts', () => {
it(`re-emits GlBanner's close event & tracks an event`, () => {
expect(closeSpy).not.toHaveBeenCalled(); expect(closeSpy).not.toHaveBeenCalled();
expect(trackingSpy).not.toHaveBeenCalled();
wrapper.findComponent(GlBanner).vm.$emit('close'); wrapper.findComponent(GlBanner).vm.$emit('close');
expect(closeSpy).toHaveBeenCalledTimes(1); expect(closeSpy).toHaveBeenCalledTimes(1);
expectTracking('dismiss_banner', SECURITY_UPGRADE_BANNER);
});
it(`re-emits GlBanner's primary event & tracks an event`, () => {
expect(primarySpy).not.toHaveBeenCalled();
expect(trackingSpy).not.toHaveBeenCalled();
wrapper.findComponent(GlBanner).vm.$emit('primary');
expect(primarySpy).toHaveBeenCalledTimes(1);
expectTracking('click_button', UPGRADE_OR_FREE_TRIAL);
});
});
}); });
}); });
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