diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 10:34:06 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 10:34:06 +0000 |
commit | 859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch) | |
tree | d7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /spec/frontend/notifications/components/custom_notifications_modal_spec.js | |
parent | 446d496a6d000c73a304be52587cd9bbc7493136 (diff) | |
download | gitlab-ce-d39b3c02b13d72f95c637f625368b472075cc038.tar.gz |
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'spec/frontend/notifications/components/custom_notifications_modal_spec.js')
-rw-r--r-- | spec/frontend/notifications/components/custom_notifications_modal_spec.js | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/spec/frontend/notifications/components/custom_notifications_modal_spec.js b/spec/frontend/notifications/components/custom_notifications_modal_spec.js new file mode 100644 index 00000000000..3e87f3107bd --- /dev/null +++ b/spec/frontend/notifications/components/custom_notifications_modal_spec.js @@ -0,0 +1,267 @@ +import { GlSprintf, GlModal, GlFormGroup, GlFormCheckbox, GlLoadingIcon } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import httpStatus from '~/lib/utils/http_status'; +import CustomNotificationsModal from '~/notifications/components/custom_notifications_modal.vue'; +import { i18n } from '~/notifications/constants'; + +const mockNotificationSettingsResponses = { + default: { + level: 'custom', + events: { + new_release: true, + new_note: false, + }, + }, + updated: { + level: 'custom', + events: { + new_release: true, + new_note: true, + }, + }, +}; + +const mockToastShow = jest.fn(); + +describe('CustomNotificationsModal', () => { + let wrapper; + let mockAxios; + + function createComponent(options = {}) { + const { injectedProperties = {}, props = {} } = options; + return extendedWrapper( + shallowMount(CustomNotificationsModal, { + props: { + ...props, + }, + provide: { + ...injectedProperties, + }, + mocks: { + $toast: { + show: mockToastShow, + }, + }, + stubs: { + GlModal, + GlFormGroup, + GlFormCheckbox, + }, + }), + ); + } + + const findModalBodyDescription = () => wrapper.find(GlSprintf); + const findAllCheckboxes = () => wrapper.findAll(GlFormCheckbox); + const findCheckboxAt = (index) => findAllCheckboxes().at(index); + + beforeEach(() => { + gon.api_version = 'v4'; + mockAxios = new MockAdapter(axios); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + mockAxios.restore(); + }); + + describe('template', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + it('displays the body title and the body message', () => { + expect(wrapper.findByTestId('modalBodyTitle').text()).toBe( + i18n.customNotificationsModal.bodyTitle, + ); + expect(findModalBodyDescription().attributes('message')).toContain( + i18n.customNotificationsModal.bodyMessage, + ); + }); + + describe('checkbox items', () => { + beforeEach(async () => { + wrapper = createComponent(); + + wrapper.setData({ + events: [ + { id: 'new_release', enabled: true, name: 'New release', loading: false }, + { id: 'new_note', enabled: false, name: 'New note', loading: true }, + ], + }); + + await wrapper.vm.$nextTick(); + }); + + it.each` + index | eventId | eventName | enabled | loading + ${0} | ${'new_release'} | ${'New release'} | ${true} | ${false} + ${1} | ${'new_note'} | ${'New note'} | ${false} | ${true} + `( + 'renders a checkbox for "$eventName" with checked=$enabled', + async ({ index, eventName, enabled, loading }) => { + const checkbox = findCheckboxAt(index); + expect(checkbox.text()).toContain(eventName); + expect(checkbox.vm.$attrs.checked).toBe(enabled); + expect(checkbox.find(GlLoadingIcon).exists()).toBe(loading); + }, + ); + }); + }); + + describe('API calls', () => { + describe('load notification settings', () => { + beforeEach(() => { + jest.spyOn(axios, 'get'); + }); + + it.each` + projectId | groupId | endpointUrl | notificationType | condition + ${1} | ${null} | ${'/api/v4/projects/1/notification_settings'} | ${'project'} | ${'a projectId is given'} + ${null} | ${1} | ${'/api/v4/groups/1/notification_settings'} | ${'group'} | ${'a groupId is given'} + ${null} | ${null} | ${'/api/v4/notification_settings'} | ${'global'} | ${'neither projectId nor groupId are given'} + `( + 'requests $notificationType notification settings when $condition', + async ({ projectId, groupId, endpointUrl }) => { + const injectedProperties = { + projectId, + groupId, + }; + + mockAxios + .onGet(endpointUrl) + .reply(httpStatus.OK, mockNotificationSettingsResponses.default); + + wrapper = createComponent({ injectedProperties }); + + wrapper.find(GlModal).vm.$emit('show'); + + await waitForPromises(); + + expect(axios.get).toHaveBeenCalledWith(endpointUrl); + }, + ); + + it('updates the loading state and the events property', async () => { + const endpointUrl = '/api/v4/notification_settings'; + + mockAxios + .onGet(endpointUrl) + .reply(httpStatus.OK, mockNotificationSettingsResponses.default); + + wrapper = createComponent(); + + wrapper.find(GlModal).vm.$emit('show'); + expect(wrapper.vm.isLoading).toBe(true); + + await waitForPromises(); + + expect(axios.get).toHaveBeenCalledWith(endpointUrl); + expect(wrapper.vm.isLoading).toBe(false); + expect(wrapper.vm.events).toEqual([ + { id: 'new_release', enabled: true, name: 'New release', loading: false }, + { id: 'new_note', enabled: false, name: 'New note', loading: false }, + ]); + }); + + it('shows a toast message when the request fails', async () => { + mockAxios.onGet('/api/v4/notification_settings').reply(httpStatus.NOT_FOUND, {}); + wrapper = createComponent(); + + wrapper.find(GlModal).vm.$emit('show'); + + await waitForPromises(); + + expect( + mockToastShow, + ).toHaveBeenCalledWith( + 'An error occured while loading the notification settings. Please try again.', + { type: 'error' }, + ); + }); + }); + + describe('update notification settings', () => { + beforeEach(() => { + jest.spyOn(axios, 'put'); + }); + + it.each` + projectId | groupId | endpointUrl | notificationType | condition + ${1} | ${null} | ${'/api/v4/projects/1/notification_settings'} | ${'project'} | ${'a projectId is given'} + ${null} | ${1} | ${'/api/v4/groups/1/notification_settings'} | ${'group'} | ${'a groupId is given'} + ${null} | ${null} | ${'/api/v4/notification_settings'} | ${'global'} | ${'neither projectId nor groupId are given'} + `( + 'updates the $notificationType notification settings when $condition and the user clicks the checkbox ', + async ({ projectId, groupId, endpointUrl }) => { + mockAxios + .onGet(endpointUrl) + .reply(httpStatus.OK, mockNotificationSettingsResponses.default); + + mockAxios + .onPut(endpointUrl) + .reply(httpStatus.OK, mockNotificationSettingsResponses.updated); + + const injectedProperties = { + projectId, + groupId, + }; + + wrapper = createComponent({ injectedProperties }); + + wrapper.setData({ + events: [ + { id: 'new_release', enabled: true, name: 'New release', loading: false }, + { id: 'new_note', enabled: false, name: 'New note', loading: false }, + ], + }); + + await wrapper.vm.$nextTick(); + + findCheckboxAt(1).vm.$emit('change', true); + + await waitForPromises(); + + expect(axios.put).toHaveBeenCalledWith(endpointUrl, { + new_note: true, + }); + + expect(wrapper.vm.events).toEqual([ + { id: 'new_release', enabled: true, name: 'New release', loading: false }, + { id: 'new_note', enabled: true, name: 'New note', loading: false }, + ]); + }, + ); + + it('shows a toast message when the request fails', async () => { + mockAxios.onPut('/api/v4/notification_settings').reply(httpStatus.NOT_FOUND, {}); + wrapper = createComponent(); + + wrapper.setData({ + events: [ + { id: 'new_release', enabled: true, name: 'New release', loading: false }, + { id: 'new_note', enabled: false, name: 'New note', loading: false }, + ], + }); + + await wrapper.vm.$nextTick(); + + findCheckboxAt(1).vm.$emit('change', true); + + await waitForPromises(); + + expect( + mockToastShow, + ).toHaveBeenCalledWith( + 'An error occured while updating the notification settings. Please try again.', + { type: 'error' }, + ); + }); + }); + }); +}); |