summaryrefslogtreecommitdiff
path: root/spec/frontend/invite_members/components/invite_members_modal_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/invite_members/components/invite_members_modal_spec.js')
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js107
1 files changed, 91 insertions, 16 deletions
diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js
index b6b34e1063b..9687d528321 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -2,6 +2,7 @@ import { GlLink, GlModal, GlSprintf, GlFormGroup, GlCollapse, GlIcon } from '@gi
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
@@ -20,6 +21,8 @@ import {
LEARN_GITLAB,
EXPANDED_ERRORS,
EMPTY_INVITES_ALERT_TEXT,
+ ON_CELEBRATION_TRACK_LABEL,
+ INVITE_MEMBER_MODAL_TRACKING_CATEGORY,
} from '~/invite_members/constants';
import eventHub from '~/invite_members/event_hub';
import ContentTransition from '~/vue_shared/components/content_transition.vue';
@@ -58,6 +61,13 @@ jest.mock('~/lib/utils/url_utility', () => ({
describe('InviteMembersModal', () => {
let wrapper;
let mock;
+ let trackingSpy;
+
+ const expectTracking = (
+ action,
+ label = undefined,
+ category = INVITE_MEMBER_MODAL_TRACKING_CATEGORY,
+ ) => expect(trackingSpy).toHaveBeenCalledWith(category, action, { label, category });
const createComponent = (props = {}, stubs = {}) => {
wrapper = shallowMountExtended(InviteMembersModal, {
@@ -66,6 +76,7 @@ describe('InviteMembersModal', () => {
},
propsData: {
usersLimitDataset: {},
+ activeTrialDataset: {},
fullPath: 'project',
...propsData,
...props,
@@ -83,12 +94,20 @@ describe('InviteMembersModal', () => {
});
};
- const createInviteMembersToProjectWrapper = (usersLimitDataset = {}, stubs = {}) => {
- createComponent({ usersLimitDataset, isProject: true }, stubs);
+ const createInviteMembersToProjectWrapper = (
+ usersLimitDataset = {},
+ activeTrialDataset = {},
+ stubs = {},
+ ) => {
+ createComponent({ usersLimitDataset, activeTrialDataset, isProject: true }, stubs);
};
- const createInviteMembersToGroupWrapper = (usersLimitDataset = {}, stubs = {}) => {
- createComponent({ usersLimitDataset, isProject: false }, stubs);
+ const createInviteMembersToGroupWrapper = (
+ usersLimitDataset = {},
+ activeTrialDataset = {},
+ stubs = {},
+ ) => {
+ createComponent({ usersLimitDataset, activeTrialDataset, isProject: false }, stubs);
};
beforeEach(() => {
@@ -129,7 +148,7 @@ describe('InviteMembersModal', () => {
const findProjectSelect = () => wrapper.findByTestId('invite-members-modal-project-select');
const findNoProjectsAlert = () => wrapper.findByTestId('invite-members-modal-no-projects-alert');
const findCelebrationEmoji = () => wrapper.findComponent(GlEmoji);
- const triggerOpenModal = async ({ mode = 'default', source }) => {
+ const triggerOpenModal = async ({ mode = 'default', source } = {}) => {
eventHub.$emit('openModal', { mode, source });
await nextTick();
};
@@ -291,7 +310,7 @@ describe('InviteMembersModal', () => {
});
});
- describe('displaying the correct introText and form group description', () => {
+ describe('rendering with tracking considerations', () => {
describe('when inviting to a project', () => {
describe('when inviting members', () => {
beforeEach(() => {
@@ -318,7 +337,7 @@ describe('InviteMembersModal', () => {
describe('when inviting members with celebration', () => {
beforeEach(async () => {
createInviteMembersToProjectWrapper();
- await triggerOpenModal({ mode: 'celebrate' });
+ await triggerOpenModal({ mode: 'celebrate', source: ON_CELEBRATION_TRACK_LABEL });
});
it('renders the modal with confetti', () => {
@@ -344,6 +363,26 @@ describe('InviteMembersModal', () => {
expect(membersFormGroupDescription()).toContain(MEMBERS_PLACEHOLDER);
});
});
+
+ describe('tracking', () => {
+ it('tracks actions', async () => {
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ const mockEvent = { preventDefault: jest.fn() };
+
+ await triggerOpenModal({ mode: 'celebrate', source: ON_CELEBRATION_TRACK_LABEL });
+
+ expectTracking('render', ON_CELEBRATION_TRACK_LABEL);
+
+ findModal().vm.$emit('cancel', mockEvent);
+ expectTracking('click_cancel', ON_CELEBRATION_TRACK_LABEL);
+
+ findModal().vm.$emit('close');
+ expectTracking('click_x', ON_CELEBRATION_TRACK_LABEL);
+
+ unmockTracking();
+ });
+ });
});
});
@@ -361,6 +400,32 @@ describe('InviteMembersModal', () => {
});
});
});
+
+ describe('tracking', () => {
+ it.each`
+ desc | source | label
+ ${'unknown'} | ${{}} | ${'unknown'}
+ ${'known'} | ${{ source: '_invite_source_' }} | ${'_invite_source_'}
+ `('tracks actions with $desc source', async ({ source, label }) => {
+ createInviteMembersToProjectWrapper();
+
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ const mockEvent = { preventDefault: jest.fn() };
+
+ await triggerOpenModal(source);
+
+ expectTracking('render', label);
+
+ findModal().vm.$emit('cancel', mockEvent);
+ expectTracking('click_cancel', label);
+
+ findModal().vm.$emit('close');
+ expectTracking('click_x', label);
+
+ unmockTracking();
+ });
+ });
});
describe('rendering the user limit notification', () => {
@@ -625,6 +690,7 @@ describe('InviteMembersModal', () => {
createComponent();
await triggerMembersTokenSelect([user3]);
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembers').mockResolvedValue({ data: postData });
});
@@ -842,17 +908,23 @@ describe('InviteMembersModal', () => {
createComponent();
await triggerMembersTokenSelect([user1, user3]);
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembers').mockResolvedValue({ data: postData });
});
describe('when triggered from regular mounting', () => {
- beforeEach(() => {
+ beforeEach(async () => {
+ await triggerOpenModal({ source: '_invite_source_' });
+
clickInviteButton();
});
- it('calls Api inviteGroupMembers with the correct params', () => {
- expect(Api.inviteGroupMembers).toHaveBeenCalledWith(propsData.id, postData);
+ it('calls Api inviteGroupMembers with the correct params and invite source', () => {
+ expect(Api.inviteGroupMembers).toHaveBeenCalledWith(propsData.id, {
+ ...postData,
+ invite_source: '_invite_source_',
+ });
});
it('displays the successful toastMessage', () => {
@@ -866,17 +938,20 @@ describe('InviteMembersModal', () => {
it('does not call reloadOnInvitationSuccess', () => {
expect(reloadOnInvitationSuccess).not.toHaveBeenCalled();
});
+
+ it('tracks successful invite when source is known', () => {
+ expectTracking('invite_successful', '_invite_source_');
+
+ unmockTracking();
+ });
});
- it('calls Apis with the invite source passed through to openModal', async () => {
- await triggerOpenModal({ source: '_invite_source_' });
+ it('calls Apis without the invite source passed through to openModal', async () => {
+ await triggerOpenModal();
clickInviteButton();
- expect(Api.inviteGroupMembers).toHaveBeenCalledWith(propsData.id, {
- ...postData,
- invite_source: '_invite_source_',
- });
+ expect(Api.inviteGroupMembers).toHaveBeenCalledWith(propsData.id, postData);
});
});
});