diff options
author | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
commit | 6438df3a1e0fb944485cebf07976160184697d72 (patch) | |
tree | 00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/frontend/projects | |
parent | 42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff) | |
download | gitlab-ce-6438df3a1e0fb944485cebf07976160184697d72.tar.gz |
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/frontend/projects')
27 files changed, 780 insertions, 188 deletions
diff --git a/spec/frontend/projects/commit/components/branches_dropdown_spec.js b/spec/frontend/projects/commit/components/branches_dropdown_spec.js new file mode 100644 index 00000000000..9fa7d658405 --- /dev/null +++ b/spec/frontend/projects/commit/components/branches_dropdown_spec.js @@ -0,0 +1,166 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import { shallowMount } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import { GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui'; +import BranchesDropdown from '~/projects/commit/components/branches_dropdown.vue'; + +Vue.use(Vuex); + +describe('BranchesDropdown', () => { + let wrapper; + let store; + const spyFetchBranches = jest.fn(); + + const createComponent = (term, state = { isFetching: false }) => { + store = new Vuex.Store({ + getters: { + joinedBranches: () => ['_master_', '_branch_1_', '_branch_2_'], + }, + actions: { + fetchBranches: spyFetchBranches, + }, + state, + }); + + wrapper = extendedWrapper( + shallowMount(BranchesDropdown, { + store, + propsData: { + value: term, + }, + }), + ); + }; + + const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); + const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType); + const findDropdownItemByIndex = (index) => wrapper.findAllComponents(GlDropdownItem).at(index); + const findNoResults = () => wrapper.findByTestId('empty-result-message'); + const findLoading = () => wrapper.findByTestId('dropdown-text-loading-icon'); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + spyFetchBranches.mockReset(); + }); + + describe('On mount', () => { + beforeEach(() => { + createComponent(''); + }); + + it('invokes fetchBranches', () => { + expect(spyFetchBranches).toHaveBeenCalled(); + }); + }); + + describe('Loading states', () => { + it('shows loading icon while fetching', () => { + createComponent('', { isFetching: true }); + + expect(findLoading().isVisible()).toBe(true); + }); + + it('does not show loading icon', () => { + createComponent(''); + + expect(findLoading().isVisible()).toBe(false); + }); + }); + + describe('No branches found', () => { + beforeEach(() => { + createComponent('_non_existent_branch_'); + }); + + it('renders empty results message', () => { + expect(findNoResults().text()).toBe('No matching results'); + }); + + it('shows GlSearchBoxByType with default attributes', () => { + expect(findSearchBoxByType().exists()).toBe(true); + expect(findSearchBoxByType().vm.$attrs).toMatchObject({ + placeholder: 'Search branches', + debounce: 250, + }); + }); + }); + + describe('Search term is empty', () => { + beforeEach(() => { + createComponent(''); + }); + + it('renders all branches when search term is empty', () => { + expect(findAllDropdownItems()).toHaveLength(3); + expect(findDropdownItemByIndex(0).text()).toBe('_master_'); + expect(findDropdownItemByIndex(1).text()).toBe('_branch_1_'); + expect(findDropdownItemByIndex(2).text()).toBe('_branch_2_'); + }); + + it('should not be selected on the inactive branch', () => { + expect(wrapper.vm.isSelected('_master_')).toBe(false); + }); + }); + + describe('When searching', () => { + beforeEach(() => { + createComponent(''); + }); + + it('invokes fetchBranches', async () => { + const spy = jest.spyOn(wrapper.vm, 'fetchBranches'); + + findSearchBoxByType().vm.$emit('input', '_anything_'); + + await wrapper.vm.$nextTick(); + + expect(spy).toHaveBeenCalledWith('_anything_'); + expect(wrapper.vm.searchTerm).toBe('_anything_'); + }); + }); + + describe('Branches found', () => { + beforeEach(() => { + createComponent('_branch_1_', { branch: '_branch_1_' }); + }); + + it('renders only the branch searched for', () => { + expect(findAllDropdownItems()).toHaveLength(1); + expect(findDropdownItemByIndex(0).text()).toBe('_branch_1_'); + }); + + it('should not display empty results message', () => { + expect(findNoResults().exists()).toBe(false); + }); + + it('should signify this branch is selected', () => { + expect(wrapper.vm.isSelected('_branch_1_')).toBe(true); + }); + + it('should signify the branch is not selected', () => { + expect(wrapper.vm.isSelected('_not_selected_branch_')).toBe(false); + }); + + describe('Custom events', () => { + it('should emit selectBranch if an branch is clicked', () => { + findDropdownItemByIndex(0).vm.$emit('click'); + + expect(wrapper.emitted('selectBranch')).toEqual([['_branch_1_']]); + expect(wrapper.vm.searchTerm).toBe('_branch_1_'); + }); + }); + }); + + describe('Case insensitive for search term', () => { + beforeEach(() => { + createComponent('_BrAnCh_1_'); + }); + + it('renders only the branch searched for', () => { + expect(findAllDropdownItems()).toHaveLength(1); + expect(findDropdownItemByIndex(0).text()).toBe('_branch_1_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/components/form_modal_spec.js b/spec/frontend/projects/commit/components/form_modal_spec.js new file mode 100644 index 00000000000..1c37b82fed3 --- /dev/null +++ b/spec/frontend/projects/commit/components/form_modal_spec.js @@ -0,0 +1,155 @@ +import MockAdapter from 'axios-mock-adapter'; +import { shallowMount, mount, createWrapper } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import { GlModal, GlForm, GlFormCheckbox, GlSprintf } from '@gitlab/ui'; +import { within } from '@testing-library/dom'; +import axios from '~/lib/utils/axios_utils'; +import eventHub from '~/projects/commit/event_hub'; +import CommitFormModal from '~/projects/commit/components/form_modal.vue'; +import BranchesDropdown from '~/projects/commit/components/branches_dropdown.vue'; +import createStore from '~/projects/commit/store'; +import mockData from '../mock_data'; + +describe('CommitFormModal', () => { + let wrapper; + let store; + let axiosMock; + + const createComponent = (method, state = {}, provide = {}) => { + store = createStore({ ...mockData.mockModal, ...state }); + wrapper = extendedWrapper( + method(CommitFormModal, { + provide, + propsData: { ...mockData.modalPropsData }, + store, + attrs: { + static: true, + visible: true, + }, + }), + ); + }; + + const findModal = () => wrapper.findComponent(GlModal); + const findStartBranch = () => wrapper.find('#start_branch'); + const findDropdown = () => wrapper.findComponent(BranchesDropdown); + const findForm = () => findModal().findComponent(GlForm); + const findCheckBox = () => findForm().findComponent(GlFormCheckbox); + const findPrependedText = () => wrapper.findByTestId('prepended-text'); + const findAppendedText = () => wrapper.findByTestId('appended-text'); + const getByText = (text, options) => + createWrapper(within(findModal().element).getByText(text, options)); + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + wrapper.destroy(); + axiosMock.restore(); + }); + + describe('Basic interactions', () => { + it('Listens for opening of modal on mount', () => { + jest.spyOn(eventHub, '$on'); + + createComponent(shallowMount); + + expect(eventHub.$on).toHaveBeenCalledWith(mockData.modalPropsData.openModal, wrapper.vm.show); + }); + + it('Shows modal', () => { + createComponent(shallowMount); + const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit'); + + wrapper.vm.show(); + + expect(rootEmit).toHaveBeenCalledWith('bv::show::modal', mockData.modalPropsData.modalId); + }); + + it('Clears the modal state once modal is hidden', () => { + createComponent(shallowMount); + jest.spyOn(store, 'dispatch').mockImplementation(); + wrapper.vm.checked = false; + + findModal().vm.$emit('hidden'); + + expect(store.dispatch).toHaveBeenCalledWith('clearModal'); + expect(store.dispatch).toHaveBeenCalledWith('setSelectedBranch', ''); + expect(wrapper.vm.checked).toBe(true); + }); + + it('Shows the checkbox for new merge request', () => { + createComponent(shallowMount); + + expect(findCheckBox().exists()).toBe(true); + }); + + it('Shows the prepended text', () => { + createComponent(shallowMount, {}, { prependedText: '_prepended_text_' }); + + expect(findPrependedText().exists()).toBe(true); + expect(findPrependedText().find(GlSprintf).attributes('message')).toBe('_prepended_text_'); + }); + + it('Does not show prepended text', () => { + createComponent(shallowMount); + + expect(findPrependedText().exists()).toBe(false); + }); + + it('Does not show extra message text', () => { + createComponent(shallowMount); + + expect(findModal().find('[data-testid="appended-text"]').exists()).toBe(false); + }); + + it('Does not show the checkbox for new merge request', () => { + createComponent(shallowMount, { pushCode: false }); + + expect(findCheckBox().exists()).toBe(false); + }); + + it('Shows the branch in fork message', () => { + createComponent(shallowMount, { pushCode: false }); + + expect(findAppendedText().exists()).toBe(true); + expect(findAppendedText().find(GlSprintf).attributes('message')).toContain( + mockData.modalPropsData.i18n.branchInFork, + ); + }); + + it('Shows the branch collaboration message', () => { + createComponent(shallowMount, { pushCode: false, branchCollaboration: true }); + + expect(findAppendedText().exists()).toBe(true); + expect(findAppendedText().find(GlSprintf).attributes('message')).toContain( + mockData.modalPropsData.i18n.existingBranch, + ); + }); + }); + + describe('Taking action on the form', () => { + beforeEach(() => { + createComponent(mount); + }); + + it('Action primary button dispatches submit action', () => { + const submitSpy = jest.spyOn(findForm().element, 'submit'); + + getByText(mockData.modalPropsData.i18n.actionPrimaryText).trigger('click'); + + expect(submitSpy).toHaveBeenCalled(); + + submitSpy.mockRestore(); + }); + + it('Changes the start_branch input value', async () => { + findDropdown().vm.$emit('selectBranch', '_changed_branch_value_'); + + await wrapper.vm.$nextTick(); + + expect(findStartBranch().attributes('value')).toBe('_changed_branch_value_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/components/form_trigger_spec.js b/spec/frontend/projects/commit/components/form_trigger_spec.js new file mode 100644 index 00000000000..ca51419d6a5 --- /dev/null +++ b/spec/frontend/projects/commit/components/form_trigger_spec.js @@ -0,0 +1,44 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLink } from '@gitlab/ui'; +import FormTrigger from '~/projects/commit/components/form_trigger.vue'; +import eventHub from '~/projects/commit/event_hub'; + +const displayText = '_display_text_'; + +const createComponent = () => { + return shallowMount(FormTrigger, { + provide: { displayText }, + propsData: { openModal: '_open_modal_' }, + }); +}; + +describe('FormTrigger', () => { + let wrapper; + let spy; + + beforeEach(() => { + spy = jest.spyOn(eventHub, '$emit'); + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findLink = () => wrapper.find(GlLink); + + describe('displayText', () => { + it('includes the correct displayText for the link', () => { + expect(findLink().text()).toBe(displayText); + }); + }); + + describe('clicking the link', () => { + it('emits openModal', () => { + findLink().vm.$emit('click'); + + expect(spy).toHaveBeenCalledWith('_open_modal_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/mock_data.js b/spec/frontend/projects/commit/mock_data.js new file mode 100644 index 00000000000..2b3b5a14c98 --- /dev/null +++ b/spec/frontend/projects/commit/mock_data.js @@ -0,0 +1,27 @@ +import { I18N_MODAL } from '~/projects/commit/constants'; + +export default { + mockModal: { + modalTitle: '_modal_title_', + endpoint: '_endpoint_', + branch: '_branch_', + pushCode: true, + defaultBranch: '_branch_', + existingBranch: '_existing_branch', + branchesEndpoint: '_branches_endpoint_', + }, + modalPropsData: { + i18n: { + branchLabel: '_branch_label_', + actionPrimaryText: '_action_primary_text_', + startMergeRequest: '_start_merge_request_', + existingBranch: I18N_MODAL.existingBranch, + branchInFork: '_new_branch_in_fork_message_', + newMergeRequest: '_new merge request_', + actionCancelText: '_action_cancel_text_', + }, + modalId: '_modal_id_', + openModal: '_open_modal_', + }, + mockBranches: ['_branch_1', '_abc_', '_master_'], +}; diff --git a/spec/frontend/projects/commit/store/actions_spec.js b/spec/frontend/projects/commit/store/actions_spec.js new file mode 100644 index 00000000000..ec528d4ee88 --- /dev/null +++ b/spec/frontend/projects/commit/store/actions_spec.js @@ -0,0 +1,111 @@ +import MockAdapter from 'axios-mock-adapter'; +import testAction from 'helpers/vuex_action_helper'; +import axios from '~/lib/utils/axios_utils'; +import createFlash from '~/flash'; +import getInitialState from '~/projects/commit/store/state'; +import * as actions from '~/projects/commit/store/actions'; +import * as types from '~/projects/commit/store/mutation_types'; +import mockData from '../mock_data'; +import { PROJECT_BRANCHES_ERROR } from '~/projects/commit/constants'; + +jest.mock('~/flash.js'); + +describe('Commit form modal store actions', () => { + let axiosMock; + let state; + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + state = getInitialState(); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + describe('clearModal', () => { + it('commits CLEAR_MODAL mutation', () => { + testAction(actions.clearModal, {}, {}, [ + { + type: types.CLEAR_MODAL, + }, + ]); + }); + }); + + describe('requestBranches', () => { + it('commits REQUEST_BRANCHES mutation', () => { + testAction(actions.requestBranches, {}, {}, [ + { + type: types.REQUEST_BRANCHES, + }, + ]); + }); + }); + + describe('fetchBranches', () => { + it('dispatch correct actions on fetchBranches', (done) => { + jest + .spyOn(axios, 'get') + .mockImplementation(() => Promise.resolve({ data: mockData.mockBranches })); + + testAction( + actions.fetchBranches, + {}, + state, + [ + { + type: types.RECEIVE_BRANCHES_SUCCESS, + payload: mockData.mockBranches, + }, + ], + [{ type: 'requestBranches' }], + () => { + done(); + }, + ); + }); + + it('should show flash error and set error in state on fetchBranches failure', (done) => { + jest.spyOn(axios, 'get').mockRejectedValue(); + + testAction(actions.fetchBranches, {}, state, [], [{ type: 'requestBranches' }], () => { + expect(createFlash).toHaveBeenCalledWith({ message: PROJECT_BRANCHES_ERROR }); + done(); + }); + }); + }); + + describe('setBranch', () => { + it('commits SET_BRANCH mutation', () => { + testAction( + actions.setBranch, + {}, + {}, + [ + { + type: types.SET_BRANCH, + payload: {}, + }, + ], + [ + { + type: 'setSelectedBranch', + payload: {}, + }, + ], + ); + }); + }); + + describe('setSelectedBranch', () => { + it('commits SET_SELECTED_BRANCH mutation', () => { + testAction(actions.setSelectedBranch, {}, {}, [ + { + type: types.SET_SELECTED_BRANCH, + payload: {}, + }, + ]); + }); + }); +}); diff --git a/spec/frontend/projects/commit/store/getters_spec.js b/spec/frontend/projects/commit/store/getters_spec.js new file mode 100644 index 00000000000..bd0cb356854 --- /dev/null +++ b/spec/frontend/projects/commit/store/getters_spec.js @@ -0,0 +1,21 @@ +import * as getters from '~/projects/commit/store/getters'; +import mockData from '../mock_data'; + +describe('Commit form modal getters', () => { + describe('joinedBranches', () => { + it('should join fetched branches with variable branches', () => { + const state = { + branches: mockData.mockBranches, + }; + + expect(getters.joinedBranches(state)).toEqual(mockData.mockBranches.sort()); + }); + + it('should provide a uniq list of branches', () => { + const branches = ['_branch_', '_branch_', '_different_branch']; + const state = { branches }; + + expect(getters.joinedBranches(state)).toEqual(branches.slice(1)); + }); + }); +}); diff --git a/spec/frontend/projects/commit/store/mutations_spec.js b/spec/frontend/projects/commit/store/mutations_spec.js new file mode 100644 index 00000000000..59ab3d9a74a --- /dev/null +++ b/spec/frontend/projects/commit/store/mutations_spec.js @@ -0,0 +1,57 @@ +import mutations from '~/projects/commit/store/mutations'; +import * as types from '~/projects/commit/store/mutation_types'; + +describe('Commit form modal mutations', () => { + let stateCopy; + + describe('REQUEST_BRANCHES', () => { + it('should set isFetching to true', () => { + stateCopy = { isFetching: false }; + + mutations[types.REQUEST_BRANCHES](stateCopy); + + expect(stateCopy.isFetching).toBe(true); + }); + }); + + describe('RECEIVE_BRANCHES_SUCCESS', () => { + it('should set branches', () => { + stateCopy = { branch: '_existing_branch_', isFetching: true }; + + mutations[types.RECEIVE_BRANCHES_SUCCESS](stateCopy, ['_branch_1_', '_branch_2_']); + + expect(stateCopy.branches).toEqual(['_existing_branch_', '_branch_1_', '_branch_2_']); + expect(stateCopy.isFetching).toEqual(false); + }); + }); + + describe('CLEAR_MODAL', () => { + it('should clear modal state ', () => { + stateCopy = { branch: '_master_', defaultBranch: '_default_branch_' }; + + mutations[types.CLEAR_MODAL](stateCopy); + + expect(stateCopy.branch).toEqual('_default_branch_'); + }); + }); + + describe('SET_BRANCH', () => { + it('should set branch', () => { + stateCopy = { branch: '_master_' }; + + mutations[types.SET_BRANCH](stateCopy, '_changed_branch_'); + + expect(stateCopy.branch).toBe('_changed_branch_'); + }); + }); + + describe('SET_SELECTED_BRANCH', () => { + it('should set selectedBranch', () => { + stateCopy = { selectedBranch: '_master_' }; + + mutations[types.SET_SELECTED_BRANCH](stateCopy, '_changed_branch_'); + + expect(stateCopy.selectedBranch).toBe('_changed_branch_'); + }); + }); +}); diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js index 68c285a4097..63920ddfd72 100644 --- a/spec/frontend/projects/commits/components/author_select_spec.js +++ b/spec/frontend/projects/commits/components/author_select_spec.js @@ -139,11 +139,7 @@ describe('Author Select', () => { }); it('has a "Any Author" as the first list item', () => { - expect( - findDropdownItems() - .at(0) - .text(), - ).toBe('Any Author'); + expect(findDropdownItems().at(0).text()).toBe('Any Author'); }); it('displays the project authors', () => { @@ -163,21 +159,13 @@ describe('Author Select', () => { wrapper.setData({ currentAuthor }); return wrapper.vm.$nextTick().then(() => { - expect( - findDropdownItems() - .at(1) - .props(), - ).toEqual(expect.objectContaining(result)); + expect(findDropdownItems().at(1).props()).toEqual(expect.objectContaining(result)); }); }); it("display the author's name", () => { return wrapper.vm.$nextTick().then(() => { - expect( - findDropdownItems() - .at(1) - .text(), - ).toBe(currentAuthor); + expect(findDropdownItems().at(1).text()).toBe(currentAuthor); }); }); @@ -186,9 +174,7 @@ describe('Author Select', () => { const spy = jest.spyOn(urlUtility, 'redirectTo'); spy.mockImplementation(() => 'mock'); - findDropdownItems() - .at(1) - .vm.$emit('click'); + findDropdownItems().at(1).vm.$emit('click'); expect(spy).toHaveBeenCalledWith(redirectToUrl); }); @@ -198,9 +184,7 @@ describe('Author Select', () => { const spy = jest.spyOn(urlUtility, 'redirectTo'); spy.mockImplementation(); - findDropdownItems() - .at(0) - .vm.$emit('click'); + findDropdownItems().at(0).vm.$emit('click'); expect(spy).toHaveBeenCalledWith(redirectToUrl); }); }); diff --git a/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap index 4eb5060cb0a..0b9f095a700 100644 --- a/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap +++ b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap @@ -31,6 +31,7 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` <gl-modal-stub actioncancel="[object Object]" actionprimary="[object Object]" + dismisslabel="Close" footer-class="gl-bg-gray-10 gl-p-5" modalclass="" modalid="fakeUniqueId" diff --git a/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap b/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap index 4630415f61c..dd54db7dc0a 100644 --- a/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap +++ b/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap @@ -29,24 +29,12 @@ exports[`Project remove modal intialized matches the snapshot 1`] = ` Delete project </gl-button-stub> - <b-modal-stub - canceltitle="Cancel" - cancelvariant="secondary" - footerclass="gl-bg-gray-10 gl-p-5" - headerclosecontent="×" - headercloselabel="Close" - id="delete-project-modal-2" - ignoreenforcefocusselector="" - lazy="true" - modalclass="gl-modal," - oktitle="OK" - okvariant="danger" - size="sm" - title="" - titleclass="gl-text-red-500" - titletag="h4" + <div + footer-class="gl-bg-gray-10 gl-p-5" + ok-variant="danger" + title-class="gl-text-red-500" > - + Delete project. Are you ABSOLUTELY SURE? <div> <p @@ -70,49 +58,6 @@ exports[`Project remove modal intialized matches the snapshot 1`] = ` /> </div> - - <template /> - - <template> - Delete project. Are you ABSOLUTELY SURE? - </template> - - <template /> - - <template /> - - <template /> - - <template> - <gl-button-stub - buttontextclasses="" - category="primary" - class="js-modal-action-cancel" - icon="" - size="medium" - variant="default" - > - - Cancel, keep project - - </gl-button-stub> - - <!----> - - <gl-button-stub - buttontextclasses="" - category="primary" - class="js-modal-action-primary" - disabled="true" - icon="" - size="medium" - variant="danger" - > - - Yes, delete project - - </gl-button-stub> - </template> - </b-modal-stub> + </div> </form> `; diff --git a/spec/frontend/projects/components/shared/delete_button_spec.js b/spec/frontend/projects/components/shared/delete_button_spec.js index a6394a50011..cf7e41a2df2 100644 --- a/spec/frontend/projects/components/shared/delete_button_spec.js +++ b/spec/frontend/projects/components/shared/delete_button_spec.js @@ -1,5 +1,6 @@ import { shallowMount } from '@vue/test-utils'; import { GlModal } from '@gitlab/ui'; +import { stubComponent } from 'helpers/stub_component'; import SharedDeleteButton from '~/projects/components/shared/delete_button.vue'; jest.mock('~/lib/utils/csrf', () => ({ token: 'test-csrf-token' })); @@ -17,12 +18,19 @@ describe('Project remove modal', () => { formPath: 'some/path', }; - const createComponent = (data = {}) => { + const createComponent = (data = {}, stubs = {}) => { wrapper = shallowMount(SharedDeleteButton, { propsData: defaultProps, data: () => data, stubs: { - GlModal, + GlModal: stubComponent(GlModal, { + template: ` + <div> + <slot name="modal-title"></slot> + <slot></slot> + </div>`, + }), + ...stubs, }, }); }; @@ -52,7 +60,7 @@ describe('Project remove modal', () => { describe('when the user input does not match the confirmPhrase', () => { beforeEach(() => { - createComponent({ userInput: 'bar' }); + createComponent({ userInput: 'bar' }, { GlModal }); }); it('the confirm button is disabled', () => { @@ -62,7 +70,7 @@ describe('Project remove modal', () => { describe('when the user input matches the confirmPhrase', () => { beforeEach(() => { - createComponent({ userInput: defaultProps.confirmPhrase }); + createComponent({ userInput: defaultProps.confirmPhrase }, { GlModal }); }); it('the confirm button is not disabled', () => { diff --git a/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js index a1e1e4554e2..9a5f200f5a9 100644 --- a/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js +++ b/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js @@ -7,7 +7,7 @@ import LegacyContainer from '~/projects/experiment_new_project_creation/componen describe('Experimental new project creation app', () => { let wrapper; - const createComponent = propsData => { + const createComponent = (propsData) => { wrapper = shallowMount(App, { propsData }); }; @@ -53,6 +53,28 @@ describe('Experimental new project creation app', () => { }); }); + describe('display custom new project guideline text', () => { + beforeEach(() => { + window.location.hash = '#blank_project'; + }); + + it('does not render new project guideline if undefined', () => { + createComponent(); + expect(wrapper.find('div#new-project-guideline').exists()).toBe(false); + }); + + it('render new project guideline if defined', () => { + const guidelineSelector = 'div#new-project-guideline'; + + createComponent({ + newProjectGuidelines: '<h4>Internal Guidelines</h4><p>lorem ipsum</p>', + }); + expect(wrapper.find(guidelineSelector).exists()).toBe(true); + expect(wrapper.find(guidelineSelector).html()).toContain('<h4>Internal Guidelines</h4>'); + expect(wrapper.find(guidelineSelector).html()).toContain('<p>lorem ipsum</p>'); + }); + }); + it('renders relevant container when hash changes', () => { createComponent(); expect(wrapper.find(WelcomePage).exists()).toBe(true); diff --git a/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js index 42a7aa6bc88..6fc36d6362c 100644 --- a/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js +++ b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js @@ -6,7 +6,7 @@ describe('Legacy container component', () => { let wrapper; let dummy; - const createComponent = propsData => { + const createComponent = (propsData) => { wrapper = shallowMount(LegacyContainer, { propsData }); }; diff --git a/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js index cf23ba281f9..d6764f75262 100644 --- a/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js +++ b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js @@ -6,7 +6,7 @@ describe('Welcome page', () => { let wrapper; let trackingSpy; - const createComponent = propsData => { + const createComponent = (propsData) => { wrapper = shallowMount(WelcomePage, { propsData }); }; diff --git a/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap b/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap index d68e009f46e..fc51825f15b 100644 --- a/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap +++ b/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PipelinesAreaChart matches the snapshot 1`] = ` +exports[`CiCdAnalyticsAreaChart matches the snapshot 1`] = ` <div class="gl-mt-3" > diff --git a/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap b/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap index c7e760486c0..be3716c24e6 100644 --- a/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap +++ b/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap @@ -38,14 +38,5 @@ exports[`StatisticsList displays the counts data with labels 1`] = ` 50.00% </strong> </li> - <li> - <span> - Total duration: - </span> - - <strong> - 00:01:56 - </strong> - </li> </ul> `; diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index f8737dda5f6..44329944097 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -1,10 +1,10 @@ +import { merge } from 'lodash'; import { createLocalVue, shallowMount } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; -import createMockApollo from 'jest/helpers/mock_apollo_helper'; -import { GlColumnChart } from '@gitlab/ui/dist/charts'; +import { GlTabs, GlTab } from '@gitlab/ui'; +import createMockApollo from 'helpers/mock_apollo_helper'; import Component from '~/projects/pipelines/charts/components/app.vue'; -import StatisticsList from '~/projects/pipelines/charts/components/statistics_list.vue'; -import PipelinesAreaChart from '~/projects/pipelines/charts/components/pipelines_area_chart.vue'; +import PipelineCharts from '~/projects/pipelines/charts/components/pipeline_charts.vue'; import getPipelineCountByStatus from '~/projects/pipelines/charts/graphql/queries/get_pipeline_count_by_status.query.graphql'; import getProjectPipelineStatistics from '~/projects/pipelines/charts/graphql/queries/get_project_pipeline_statistics.query.graphql'; import { mockPipelineCount, mockPipelineStatistics } from '../mock_data'; @@ -13,6 +13,8 @@ const projectPath = 'gitlab-org/gitlab'; const localVue = createLocalVue(); localVue.use(VueApollo); +const DeploymentFrequencyChartsStub = { name: 'DeploymentFrequencyCharts', render: () => {} }; + describe('ProjectsPipelinesChartsApp', () => { let wrapper; @@ -25,21 +27,29 @@ describe('ProjectsPipelinesChartsApp', () => { return createMockApollo(requestHandlers); } - function createComponent(options = {}) { - const { fakeApollo } = options; - - return shallowMount(Component, { - provide: { - projectPath, - }, - localVue, - apolloProvider: fakeApollo, - }); + function createComponent(mountOptions = {}) { + wrapper = shallowMount( + Component, + merge( + {}, + { + provide: { + projectPath, + shouldRenderDeploymentFrequencyCharts: false, + }, + localVue, + apolloProvider: createMockApolloProvider(), + stubs: { + DeploymentFrequencyCharts: DeploymentFrequencyChartsStub, + }, + }, + mountOptions, + ), + ); } beforeEach(() => { - const fakeApollo = createMockApolloProvider(); - wrapper = createComponent({ fakeApollo }); + createComponent(); }); afterEach(() => { @@ -47,50 +57,74 @@ describe('ProjectsPipelinesChartsApp', () => { wrapper = null; }); - describe('overall statistics', () => { - it('displays the statistics list', () => { - const list = wrapper.find(StatisticsList); - - expect(list.exists()).toBe(true); - expect(list.props('counts')).toMatchObject({ - failed: 1, - success: 23, - total: 34, - successRatio: 95.83333333333334, - totalDuration: 2471, - }); - }); + describe('pipelines charts', () => { + it('displays the pipeline charts', () => { + const chart = wrapper.find(PipelineCharts); + const analytics = mockPipelineStatistics.data.project.pipelineAnalytics; - it('displays the commit duration chart', () => { - const chart = wrapper.find(GlColumnChart); + const { + totalPipelines: total, + successfulPipelines: success, + failedPipelines: failed, + } = mockPipelineCount.data.project; expect(chart.exists()).toBe(true); - expect(chart.props('yAxisTitle')).toBe('Minutes'); - expect(chart.props('xAxisTitle')).toBe('Commit'); - expect(chart.props('bars')).toBe(wrapper.vm.timesChartTransformedData); - expect(chart.props('option')).toBe(wrapper.vm.$options.timesChartOptions); + expect(chart.props()).toMatchObject({ + counts: { + failed: failed.count, + success: success.count, + total: total.count, + successRatio: (success.count / (success.count + failed.count)) * 100, + }, + lastWeek: { + labels: analytics.weekPipelinesLabels, + totals: analytics.weekPipelinesTotals, + success: analytics.weekPipelinesSuccessful, + }, + lastMonth: { + labels: analytics.monthPipelinesLabels, + totals: analytics.monthPipelinesTotals, + success: analytics.monthPipelinesSuccessful, + }, + lastYear: { + labels: analytics.yearPipelinesLabels, + totals: analytics.yearPipelinesTotals, + success: analytics.yearPipelinesSuccessful, + }, + timesChart: { + labels: analytics.pipelineTimesLabels, + values: analytics.pipelineTimesValues, + }, + }); }); }); - describe('pipelines charts', () => { - it('displays 3 area charts', () => { - expect(wrapper.findAll(PipelinesAreaChart)).toHaveLength(3); + const findDeploymentFrequencyCharts = () => wrapper.find(DeploymentFrequencyChartsStub); + const findGlTabs = () => wrapper.find(GlTabs); + const findAllGlTab = () => wrapper.findAll(GlTab); + const findGlTabAt = (i) => findAllGlTab().at(i); + + describe('when shouldRenderDeploymentFrequencyCharts is true', () => { + beforeEach(() => { + createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: true } }); }); - describe('displays individual correctly', () => { - it('renders with the correct data', () => { - const charts = wrapper.findAll(PipelinesAreaChart); + it('renders the deployment frequency charts in a tab', () => { + expect(findGlTabs().exists()).toBe(true); + expect(findGlTabAt(0).attributes('title')).toBe('Pipelines'); + expect(findGlTabAt(1).attributes('title')).toBe('Deployments'); + expect(findDeploymentFrequencyCharts().exists()).toBe(true); + }); + }); - for (let i = 0; i < charts.length; i += 1) { - const chart = charts.at(i); + describe('when shouldRenderDeploymentFrequencyCharts is false', () => { + beforeEach(() => { + createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: false } }); + }); - expect(chart.exists()).toBe(true); - // TODO: Refactor this to use the mocked data instead of the vm data - // https://gitlab.com/gitlab-org/gitlab/-/issues/292085 - expect(chart.props('chartData')).toBe(wrapper.vm.areaCharts[i].data); - expect(chart.text()).toBe(wrapper.vm.areaCharts[i].title); - } - }); + it('does not render the deployment frequency charts in a tab', () => { + expect(findGlTabs().exists()).toBe(false); + expect(findDeploymentFrequencyCharts().exists()).toBe(false); }); }); }); diff --git a/spec/frontend/projects/pipelines/charts/components/pipelines_area_chart_spec.js b/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_area_chart_spec.js index aea25903023..64f80300237 100644 --- a/spec/frontend/projects/pipelines/charts/components/pipelines_area_chart_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_area_chart_spec.js @@ -1,14 +1,23 @@ import { mount } from '@vue/test-utils'; -import Component from '~/projects/pipelines/charts/components/pipelines_area_chart.vue'; +import CiCdAnalyticsAreaChart from '~/projects/pipelines/charts/components/ci_cd_analytics_area_chart.vue'; import { transformedAreaChartData } from '../mock_data'; -describe('PipelinesAreaChart', () => { +describe('CiCdAnalyticsAreaChart', () => { let wrapper; beforeEach(() => { - wrapper = mount(Component, { + wrapper = mount(CiCdAnalyticsAreaChart, { propsData: { chartData: transformedAreaChartData, + areaChartOptions: { + xAxis: { + name: 'X axis title', + type: 'category', + }, + yAxis: { + name: 'Y axis title', + }, + }, }, slots: { default: 'Some title', diff --git a/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js index c03b571eb26..598055d5828 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js @@ -1,27 +1,34 @@ import { shallowMount } from '@vue/test-utils'; import { GlColumnChart } from '@gitlab/ui/dist/charts'; -import Component from '~/projects/pipelines/charts/components/app_legacy.vue'; import StatisticsList from '~/projects/pipelines/charts/components/statistics_list.vue'; -import PipelinesAreaChart from '~/projects/pipelines/charts/components/pipelines_area_chart.vue'; +import CiCdAnalyticsAreaChart from '~/projects/pipelines/charts/components/ci_cd_analytics_area_chart.vue'; +import PipelineCharts from '~/projects/pipelines/charts/components/pipeline_charts.vue'; import { counts, - timesChartData, - areaChartData as lastWeekChartData, - areaChartData as lastMonthChartData, - lastYearChartData, + timesChartData as timesChart, + areaChartData as lastWeek, + areaChartData as lastMonth, + lastYearChartData as lastYear, } from '../mock_data'; describe('ProjectsPipelinesChartsApp', () => { let wrapper; beforeEach(() => { - wrapper = shallowMount(Component, { + wrapper = shallowMount(PipelineCharts, { propsData: { counts, - timesChartData, - lastWeekChartData, - lastMonthChartData, - lastYearChartData, + timesChart, + lastWeek, + lastMonth, + lastYear, + }, + provide: { + projectPath: 'test/project', + shouldRenderDeploymentFrequencyCharts: true, + }, + stubs: { + DeploymentFrequencyCharts: true, }, }); }); @@ -35,7 +42,7 @@ describe('ProjectsPipelinesChartsApp', () => { it('displays the statistics list', () => { const list = wrapper.find(StatisticsList); - expect(list.exists()).toBeTruthy(); + expect(list.exists()).toBe(true); expect(list.props('counts')).toBe(counts); }); @@ -52,13 +59,12 @@ describe('ProjectsPipelinesChartsApp', () => { describe('pipelines charts', () => { it('displays 3 area charts', () => { - expect(wrapper.findAll(PipelinesAreaChart).length).toBe(3); + expect(wrapper.findAll(CiCdAnalyticsAreaChart)).toHaveLength(3); }); describe('displays individual correctly', () => { it('renders with the correct data', () => { - const charts = wrapper.findAll(PipelinesAreaChart); - + const charts = wrapper.findAll(CiCdAnalyticsAreaChart); for (let i = 0; i < charts.length; i += 1) { const chart = charts.at(i); diff --git a/spec/frontend/projects/pipelines/charts/mock_data.js b/spec/frontend/projects/pipelines/charts/mock_data.js index da055536fcc..3bc09f0b0a0 100644 --- a/spec/frontend/projects/pipelines/charts/mock_data.js +++ b/spec/frontend/projects/pipelines/charts/mock_data.js @@ -25,11 +25,23 @@ export const lastYearChartData = { export const transformedAreaChartData = [ { name: 'all', - data: [['01 Jan', 4], ['02 Jan', 6], ['03 Jan', 3], ['04 Jan', 6], ['05 Jan', 7]], + data: [ + ['01 Jan', 4], + ['02 Jan', 6], + ['03 Jan', 3], + ['04 Jan', 6], + ['05 Jan', 7], + ], }, { name: 'success', - data: [['01 Jan', 3], ['02 Jan', 3], ['03 Jan', 3], ['04 Jan', 3], ['05 Jan', 5]], + data: [ + ['01 Jan', 3], + ['02 Jan', 3], + ['03 Jan', 3], + ['04 Jan', 3], + ['05 Jan', 5], + ], }, ]; diff --git a/spec/frontend/projects/project_import_gitlab_project_spec.js b/spec/frontend/projects/project_import_gitlab_project_spec.js index 3c94934699d..aaf8a81f626 100644 --- a/spec/frontend/projects/project_import_gitlab_project_spec.js +++ b/spec/frontend/projects/project_import_gitlab_project_spec.js @@ -4,7 +4,7 @@ describe('Import Gitlab project', () => { const pathName = 'my-project'; const projectName = 'My Project'; - const setTestFixtures = url => { + const setTestFixtures = (url) => { window.history.pushState({}, null, url); setFixtures(` diff --git a/spec/frontend/projects/project_new_spec.js b/spec/frontend/projects/project_new_spec.js index c32979dcd74..d2936cb9efe 100644 --- a/spec/frontend/projects/project_new_spec.js +++ b/spec/frontend/projects/project_new_spec.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import { TEST_HOST } from 'jest/helpers/test_constants'; +import { TEST_HOST } from 'helpers/test_constants'; import projectNew from '~/projects/project_new'; describe('New Project', () => { @@ -38,10 +38,7 @@ describe('New Project', () => { beforeEach(() => { projectNew.bindEvents(); - $projectPath - .val('') - .keyup() - .val(dummyImportUrl); + $projectPath.val('').keyup().val(dummyImportUrl); }); it('does not change project path for disabled $projectImportUrl', () => { diff --git a/spec/frontend/projects/projects_filterable_list_spec.js b/spec/frontend/projects/projects_filterable_list_spec.js index e756fb3ab56..377d347623a 100644 --- a/spec/frontend/projects/projects_filterable_list_spec.js +++ b/spec/frontend/projects/projects_filterable_list_spec.js @@ -1,5 +1,5 @@ +import { getJSONFixture, setHTMLFixture } from 'helpers/fixtures'; import ProjectsFilterableList from '~/projects/projects_filterable_list'; -import { getJSONFixture, setHTMLFixture } from '../helpers/fixtures'; describe('ProjectsFilterableList', () => { let List; diff --git a/spec/frontend/projects/settings/access_dropdown_spec.js b/spec/frontend/projects/settings/access_dropdown_spec.js index 41b9c0c3763..8a57930ac83 100644 --- a/spec/frontend/projects/settings/access_dropdown_spec.js +++ b/spec/frontend/projects/settings/access_dropdown_spec.js @@ -72,7 +72,7 @@ describe('AccessDropdown', () => { describe('with only role', () => { beforeEach(() => { - dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.ROLE)); + dropdown.setSelectedItems(dummyItems.filter((item) => item.type === LEVEL_TYPES.ROLE)); $dropdownToggleText.addClass('is-default'); }); @@ -86,7 +86,7 @@ describe('AccessDropdown', () => { describe('with only users', () => { beforeEach(() => { - dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.USER)); + dropdown.setSelectedItems(dummyItems.filter((item) => item.type === LEVEL_TYPES.USER)); $dropdownToggleText.addClass('is-default'); }); @@ -100,7 +100,7 @@ describe('AccessDropdown', () => { describe('with only groups', () => { beforeEach(() => { - dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.GROUP)); + dropdown.setSelectedItems(dummyItems.filter((item) => item.type === LEVEL_TYPES.GROUP)); $dropdownToggleText.addClass('is-default'); }); @@ -115,7 +115,7 @@ describe('AccessDropdown', () => { describe('with users and groups', () => { beforeEach(() => { const selectedTypes = [LEVEL_TYPES.GROUP, LEVEL_TYPES.USER]; - dropdown.setSelectedItems(dummyItems.filter(item => selectedTypes.includes(item.type))); + dropdown.setSelectedItems(dummyItems.filter((item) => selectedTypes.includes(item.type))); $dropdownToggleText.addClass('is-default'); }); @@ -130,7 +130,7 @@ describe('AccessDropdown', () => { describe('with users and deploy keys', () => { beforeEach(() => { const selectedTypes = [LEVEL_TYPES.DEPLOY_KEY, LEVEL_TYPES.USER]; - dropdown.setSelectedItems(dummyItems.filter(item => selectedTypes.includes(item.type))); + dropdown.setSelectedItems(dummyItems.filter((item) => selectedTypes.includes(item.type))); $dropdownToggleText.addClass('is-default'); }); diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js index 7e74a5deee1..c83b1852147 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js @@ -137,7 +137,7 @@ describe('ServiceDeskRoot', () => { .$nextTick() .then(waitForPromises) .then(() => { - expect(wrapper.html()).toContain('Changes were successfully made.'); + expect(wrapper.html()).toContain('Changes saved.'); }); }); @@ -160,7 +160,7 @@ describe('ServiceDeskRoot', () => { .$nextTick() .then(waitForPromises) .then(() => { - expect(wrapper.html()).toContain('An error occured while making the changes:'); + expect(wrapper.html()).toContain('An error occured while saving changes:'); }); }); diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js index 173a7fc4e11..ddd9a7b2fad 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js @@ -185,7 +185,9 @@ describe('ServiceDeskSetting', () => { const expectedTemplates = [''].concat(templates); const dropdown = findTemplateDropdown(); - const dropdownList = Array.from(dropdown.element.children).map(option => option.innerText); + const dropdownList = Array.from(dropdown.element.children).map( + (option) => option.innerText, + ); expect(dropdown.element.children).toHaveLength(expectedTemplates.length); expect(dropdownList.includes('Bug')).toEqual(true); diff --git a/spec/frontend/projects/settings_service_desk/services/service_desk_service_spec.js b/spec/frontend/projects/settings_service_desk/services/service_desk_service_spec.js index 3b960a95db4..d5340df03fe 100644 --- a/spec/frontend/projects/settings_service_desk/services/service_desk_service_spec.js +++ b/spec/frontend/projects/settings_service_desk/services/service_desk_service_spec.js @@ -23,7 +23,7 @@ describe('ServiceDeskService', () => { it('makes a request to set service desk', () => { axiosMock.onPut(endpoint).replyOnce(httpStatusCodes.OK, dummyResponse); - return service.toggleServiceDesk(true).then(response => { + return service.toggleServiceDesk(true).then((response) => { expect(response.data).toEqual(dummyResponse); }); }); @@ -31,7 +31,7 @@ describe('ServiceDeskService', () => { it('fails on error response', () => { axiosMock.onPut(endpoint).networkError(); - return service.toggleServiceDesk(true).catch(error => { + return service.toggleServiceDesk(true).catch((error) => { expect(error.message).toBe(errorMessage); }); }); @@ -63,7 +63,7 @@ describe('ServiceDeskService', () => { }, true, ) - .then(response => { + .then((response) => { expect(response.data).toEqual(dummyResponse); }); }); @@ -79,7 +79,7 @@ describe('ServiceDeskService', () => { }, true, ) - .catch(error => { + .catch((error) => { expect(error.message).toBe(errorMessage); }); }); |