Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/google_tag_manager/index_spec.js')
-rw-r--r--spec/frontend/google_tag_manager/index_spec.js259
1 files changed, 259 insertions, 0 deletions
diff --git a/spec/frontend/google_tag_manager/index_spec.js b/spec/frontend/google_tag_manager/index_spec.js
new file mode 100644
index 00000000000..ff38de28da6
--- /dev/null
+++ b/spec/frontend/google_tag_manager/index_spec.js
@@ -0,0 +1,259 @@
+import { merge } from 'lodash';
+import {
+ trackFreeTrialAccountSubmissions,
+ trackNewRegistrations,
+ trackSaasTrialSubmit,
+ trackSaasTrialSkip,
+ trackSaasTrialGroup,
+ trackSaasTrialProject,
+ trackSaasTrialProjectImport,
+ trackSaasTrialGetStarted,
+} from '~/google_tag_manager';
+import { setHTMLFixture } from 'helpers/fixtures';
+import { logError } from '~/lib/logger';
+
+jest.mock('~/lib/logger');
+
+describe('~/google_tag_manager/index', () => {
+ let spy;
+
+ beforeEach(() => {
+ spy = jest.fn();
+
+ window.dataLayer = {
+ push: spy,
+ };
+ window.gon.features = {
+ gitlabGtmDatalayer: true,
+ };
+ });
+
+ const createHTML = ({ links = [], forms = [] } = {}) => {
+ // .foo elements are used to test elements which shouldn't do anything
+ const allLinks = links.concat({ cls: 'foo' });
+ const allForms = forms.concat({ cls: 'foo' });
+
+ const el = document.createElement('div');
+
+ allLinks.forEach(({ cls = '', id = '', href = '#', text = 'Hello', attributes = {} }) => {
+ const a = document.createElement('a');
+ a.id = id;
+ a.href = href || '#';
+ a.className = cls;
+ a.textContent = text;
+
+ Object.entries(attributes).forEach(([key, value]) => {
+ a.setAttribute(key, value);
+ });
+
+ el.append(a);
+ });
+
+ allForms.forEach(({ cls = '', id = '' }) => {
+ const form = document.createElement('form');
+ form.id = id;
+ form.className = cls;
+
+ el.append(form);
+ });
+
+ return el.innerHTML;
+ };
+
+ const triggerEvent = (selector, eventType) => {
+ const el = document.querySelector(selector);
+
+ el.dispatchEvent(new Event(eventType));
+ };
+
+ const getSelector = ({ id, cls }) => (id ? `#${id}` : `.${cls}`);
+
+ const createTestCase = (subject, { forms = [], links = [] }) => {
+ const expectedFormEvents = forms.map(({ expectation, ...form }) => ({
+ selector: getSelector(form),
+ trigger: 'submit',
+ expectation,
+ }));
+
+ const expectedLinkEvents = links.map(({ expectation, ...link }) => ({
+ selector: getSelector(link),
+ trigger: 'click',
+ expectation,
+ }));
+
+ return [
+ subject,
+ {
+ forms,
+ links,
+ expectedEvents: [...expectedFormEvents, ...expectedLinkEvents],
+ },
+ ];
+ };
+
+ const createOmniAuthTestCase = (subject, accountType) =>
+ createTestCase(subject, {
+ forms: [
+ {
+ id: 'new_new_user',
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'form',
+ accountType,
+ },
+ },
+ ],
+ links: [
+ {
+ // id is needed so that the test selects the right element to trigger
+ id: 'test-0',
+ cls: 'js-oauth-login',
+ attributes: {
+ 'data-provider': 'myspace',
+ },
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'myspace',
+ accountType,
+ },
+ },
+ {
+ id: 'test-1',
+ cls: 'js-oauth-login',
+ attributes: {
+ 'data-provider': 'gitlab',
+ },
+ expectation: {
+ event: 'accountSubmit',
+ accountMethod: 'gitlab',
+ accountType,
+ },
+ },
+ ],
+ });
+
+ describe.each([
+ createOmniAuthTestCase(trackFreeTrialAccountSubmissions, 'freeThirtyDayTrial'),
+ createOmniAuthTestCase(trackNewRegistrations, 'standardSignUp'),
+ createTestCase(trackSaasTrialSkip, {
+ links: [{ cls: 'js-skip-trial', expectation: { event: 'saasTrialSkip' } }],
+ }),
+ createTestCase(trackSaasTrialGroup, {
+ forms: [{ cls: 'js-saas-trial-group', expectation: { event: 'saasTrialGroup' } }],
+ }),
+ createTestCase(trackSaasTrialProject, {
+ forms: [{ id: 'new_project', expectation: { event: 'saasTrialProject' } }],
+ }),
+ createTestCase(trackSaasTrialProjectImport, {
+ links: [
+ {
+ id: 'js-test-btn-0',
+ cls: 'js-import-project-btn',
+ attributes: { 'data-platform': 'bitbucket' },
+ expectation: { event: 'saasTrialProjectImport', saasProjectImport: 'bitbucket' },
+ },
+ {
+ // id is neeeded so we trigger the right element in the test
+ id: 'js-test-btn-1',
+ cls: 'js-import-project-btn',
+ attributes: { 'data-platform': 'github' },
+ expectation: { event: 'saasTrialProjectImport', saasProjectImport: 'github' },
+ },
+ ],
+ }),
+ createTestCase(trackSaasTrialGetStarted, {
+ links: [
+ {
+ cls: 'js-get-started-btn',
+ expectation: { event: 'saasTrialGetStarted' },
+ },
+ ],
+ }),
+ ])('%p', (subject, { links = [], forms = [], expectedEvents }) => {
+ beforeEach(() => {
+ setHTMLFixture(createHTML({ links, forms }));
+
+ subject();
+ });
+
+ it.each(expectedEvents)('when %p', ({ selector, trigger, expectation }) => {
+ expect(spy).not.toHaveBeenCalled();
+
+ triggerEvent(selector, trigger);
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith(expectation);
+ expect(logError).not.toHaveBeenCalled();
+ });
+
+ it('when random link is clicked, does nothing', () => {
+ triggerEvent('a.foo', 'click');
+
+ expect(spy).not.toHaveBeenCalled();
+ });
+
+ it('when random form is submitted, does nothing', () => {
+ triggerEvent('form.foo', 'submit');
+
+ expect(spy).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('No listener events', () => {
+ it('when trackSaasTrialSubmit is invoked', () => {
+ expect(spy).not.toHaveBeenCalled();
+
+ trackSaasTrialSubmit();
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith({ event: 'saasTrialSubmit' });
+ expect(logError).not.toHaveBeenCalled();
+ });
+ });
+
+ describe.each([
+ { dataLayer: null },
+ { gon: { features: null } },
+ { gon: { features: { gitlabGtmDatalayer: false } } },
+ ])('when window %o', (windowAttrs) => {
+ beforeEach(() => {
+ merge(window, windowAttrs);
+ });
+
+ it('no ops', () => {
+ setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] }));
+
+ trackSaasTrialProject();
+
+ triggerEvent('#new_project', 'submit');
+
+ expect(spy).not.toHaveBeenCalled();
+ expect(logError).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when window.dataLayer throws error', () => {
+ const pushError = new Error('test');
+
+ beforeEach(() => {
+ window.dataLayer = {
+ push() {
+ throw pushError;
+ },
+ };
+ });
+
+ it('logs error', () => {
+ setHTMLFixture(createHTML({ forms: [{ id: 'new_project' }] }));
+
+ trackSaasTrialProject();
+
+ triggerEvent('#new_project', 'submit');
+
+ expect(logError).toHaveBeenCalledWith(
+ 'Unexpected error while pushing to dataLayer',
+ pushError,
+ );
+ });
+ });
+});