summaryrefslogtreecommitdiff
path: root/spec/frontend/notifications/components/custom_notifications_modal_spec.js
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 10:34:06 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 10:34:06 +0000
commit859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch)
treed7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /spec/frontend/notifications/components/custom_notifications_modal_spec.js
parent446d496a6d000c73a304be52587cd9bbc7493136 (diff)
downloadgitlab-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.js267
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' },
+ );
+ });
+ });
+ });
+});