diff options
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.js | 227 |
1 files changed, 174 insertions, 53 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 4ac2a28105c..fc039bdf6da 100644 --- a/spec/frontend/invite_members/components/invite_members_modal_spec.js +++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js @@ -1,5 +1,7 @@ import { shallowMount } from '@vue/test-utils'; -import { GlDropdown, GlDropdownItem, GlDatepicker, GlSprintf, GlLink } from '@gitlab/ui'; +import { GlDropdown, GlDropdownItem, GlDatepicker, GlSprintf, GlLink, GlModal } from '@gitlab/ui'; +import { stubComponent } from 'helpers/stub_component'; +import waitForPromises from 'helpers/wait_for_promises'; import Api from '~/api'; import InviteMembersModal from '~/invite_members/components/invite_members_modal.vue'; @@ -10,6 +12,15 @@ const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, O const defaultAccessLevel = '10'; const helpLink = 'https://example.com'; +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 createComponent = (data = {}) => { return shallowMount(InviteMembersModal, { propsData: { @@ -24,9 +35,12 @@ const createComponent = (data = {}) => { return data; }, stubs: { - 'gl-modal': '<div><slot name="modal-footer"></slot><slot></slot></div>', - 'gl-dropdown': true, - 'gl-dropdown-item': true, + GlModal: stubComponent(GlModal, { + template: + '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>', + }), + GlDropdown: true, + GlDropdownItem: true, GlSprintf, }, }); @@ -46,6 +60,7 @@ describe('InviteMembersModal', () => { const findLink = () => wrapper.find(GlLink); const findCancelButton = () => wrapper.find({ ref: 'cancelButton' }); const findInviteButton = () => wrapper.find({ ref: 'inviteButton' }); + const clickInviteButton = () => findInviteButton().vm.$emit('click'); describe('rendering the modal', () => { beforeEach(() => { @@ -53,7 +68,7 @@ describe('InviteMembersModal', () => { }); it('renders the modal with the correct title', () => { - expect(wrapper.attributes('title')).toBe('Invite team members'); + expect(wrapper.find(GlModal).props('title')).toBe('Invite team members'); }); it('renders the Cancel button text correctly', () => { @@ -88,78 +103,184 @@ describe('InviteMembersModal', () => { }); describe('submitting the invite form', () => { - const postData = { - user_id: '1', - access_level: '10', - expires_at: new Date(), - format: 'json', - }; + const apiErrorMessage = 'Member already exists'; + + describe('when inviting an existing user to group by user ID', () => { + const postData = { + user_id: '1', + access_level: '10', + expires_at: undefined, + format: 'json', + }; + + describe('when invites are sent successfully', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1] }); - describe('when the invite was sent successfully', () => { - beforeEach(() => { - wrapper = createComponent(); + wrapper.vm.$toast = { show: jest.fn() }; + jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData }); + jest.spyOn(wrapper.vm, 'showToastMessageSuccess'); - wrapper.vm.$toast = { show: jest.fn() }; - jest.spyOn(Api, 'inviteGroupMember').mockResolvedValue({ data: postData }); + clickInviteButton(); + }); - wrapper.vm.submitForm(postData); + it('calls Api addGroupMembersByUserId with the correct params', () => { + expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, postData); + }); + + it('displays the successful toastMessage', () => { + expect(wrapper.vm.showToastMessageSuccess).toHaveBeenCalled(); + }); }); - it('displays the successful toastMessage', () => { - const toastMessageSuccessful = 'Members were successfully added'; + describe('when the invite received an api error message', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1] }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest + .spyOn(Api, 'addGroupMembersByUserId') + .mockRejectedValue({ response: { data: { message: apiErrorMessage } } }); + jest.spyOn(wrapper.vm, 'showToastMessageError'); + + clickInviteButton(); + }); - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( - toastMessageSuccessful, - wrapper.vm.toastOptions, - ); + it('displays the apiErrorMessage in the toastMessage', async () => { + await waitForPromises(); + + expect(wrapper.vm.showToastMessageError).toHaveBeenCalledWith({ + response: { data: { message: apiErrorMessage } }, + }); + }); }); - it('calls Api inviteGroupMember with the correct params', () => { - expect(Api.inviteGroupMember).toHaveBeenCalledWith(id, postData); + describe('when any invite failed for any other reason', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1, user2] }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest + .spyOn(Api, 'addGroupMembersByUserId') + .mockRejectedValue({ response: { data: { success: false } } }); + jest.spyOn(wrapper.vm, 'showToastMessageError'); + + clickInviteButton(); + }); + + it('displays the generic error toastMessage', async () => { + await waitForPromises(); + + expect(wrapper.vm.showToastMessageError).toHaveBeenCalled(); + }); }); }); - describe('when sending the invite for a single member returned an api error', () => { - const apiErrorMessage = 'Members already exists'; + describe('when inviting a new user by email address', () => { + const postData = { + access_level: '10', + expires_at: undefined, + email: 'email@example.com', + format: 'json', + }; + + describe('when invites are sent successfully', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user3] }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData }); + jest.spyOn(wrapper.vm, 'showToastMessageSuccess'); - beforeEach(() => { - wrapper = createComponent({ newUsersToInvite: '123' }); + clickInviteButton(); + }); - wrapper.vm.$toast = { show: jest.fn() }; - jest - .spyOn(Api, 'inviteGroupMember') - .mockRejectedValue({ response: { data: { message: apiErrorMessage } } }); + it('calls Api inviteGroupMembersByEmail with the correct params', () => { + expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, postData); + }); - findInviteButton().vm.$emit('click'); + it('displays the successful toastMessage', () => { + expect(wrapper.vm.showToastMessageSuccess).toHaveBeenCalled(); + }); }); - it('displays the api error message for the toastMessage', () => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( - apiErrorMessage, - wrapper.vm.toastOptions, - ); + describe('when any invite failed for any reason', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1, user2] }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest + .spyOn(Api, 'addGroupMembersByUserId') + .mockRejectedValue({ response: { data: { success: false } } }); + jest.spyOn(wrapper.vm, 'showToastMessageError'); + + clickInviteButton(); + }); + + it('displays the generic error toastMessage', async () => { + await waitForPromises(); + + expect(wrapper.vm.showToastMessageError).toHaveBeenCalled(); + }); }); }); - describe('when sending the invite for multiple members returned any error', () => { - const genericErrorMessage = 'Some of the members could not be added'; + describe('when inviting members and non-members in same click', () => { + const postData = { + access_level: '10', + expires_at: undefined, + format: 'json', + }; + + const emailPostData = { ...postData, email: 'email@example.com' }; + const idPostData = { ...postData, user_id: '1' }; + + describe('when invites are sent successfully', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1, user3] }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData }); + jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData }); + jest.spyOn(wrapper.vm, 'showToastMessageSuccess'); - beforeEach(() => { - wrapper = createComponent({ newUsersToInvite: '123' }); + clickInviteButton(); + }); - wrapper.vm.$toast = { show: jest.fn() }; - jest - .spyOn(Api, 'inviteGroupMember') - .mockRejectedValue({ response: { data: { success: false } } }); + it('calls Api inviteGroupMembersByEmail with the correct params', () => { + expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, emailPostData); + }); - findInviteButton().vm.$emit('click'); + it('calls Api addGroupMembersByUserId with the correct params', () => { + expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, idPostData); + }); + + it('displays the successful toastMessage', () => { + expect(wrapper.vm.showToastMessageSuccess).toHaveBeenCalled(); + }); }); - it('displays the expected toastMessage', () => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( - genericErrorMessage, - wrapper.vm.toastOptions, - ); + describe('when any invite failed for any reason', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: [user1, user3] }); + + wrapper.vm.$toast = { show: jest.fn() }; + + jest + .spyOn(Api, 'inviteGroupMembersByEmail') + .mockRejectedValue({ response: { data: { success: false } } }); + + jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData }); + jest.spyOn(wrapper.vm, 'showToastMessageError'); + + clickInviteButton(); + }); + + it('displays the generic error toastMessage', async () => { + await waitForPromises(); + + expect(wrapper.vm.showToastMessageError).toHaveBeenCalled(); + }); }); }); }); |