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.js495
1 files changed, 157 insertions, 338 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 3ab89b3dff2..15a366474e4 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -1,28 +1,19 @@
-import {
- GlDropdown,
- GlDropdownItem,
- GlDatepicker,
- GlFormGroup,
- GlSprintf,
- GlLink,
- GlModal,
-} from '@gitlab/ui';
+import { GlLink, GlModal, GlSprintf } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
import ExperimentTracking from '~/experimentation/experiment_tracking';
import InviteMembersModal from '~/invite_members/components/invite_members_modal.vue';
+import InviteModalBase from '~/invite_members/components/invite_modal_base.vue';
import ModalConfetti from '~/invite_members/components/confetti.vue';
import MembersTokenSelect from '~/invite_members/components/members_token_select.vue';
import {
INVITE_MEMBERS_FOR_TASK,
- CANCEL_BUTTON_TEXT,
- INVITE_BUTTON_TEXT,
MEMBERS_MODAL_CELEBRATE_INTRO,
MEMBERS_MODAL_CELEBRATE_TITLE,
- MEMBERS_MODAL_DEFAULT_TITLE,
MEMBERS_PLACEHOLDER,
MEMBERS_TO_PROJECT_CELEBRATE_INTRO_TEXT,
LEARN_GITLAB,
@@ -32,9 +23,16 @@ import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import { getParameterValues } from '~/lib/utils/url_utility';
import { apiPaths, membersApiResponse, invitationsApiResponse } from '../mock_data/api_responses';
-
-let wrapper;
-let mock;
+import {
+ propsData,
+ inviteSource,
+ newProjectPath,
+ user1,
+ user2,
+ user3,
+ user4,
+ GlEmoji,
+} from '../mock_data/member_modal';
jest.mock('~/experimentation/experiment_tracking');
jest.mock('~/lib/utils/url_utility', () => ({
@@ -42,211 +40,125 @@ jest.mock('~/lib/utils/url_utility', () => ({
getParameterValues: jest.fn(() => []),
}));
-const id = '1';
-const name = 'test name';
-const isProject = false;
-const inviteeType = 'members';
-const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 };
-const defaultAccessLevel = 10;
-const inviteSource = 'unknown';
-const helpLink = 'https://example.com';
-const tasksToBeDoneOptions = [
- { text: 'First task', value: 'first' },
- { text: 'Second task', value: 'second' },
-];
-const newProjectPath = 'projects/new';
-const projects = [
- { text: 'First project', value: '1' },
- { text: 'Second project', value: '2' },
-];
-
-const user1 = { id: 1, name: 'Name One', username: 'one_1', avatar_url: '' };
-const user2 = { id: 2, name: 'Name Two', username: 'one_2', avatar_url: '' };
-const user3 = {
- id: 'user-defined-token',
- name: 'email@example.com',
- username: 'one_2',
- avatar_url: '',
-};
-const user4 = {
- id: 'user-defined-token',
- name: 'email4@example.com',
- username: 'one_4',
- avatar_url: '',
-};
-const sharedGroup = { id: '981' };
-const GlEmoji = { template: '<img/>' };
-
-const createComponent = (data = {}, props = {}) => {
- wrapper = shallowMountExtended(InviteMembersModal, {
- provide: {
- newProjectPath,
- },
- propsData: {
- id,
- name,
- isProject,
- inviteeType,
- accessLevels,
- defaultAccessLevel,
- tasksToBeDoneOptions,
- projects,
- helpLink,
- ...props,
- },
- data() {
- return data;
- },
- stubs: {
- GlModal: stubComponent(GlModal, {
- template:
- '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>',
- }),
- GlDropdown: true,
- GlDropdownItem: true,
- GlEmoji,
- GlSprintf,
- GlFormGroup: stubComponent(GlFormGroup, {
- props: ['state', 'invalidFeedback', 'description'],
- }),
- },
- });
-};
-
-const createInviteMembersToProjectWrapper = () => {
- createComponent({ inviteeType: 'members' }, { isProject: true });
-};
-
-const createInviteMembersToGroupWrapper = () => {
- createComponent({ inviteeType: 'members' }, { isProject: false });
-};
+describe('InviteMembersModal', () => {
+ let wrapper;
+ let mock;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(InviteMembersModal, {
+ provide: {
+ newProjectPath,
+ },
+ propsData: {
+ ...propsData,
+ ...props,
+ },
+ stubs: {
+ InviteModalBase,
+ GlSprintf,
+ GlModal: stubComponent(GlModal, {
+ template: '<div><slot></slot><slot name="modal-footer"></slot></div>',
+ }),
+ GlEmoji,
+ },
+ });
+ };
-const createInviteGroupToProjectWrapper = () => {
- createComponent({ inviteeType: 'group' }, { isProject: true });
-};
+ const createInviteMembersToProjectWrapper = () => {
+ createComponent({ isProject: true });
+ };
-const createInviteGroupToGroupWrapper = () => {
- createComponent({ inviteeType: 'group' }, { isProject: false });
-};
+ const createInviteMembersToGroupWrapper = () => {
+ createComponent({ isProject: false });
+ };
-beforeEach(() => {
- gon.api_version = 'v4';
- mock = new MockAdapter(axios);
-});
+ beforeEach(() => {
+ gon.api_version = 'v4';
+ mock = new MockAdapter(axios);
+ });
-afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- mock.restore();
-});
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ mock.restore();
+ });
-describe('InviteMembersModal', () => {
- const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findDropdownItems = () => findDropdown().findAllComponents(GlDropdownItem);
- const findDatepicker = () => wrapper.findComponent(GlDatepicker);
- const findLink = () => wrapper.findComponent(GlLink);
- const findIntroText = () => wrapper.find({ ref: 'introText' }).text();
+ const findBase = () => wrapper.findComponent(InviteModalBase);
+ const findIntroText = () => wrapper.findByTestId('modal-base-intro-text').text();
const findCancelButton = () => wrapper.findByTestId('cancel-button');
const findInviteButton = () => wrapper.findByTestId('invite-button');
const clickInviteButton = () => findInviteButton().vm.$emit('click');
const clickCancelButton = () => findCancelButton().vm.$emit('click');
const findMembersFormGroup = () => wrapper.findByTestId('members-form-group');
- const membersFormGroupInvalidFeedback = () => findMembersFormGroup().props('invalidFeedback');
- const membersFormGroupDescription = () => findMembersFormGroup().props('description');
+ const membersFormGroupInvalidFeedback = () =>
+ findMembersFormGroup().attributes('invalid-feedback');
+ const membersFormGroupDescription = () => findMembersFormGroup().attributes('description');
const findMembersSelect = () => wrapper.findComponent(MembersTokenSelect);
const findTasksToBeDone = () => wrapper.findByTestId('invite-members-modal-tasks-to-be-done');
const findTasks = () => wrapper.findByTestId('invite-members-modal-tasks');
const findProjectSelect = () => wrapper.findByTestId('invite-members-modal-project-select');
const findNoProjectsAlert = () => wrapper.findByTestId('invite-members-modal-no-projects-alert');
- const findCelebrationEmoji = () => wrapper.findComponent(GlModal).find(GlEmoji);
-
- describe('rendering the modal', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders the modal with the correct title', () => {
- expect(wrapper.findComponent(GlModal).props('title')).toBe(MEMBERS_MODAL_DEFAULT_TITLE);
- });
-
- it('renders the Cancel button text correctly', () => {
- expect(findCancelButton().text()).toBe(CANCEL_BUTTON_TEXT);
- });
-
- it('renders the Invite button text correctly', () => {
- expect(findInviteButton().text()).toBe(INVITE_BUTTON_TEXT);
- });
-
- it('renders the Invite button modal without isLoading', () => {
- expect(findInviteButton().props('loading')).toBe(false);
- });
-
- describe('rendering the access levels dropdown', () => {
- it('sets the default dropdown text to the default access level name', () => {
- expect(findDropdown().attributes('text')).toBe('Guest');
- });
-
- it('renders dropdown items for each accessLevel', () => {
- expect(findDropdownItems()).toHaveLength(5);
- });
- });
-
- describe('rendering the help link', () => {
- it('renders the correct link', () => {
- expect(findLink().attributes('href')).toBe(helpLink);
- });
- });
-
- describe('rendering the access expiration date field', () => {
- it('renders the datepicker', () => {
- expect(findDatepicker().exists()).toBe(true);
- });
- });
- });
+ const findCelebrationEmoji = () => wrapper.findComponent(GlEmoji);
+ const triggerOpenModal = async ({ mode = 'default', source }) => {
+ eventHub.$emit('openModal', { mode, source });
+ await nextTick();
+ };
+ const triggerMembersTokenSelect = async (val) => {
+ findMembersSelect().vm.$emit('input', val);
+ await nextTick();
+ };
+ const triggerTasks = async (val) => {
+ findTasks().vm.$emit('input', val);
+ await nextTick();
+ };
+ const triggerAccessLevel = async (val) => {
+ findBase().vm.$emit('access-level', val);
+ await nextTick();
+ };
describe('rendering the tasks to be done', () => {
- const setupComponent = (
- extraData = {},
- props = {},
- urlParameter = ['invite_members_for_task'],
- ) => {
- const data = {
- selectedAccessLevel: 30,
- selectedTasksToBeDone: ['ci', 'code'],
- ...extraData,
- };
+ const setupComponent = async (props = {}, urlParameter = ['invite_members_for_task']) => {
getParameterValues.mockImplementation(() => urlParameter);
- createComponent(data, props);
+ createComponent(props);
+
+ await triggerAccessLevel(30);
+ };
+
+ const setupComponentWithTasks = async (...args) => {
+ await setupComponent(...args);
+ await triggerTasks(['ci', 'code']);
};
afterAll(() => {
getParameterValues.mockImplementation(() => []);
});
- it('renders the tasks to be done', () => {
- setupComponent();
+ it('renders the tasks to be done', async () => {
+ await setupComponent();
expect(findTasksToBeDone().exists()).toBe(true);
});
describe('when the selected access level is lower than 30', () => {
- it('does not render the tasks to be done', () => {
- setupComponent({ selectedAccessLevel: 20 });
+ it('does not render the tasks to be done', async () => {
+ await setupComponent();
+ await triggerAccessLevel(20);
expect(findTasksToBeDone().exists()).toBe(false);
});
});
describe('when the url does not contain the parameter `open_modal=invite_members_for_task`', () => {
- it('does not render the tasks to be done', () => {
- setupComponent({}, {}, []);
+ it('does not render the tasks to be done', async () => {
+ await setupComponent({}, []);
expect(findTasksToBeDone().exists()).toBe(false);
});
describe('when opened from the Learn GitLab page', () => {
- it('does render the tasks to be done', () => {
- setupComponent({ source: LEARN_GITLAB }, {}, []);
+ it('does render the tasks to be done', async () => {
+ await setupComponent({}, []);
+ await triggerOpenModal({ source: LEARN_GITLAB });
expect(findTasksToBeDone().exists()).toBe(true);
});
@@ -254,27 +166,27 @@ describe('InviteMembersModal', () => {
});
describe('rendering the tasks', () => {
- it('renders the tasks', () => {
- setupComponent();
+ it('renders the tasks', async () => {
+ await setupComponent();
expect(findTasks().exists()).toBe(true);
});
- it('does not render an alert', () => {
- setupComponent();
+ it('does not render an alert', async () => {
+ await setupComponent();
expect(findNoProjectsAlert().exists()).toBe(false);
});
describe('when there are no projects passed in the data', () => {
- it('does not render the tasks', () => {
- setupComponent({}, { projects: [] });
+ it('does not render the tasks', async () => {
+ await setupComponent({ projects: [] });
expect(findTasks().exists()).toBe(false);
});
- it('renders an alert with a link to the new projects path', () => {
- setupComponent({}, { projects: [] });
+ it('renders an alert with a link to the new projects path', async () => {
+ await setupComponent({ projects: [] });
expect(findNoProjectsAlert().exists()).toBe(true);
expect(findNoProjectsAlert().findComponent(GlLink).attributes('href')).toBe(
@@ -285,23 +197,23 @@ describe('InviteMembersModal', () => {
});
describe('rendering the project dropdown', () => {
- it('renders the project select', () => {
- setupComponent();
+ it('renders the project select', async () => {
+ await setupComponentWithTasks();
expect(findProjectSelect().exists()).toBe(true);
});
describe('when the modal is shown for a project', () => {
- it('does not render the project select', () => {
- setupComponent({}, { isProject: true });
+ it('does not render the project select', async () => {
+ await setupComponentWithTasks({ isProject: true });
expect(findProjectSelect().exists()).toBe(false);
});
});
describe('when no tasks are selected', () => {
- it('does not render the project select', () => {
- setupComponent({ selectedTasksToBeDone: [] });
+ it('does not render the project select', async () => {
+ await setupComponent();
expect(findProjectSelect().exists()).toBe(false);
});
@@ -309,8 +221,8 @@ describe('InviteMembersModal', () => {
});
describe('tracking events', () => {
- it('tracks the view for invite_members_for_task', () => {
- setupComponent();
+ it('tracks the view for invite_members_for_task', async () => {
+ await setupComponentWithTasks();
expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name);
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
@@ -318,8 +230,8 @@ describe('InviteMembersModal', () => {
);
});
- it('tracks the submit for invite_members_for_task', () => {
- setupComponent();
+ it('tracks the submit for invite_members_for_task', async () => {
+ await setupComponentWithTasks();
clickInviteButton();
expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name, {
@@ -352,8 +264,9 @@ describe('InviteMembersModal', () => {
});
describe('when inviting members with celebration', () => {
- beforeEach(() => {
- createComponent({ mode: 'celebrate', inviteeType: 'members' }, { isProject: true });
+ beforeEach(async () => {
+ createComponent({ isProject: true });
+ await triggerOpenModal({ mode: 'celebrate' });
});
it('renders the modal with confetti', () => {
@@ -372,34 +285,14 @@ describe('InviteMembersModal', () => {
expect(membersFormGroupDescription()).toBe(MEMBERS_PLACEHOLDER);
});
});
-
- describe('when sharing with a group', () => {
- it('includes the correct invitee, type, and formatted name', () => {
- createInviteGroupToProjectWrapper();
-
- expect(findIntroText()).toBe("You're inviting a group to the test name project.");
- expect(membersFormGroupDescription()).toBe('');
- });
- });
});
describe('when inviting to a group', () => {
- describe('when inviting members', () => {
- it('includes the correct invitee, type, and formatted name', () => {
- createInviteMembersToGroupWrapper();
-
- expect(findIntroText()).toBe("You're inviting members to the test name group.");
- expect(membersFormGroupDescription()).toBe(MEMBERS_PLACEHOLDER);
- });
- });
-
- describe('when sharing with a group', () => {
- it('includes the correct invitee, type, and formatted name', () => {
- createInviteGroupToGroupWrapper();
+ it('includes the correct invitee, type, and formatted name', () => {
+ createInviteMembersToGroupWrapper();
- expect(findIntroText()).toBe("You're inviting a group to the test name group.");
- expect(membersFormGroupDescription()).toBe('');
- });
+ expect(findIntroText()).toBe("You're inviting members to the test name group.");
+ expect(membersFormGroupDescription()).toBe(MEMBERS_PLACEHOLDER);
});
});
});
@@ -419,7 +312,7 @@ describe('InviteMembersModal', () => {
describe('when inviting an existing user to group by user ID', () => {
const postData = {
user_id: '1,2',
- access_level: defaultAccessLevel,
+ access_level: propsData.defaultAccessLevel,
expires_at: undefined,
invite_source: inviteSource,
format: 'json',
@@ -428,8 +321,9 @@ describe('InviteMembersModal', () => {
};
describe('when member is added successfully', () => {
- beforeEach(() => {
- createComponent({ newUsersToInvite: [user1, user2] });
+ beforeEach(async () => {
+ createComponent();
+ await triggerMembersTokenSelect([user1, user2]);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData });
@@ -445,19 +339,17 @@ describe('InviteMembersModal', () => {
});
it('calls Api addGroupMembersByUserId with the correct params', () => {
- expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, postData);
+ expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(propsData.id, postData);
});
it('displays the successful toastMessage', () => {
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added', {
- onComplete: expect.any(Function),
- });
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added');
});
});
describe('when opened from a Learn GitLab page', () => {
it('emits the `showSuccessfulInvitationsAlert` event', async () => {
- eventHub.$emit('openModal', { inviteeType: 'members', source: LEARN_GITLAB });
+ await triggerOpenModal({ source: LEARN_GITLAB });
jest.spyOn(eventHub, '$emit').mockImplementation();
@@ -471,12 +363,10 @@ describe('InviteMembersModal', () => {
});
describe('when member is not added successfully', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createInviteMembersToGroupWrapper();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ newUsersToInvite: [user1] });
+ await triggerMembersTokenSelect([user1]);
});
it('displays "Member already exists" api message for http status conflict', async () => {
@@ -487,7 +377,6 @@ describe('InviteMembersModal', () => {
await waitForPromises();
expect(membersFormGroupInvalidFeedback()).toBe('Member already exists');
- expect(findMembersFormGroup().props('state')).toBe(false);
expect(findMembersSelect().props('validationState')).toBe(false);
expect(findInviteButton().props('loading')).toBe(false);
});
@@ -503,35 +392,31 @@ describe('InviteMembersModal', () => {
it('clears the error when the list of members to invite is cleared', async () => {
expect(membersFormGroupInvalidFeedback()).toBe('Member already exists');
- expect(findMembersFormGroup().props('state')).toBe(false);
expect(findMembersSelect().props('validationState')).toBe(false);
findMembersSelect().vm.$emit('clear');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
- expect(findMembersFormGroup().props('state')).not.toBe(false);
expect(findMembersSelect().props('validationState')).not.toBe(false);
});
it('clears the error when the cancel button is clicked', async () => {
clickCancelButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
- expect(findMembersFormGroup().props('state')).not.toBe(false);
expect(findMembersSelect().props('validationState')).not.toBe(false);
});
it('clears the error when the modal is hidden', async () => {
wrapper.findComponent(GlModal).vm.$emit('hide');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
- expect(findMembersFormGroup().props('state')).not.toBe(false);
expect(findMembersSelect().props('validationState')).not.toBe(false);
});
});
@@ -544,7 +429,6 @@ describe('InviteMembersModal', () => {
await waitForPromises();
expect(membersFormGroupInvalidFeedback()).toBe('Member already exists');
- expect(findMembersFormGroup().props('state')).toBe(false);
expect(findMembersSelect().props('validationState')).toBe(false);
expect(findInviteButton().props('loading')).toBe(false);
@@ -553,8 +437,7 @@ describe('InviteMembersModal', () => {
await waitForPromises();
expect(membersFormGroupInvalidFeedback()).toBe('');
- expect(findMembersFormGroup().props('state')).not.toBe(false);
- expect(findMembersSelect().props('validationState')).not.toBe(false);
+ expect(findMembersSelect().props('validationState')).toBe(null);
expect(findInviteButton().props('loading')).toBe(false);
});
@@ -608,7 +491,7 @@ describe('InviteMembersModal', () => {
describe('when inviting a new user by email address', () => {
const postData = {
- access_level: defaultAccessLevel,
+ access_level: propsData.defaultAccessLevel,
expires_at: undefined,
email: 'email@example.com',
invite_source: inviteSource,
@@ -618,8 +501,9 @@ describe('InviteMembersModal', () => {
};
describe('when invites are sent successfully', () => {
- beforeEach(() => {
- createComponent({ newUsersToInvite: [user3] });
+ beforeEach(async () => {
+ createComponent();
+ await triggerMembersTokenSelect([user3]);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData });
@@ -631,24 +515,20 @@ describe('InviteMembersModal', () => {
});
it('calls Api inviteGroupMembersByEmail with the correct params', () => {
- expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, postData);
+ expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(propsData.id, postData);
});
it('displays the successful toastMessage', () => {
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added', {
- onComplete: expect.any(Function),
- });
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added');
});
});
});
describe('when invites are not sent successfully', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createInviteMembersToGroupWrapper();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ newUsersToInvite: [user3] });
+ await triggerMembersTokenSelect([user3]);
});
it('displays the api error for invalid email syntax', async () => {
@@ -683,9 +563,7 @@ describe('InviteMembersModal', () => {
await waitForPromises();
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added', {
- onComplete: expect.any(Function),
- });
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added');
expect(findMembersSelect().props('validationState')).toBe(null);
});
@@ -716,9 +594,7 @@ describe('InviteMembersModal', () => {
it('displays the invalid syntax error if one of the emails is invalid', async () => {
createInviteMembersToGroupWrapper();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ newUsersToInvite: [user3, user4] });
+ await triggerMembersTokenSelect([user3, user4]);
mockInvitationsApi(httpStatus.CREATED, invitationsApiResponse.ERROR_EMAIL_INVALID);
clickInviteButton();
@@ -733,7 +609,7 @@ describe('InviteMembersModal', () => {
describe('when inviting members and non-members in same click', () => {
const postData = {
- access_level: defaultAccessLevel,
+ access_level: propsData.defaultAccessLevel,
expires_at: undefined,
invite_source: inviteSource,
format: 'json',
@@ -745,8 +621,9 @@ describe('InviteMembersModal', () => {
const idPostData = { ...postData, user_id: '1' };
describe('when invites are sent successfully', () => {
- beforeEach(() => {
- createComponent({ newUsersToInvite: [user1, user3] });
+ beforeEach(async () => {
+ createComponent();
+ await triggerMembersTokenSelect([user1, user3]);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData });
@@ -759,30 +636,28 @@ describe('InviteMembersModal', () => {
});
it('calls Api inviteGroupMembersByEmail with the correct params', () => {
- expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, emailPostData);
+ expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(propsData.id, emailPostData);
});
it('calls Api addGroupMembersByUserId with the correct params', () => {
- expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, idPostData);
+ expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(propsData.id, idPostData);
});
it('displays the successful toastMessage', () => {
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added', {
- onComplete: expect.any(Function),
- });
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added');
});
});
- it('calls Apis with the invite source passed through to openModal', () => {
- eventHub.$emit('openModal', { inviteeType: 'members', source: '_invite_source_' });
+ it('calls Apis with the invite source passed through to openModal', async () => {
+ await triggerOpenModal({ source: '_invite_source_' });
clickInviteButton();
- expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, {
+ expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(propsData.id, {
...emailPostData,
invite_source: '_invite_source_',
});
- expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, {
+ expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(propsData.id, {
...idPostData,
invite_source: '_invite_source_',
});
@@ -790,12 +665,10 @@ describe('InviteMembersModal', () => {
});
describe('when any invite failed for any reason', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createInviteMembersToGroupWrapper();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ newUsersToInvite: [user1, user3] });
+ await triggerMembersTokenSelect([user1, user3]);
mockInvitationsApi(httpStatus.BAD_REQUEST, invitationsApiResponse.EMAIL_INVALID);
mockMembersApi(httpStatus.OK, '200 OK');
@@ -811,71 +684,17 @@ describe('InviteMembersModal', () => {
});
});
- describe('when inviting a group to share', () => {
- describe('when sharing the group is successful', () => {
- const groupPostData = {
- group_id: sharedGroup.id,
- group_access: defaultAccessLevel,
- expires_at: undefined,
- format: 'json',
- };
-
- beforeEach(() => {
- createComponent({ groupToBeSharedWith: sharedGroup });
-
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ inviteeType: 'group' });
- wrapper.vm.$toast = { show: jest.fn() };
- jest.spyOn(Api, 'groupShareWithGroup').mockResolvedValue({ data: groupPostData });
-
- clickInviteButton();
- });
-
- it('calls Api groupShareWithGroup with the correct params', () => {
- expect(Api.groupShareWithGroup).toHaveBeenCalledWith(id, groupPostData);
- });
-
- it('displays the successful toastMessage', () => {
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('Members were successfully added', {
- onComplete: expect.any(Function),
- });
- });
- });
-
- describe('when sharing the group fails', () => {
- beforeEach(() => {
- createInviteGroupToGroupWrapper();
-
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ groupToBeSharedWith: sharedGroup });
- wrapper.vm.$toast = { show: jest.fn() };
-
- jest
- .spyOn(Api, 'groupShareWithGroup')
- .mockRejectedValue({ response: { data: { success: false } } });
-
- clickInviteButton();
- });
-
- it('displays the generic error message', () => {
- expect(membersFormGroupInvalidFeedback()).toBe('Something went wrong');
- expect(membersFormGroupDescription()).toBe('');
- });
- });
- });
-
describe('tracking', () => {
- beforeEach(() => {
- createComponent({ newUsersToInvite: [user3] });
+ beforeEach(async () => {
+ createComponent();
+ await triggerMembersTokenSelect([user3]);
wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({});
});
it('tracks the view for learn_gitlab source', () => {
- eventHub.$emit('openModal', { inviteeType: 'members', source: LEARN_GITLAB });
+ eventHub.$emit('openModal', { source: LEARN_GITLAB });
expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name);
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(LEARN_GITLAB);