diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-25 12:10:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-25 12:10:31 +0300 |
commit | 533785b08b52989b1435c8d0723b83c8e1b5d12a (patch) | |
tree | fc8963d5d0bc91c44669c4c43759e2891d652ec0 /spec/frontend/design_management | |
parent | 94ccc6ad21ea0634dd7702cd7fc28ea31043c672 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/design_management')
-rw-r--r-- | spec/frontend/design_management/components/design_presentation_spec.js | 42 | ||||
-rw-r--r-- | spec/frontend/design_management/pages/index_spec.js | 254 |
2 files changed, 145 insertions, 151 deletions
diff --git a/spec/frontend/design_management/components/design_presentation_spec.js b/spec/frontend/design_management/components/design_presentation_spec.js index d633d00f2ed..31fd154dc4b 100644 --- a/spec/frontend/design_management/components/design_presentation_spec.js +++ b/spec/frontend/design_management/components/design_presentation_spec.js @@ -1,3 +1,4 @@ +import { nextTick } from 'vue'; import { shallowMount } from '@vue/test-utils'; import DesignPresentation from '~/design_management/components/design_presentation.vue'; import DesignOverlay from '~/design_management/components/design_overlay.vue'; @@ -100,12 +101,12 @@ describe('Design management design presentation component', () => { clientY: endCoords.clientY, }); - return wrapper.vm.$nextTick(); + return nextTick(); }) .then(() => { if (mouseup) { addCommentOverlay.trigger(event.mouseup); - return wrapper.vm.$nextTick(); + return nextTick(); } return undefined; @@ -125,7 +126,7 @@ describe('Design management design presentation component', () => { mockOverlayData, ); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.element).toMatchSnapshot(); }); }); @@ -133,7 +134,7 @@ describe('Design management design presentation component', () => { it('renders empty state when no image provided', () => { createComponent(); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.element).toMatchSnapshot(); }); }); @@ -149,7 +150,7 @@ describe('Design management design presentation component', () => { wrapper.vm.openCommentForm({ x: 1, y: 1 }); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.emitted('openCommentForm')).toEqual([ [{ ...mockOverlayData.overlayDimensions, x: 1, y: 1 }], ]); @@ -166,7 +167,7 @@ describe('Design management design presentation component', () => { mockOverlayData, ); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.vm.currentCommentForm).toBeNull(); expect(wrapper.element).toMatchSnapshot(); }); @@ -182,7 +183,7 @@ describe('Design management design presentation component', () => { mockOverlayData, ); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.vm.currentCommentForm).toBeNull(); expect(wrapper.element).toMatchSnapshot(); }); @@ -206,7 +207,7 @@ describe('Design management design presentation component', () => { }, ); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.vm.currentCommentForm).toEqual({ x: 1, y: 1, @@ -379,7 +380,7 @@ describe('Design management design presentation component', () => { }); describe('onImageResize', () => { - it('sets zoom focal point on initial load', () => { + beforeEach(() => { createComponent( { image: 'test.jpg', @@ -388,22 +389,21 @@ describe('Design management design presentation component', () => { mockOverlayData, ); - wrapper.setMethods({ - shiftZoomFocalPoint: jest.fn(), - scaleZoomFocalPoint: jest.fn(), - scrollToFocalPoint: jest.fn(), - }); - + jest.spyOn(wrapper.vm, 'shiftZoomFocalPoint'); + jest.spyOn(wrapper.vm, 'scaleZoomFocalPoint'); + jest.spyOn(wrapper.vm, 'scrollToFocalPoint'); wrapper.vm.onImageResize({ width: 10, height: 10 }); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.shiftZoomFocalPoint).toHaveBeenCalled(); - expect(wrapper.vm.initialLoad).toBe(false); - }); + return nextTick(); + }); + + it('sets zoom focal point on initial load', () => { + expect(wrapper.vm.shiftZoomFocalPoint).toHaveBeenCalled(); + expect(wrapper.vm.initialLoad).toBe(false); }); it('calls scaleZoomFocalPoint and scrollToFocalPoint after initial load', () => { wrapper.vm.onImageResize({ width: 10, height: 10 }); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.vm.scaleZoomFocalPoint).toHaveBeenCalled(); expect(wrapper.vm.scrollToFocalPoint).toHaveBeenCalled(); }); @@ -506,7 +506,7 @@ describe('Design management design presentation component', () => { .$nextTick() .then(() => { addCommentOverlay.trigger('mouseup'); - return wrapper.vm.$nextTick(); + return nextTick(); }) .then(() => { expect(wrapper.emitted('openCommentForm')).toBeDefined(); diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js index f2f15e286f5..df289350390 100644 --- a/spec/frontend/design_management/pages/index_spec.js +++ b/spec/frontend/design_management/pages/index_spec.js @@ -1,3 +1,4 @@ +import { nextTick } from 'vue'; import { createLocalVue, shallowMount } from '@vue/test-utils'; import VueApollo, { ApolloMutation } from 'vue-apollo'; import VueDraggable from 'vuedraggable'; @@ -8,7 +9,7 @@ import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import getDesignListQuery from 'shared_queries/design_management/get_design_list.query.graphql'; import permissionsQuery from 'shared_queries/design_management/design_permissions.query.graphql'; import Index from '~/design_management/pages/index.vue'; -import uploadDesignQuery from '~/design_management/graphql/mutations/upload_design.mutation.graphql'; +import uploadDesignMutation from '~/design_management/graphql/mutations/upload_design.mutation.graphql'; import DesignDestroyer from '~/design_management/components/design_destroyer.vue'; import DesignDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue'; import DeleteButton from '~/design_management/components/delete_button.vue'; @@ -113,7 +114,7 @@ describe('Design management index page', () => { async function moveDesigns(localWrapper) { await jest.runOnlyPendingTimers(); - await localWrapper.vm.$nextTick(); + await nextTick(); localWrapper.find(VueDraggable).vm.$emit('input', reorderedDesigns); localWrapper.find(VueDraggable).vm.$emit('change', { @@ -200,14 +201,13 @@ describe('Design management index page', () => { expect(wrapper.element).toMatchSnapshot(); }); - it('renders error', () => { + it('renders error', async () => { createComponent(); wrapper.setData({ error: true }); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.element).toMatchSnapshot(); - }); + await nextTick(); + expect(wrapper.element).toMatchSnapshot(); }); it('renders a toolbar with buttons when there are designs', () => { @@ -254,10 +254,10 @@ describe('Design management index page', () => { createComponent({ designCollection: { designs: [], copyState: 'READY' } }); }); - it('renders design dropzone', () => - wrapper.vm.$nextTick().then(() => { - expect(findDropzone().exists()).toBe(true); - })); + it('renders design dropzone', async () => { + await nextTick(); + expect(findDropzone().exists()).toBe(true); + }); it('has correct classes applied to design dropzone', () => { expect(dropzoneClasses()).not.toContain('design-list-item'); @@ -268,10 +268,10 @@ describe('Design management index page', () => { expect(findDropzoneWrapper().classes()).toEqual(['col-12']); }); - it('does not render a toolbar with buttons', () => - wrapper.vm.$nextTick().then(() => { - expect(findToolbar().exists()).toBe(false); - })); + it('does not render a toolbar with buttons', async () => { + await nextTick(); + expect(findToolbar().exists()).toBe(false); + }); }); describe('handling design collection copy state', () => { @@ -290,7 +290,7 @@ describe('Design management index page', () => { }); describe('uploading designs', () => { - it('calls mutation on upload', () => { + it('calls mutation on upload', async () => { createComponent({ stubs: { GlEmptyState } }); const mutationVariables = { @@ -298,7 +298,7 @@ describe('Design management index page', () => { context: { hasUpload: true, }, - mutation: uploadDesignQuery, + mutation: uploadDesignMutation, variables: { files: [{ name: 'test' }], projectPath: 'project-path', @@ -348,21 +348,16 @@ describe('Design management index page', () => { }, }; - return wrapper.vm - .$nextTick() - .then(() => { - findDropzone().vm.$emit('change', [{ name: 'test' }]); - expect(mutate).toHaveBeenCalledWith(mutationVariables); - expect(wrapper.vm.filesToBeSaved).toEqual([{ name: 'test' }]); - expect(wrapper.vm.isSaving).toBeTruthy(); - }) - .then(() => { - expect(dropzoneClasses()).toContain('design-list-item'); - expect(dropzoneClasses()).toContain('design-list-item-new'); - }); + await nextTick(); + findDropzone().vm.$emit('change', [{ name: 'test' }]); + expect(mutate).toHaveBeenCalledWith(mutationVariables); + expect(wrapper.vm.filesToBeSaved).toEqual([{ name: 'test' }]); + expect(wrapper.vm.isSaving).toBeTruthy(); + expect(dropzoneClasses()).toContain('design-list-item'); + expect(dropzoneClasses()).toContain('design-list-item-new'); }); - it('sets isSaving', () => { + it('sets isSaving', async () => { createComponent(); const uploadDesign = wrapper.vm.onUploadDesign([ @@ -373,35 +368,31 @@ describe('Design management index page', () => { expect(wrapper.vm.isSaving).toBe(true); - return uploadDesign.then(() => { - expect(wrapper.vm.isSaving).toBe(false); - }); + await uploadDesign; + expect(wrapper.vm.isSaving).toBe(false); }); - it('updates state appropriately after upload complete', () => { + it('updates state appropriately after upload complete', async () => { createComponent({ stubs: { GlEmptyState } }); wrapper.setData({ filesToBeSaved: [{ name: 'test' }] }); wrapper.vm.onUploadDesignDone(designUploadMutationCreatedResponse); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.filesToBeSaved).toEqual([]); - expect(wrapper.vm.isSaving).toBeFalsy(); - expect(wrapper.vm.isLatestVersion).toBe(true); - }); + await nextTick(); + + expect(wrapper.vm.filesToBeSaved).toEqual([]); + expect(wrapper.vm.isSaving).toBeFalsy(); + expect(wrapper.vm.isLatestVersion).toBe(true); }); - it('updates state appropriately after upload error', () => { + it('updates state appropriately after upload error', async () => { createComponent({ stubs: { GlEmptyState } }); wrapper.setData({ filesToBeSaved: [{ name: 'test' }] }); wrapper.vm.onUploadDesignError(); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.filesToBeSaved).toEqual([]); - expect(wrapper.vm.isSaving).toBeFalsy(); - expect(createFlash).toHaveBeenCalled(); - - createFlash.mockReset(); - }); + await nextTick(); + expect(wrapper.vm.filesToBeSaved).toEqual([]); + expect(wrapper.vm.isSaving).toBeFalsy(); + expect(createFlash).toHaveBeenCalled(); }); it('does not call mutation if createDesign is false', () => { @@ -415,10 +406,6 @@ describe('Design management index page', () => { describe('upload count limit', () => { const MAXIMUM_FILE_UPLOAD_LIMIT = 10; - afterEach(() => { - createFlash.mockReset(); - }); - it('does not warn when the max files are uploaded', () => { createComponent(); @@ -436,7 +423,7 @@ describe('Design management index page', () => { }); }); - it('flashes warning if designs are skipped', () => { + it('flashes warning if designs are skipped', async () => { createComponent({ mockMutate: () => Promise.resolve({ @@ -450,25 +437,22 @@ describe('Design management index page', () => { }, ]); - return uploadDesign.then(() => { - expect(createFlash).toHaveBeenCalledTimes(1); - expect(createFlash).toHaveBeenCalledWith({ - message: 'Upload skipped. test.jpg did not change.', - types: 'warning', - }); + await uploadDesign; + expect(createFlash).toHaveBeenCalledTimes(1); + expect(createFlash).toHaveBeenCalledWith({ + message: 'Upload skipped. test.jpg did not change.', + types: 'warning', }); }); describe('dragging onto an existing design', () => { + let mockMutate; beforeEach(() => { - createComponent({ designs: mockDesigns, allVersions: [mockVersion] }); + mockMutate = jest.fn().mockResolvedValue(); + createComponent({ designs: mockDesigns, allVersions: [mockVersion], mockMutate }); }); - it('calls onUploadDesign with valid upload', () => { - wrapper.setMethods({ - onUploadDesign: jest.fn(), - }); - + it('uploads designs with valid upload', () => { const mockUploadPayload = [ { name: mockDesigns[0].filename, @@ -478,8 +462,13 @@ describe('Design management index page', () => { const designDropzone = findFirstDropzoneWithDesign(); designDropzone.vm.$emit('change', mockUploadPayload); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledTimes(1); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledWith(mockUploadPayload); + const [{ mutation, variables }] = mockMutate.mock.calls[0]; + expect(mutation).toBe(uploadDesignMutation); + expect(variables).toStrictEqual({ + files: mockUploadPayload, + iid: '1', + projectPath: 'project-path', + }); }); it.each` @@ -544,51 +533,39 @@ describe('Design management index page', () => { expect(findToolbar().isVisible()).toBe(true); }); - it('adds two designs to selected designs when their checkboxes are checked', () => { + it('adds two designs to selected designs when their checkboxes are checked', async () => { findDesignCheckboxes().at(0).trigger('click'); - return wrapper.vm - .$nextTick() - .then(() => { - findDesignCheckboxes().at(1).trigger('click'); - - return wrapper.vm.$nextTick(); - }) - .then(() => { - expect(findDeleteButton().exists()).toBe(true); - expect(findSelectAllButton().text()).toBe('Deselect all'); - findDeleteButton().vm.$emit('deleteSelectedDesigns'); - const [{ variables }] = mutate.mock.calls[0]; - expect(variables.filenames).toStrictEqual([ - mockDesigns[0].filename, - mockDesigns[1].filename, - ]); - }); + await nextTick(); + findDesignCheckboxes().at(1).trigger('click'); + + await nextTick(); + expect(findDeleteButton().exists()).toBe(true); + expect(findSelectAllButton().text()).toBe('Deselect all'); + findDeleteButton().vm.$emit('deleteSelectedDesigns'); + const [{ variables }] = mutate.mock.calls[0]; + expect(variables.filenames).toStrictEqual([mockDesigns[0].filename, mockDesigns[1].filename]); }); - it('adds all designs to selected designs when Select All button is clicked', () => { + it('adds all designs to selected designs when Select All button is clicked', async () => { findSelectAllButton().vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(findDeleteButton().props().hasSelectedDesigns).toBe(true); - expect(findSelectAllButton().text()).toBe('Deselect all'); - expect(wrapper.vm.selectedDesigns).toEqual(mockDesigns.map((design) => design.filename)); - }); + await nextTick(); + expect(findDeleteButton().props().hasSelectedDesigns).toBe(true); + expect(findSelectAllButton().text()).toBe('Deselect all'); + expect(wrapper.vm.selectedDesigns).toEqual(mockDesigns.map((design) => design.filename)); }); - it('removes all designs from selected designs when at least one design was selected', () => { + it('removes all designs from selected designs when at least one design was selected', async () => { findDesignCheckboxes().at(0).trigger('click'); + await nextTick(); - return wrapper.vm - .$nextTick() - .then(() => { - findSelectAllButton().vm.$emit('click'); - }) - .then(() => { - expect(findDeleteButton().props().hasSelectedDesigns).toBe(false); - expect(findSelectAllButton().text()).toBe('Select all'); - expect(wrapper.vm.selectedDesigns).toEqual([]); - }); + findSelectAllButton().vm.$emit('click'); + await nextTick(); + + expect(findDeleteButton().props().hasSelectedDesigns).toBe(false); + expect(findSelectAllButton().text()).toBe('Select all'); + expect(wrapper.vm.selectedDesigns).toEqual([]); }); }); @@ -626,12 +603,10 @@ describe('Design management index page', () => { describe('pasting a design', () => { let event; + let mockMutate; beforeEach(() => { - createComponent({ designs: mockDesigns, allVersions: [mockVersion] }); - - wrapper.setMethods({ - onUploadDesign: jest.fn(), - }); + mockMutate = jest.fn().mockResolvedValue({}); + createComponent({ designs: mockDesigns, allVersions: [mockVersion], mockMutate }); event = new Event('paste'); event.clipboardData = { @@ -640,36 +615,56 @@ describe('Design management index page', () => { }; }); - it('does not call paste event if designs wrapper is not hovered', () => { + it('does not upload designs if designs wrapper is not hovered', () => { document.dispatchEvent(event); - expect(wrapper.vm.onUploadDesign).not.toHaveBeenCalled(); + expect(mockMutate).not.toHaveBeenCalled(); }); describe('when designs wrapper is hovered', () => { + let realDateNow; + const today = () => new Date('2020-12-25'); + beforeAll(() => { + realDateNow = Date.now; + global.Date.now = today; + }); + + afterAll(() => { + global.Date.now = realDateNow; + }); + beforeEach(() => { findDesignsWrapper().trigger('mouseenter'); }); - it('calls onUploadDesign with valid paste', () => { + it('uploads design with valid paste', () => { document.dispatchEvent(event); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledTimes(1); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledWith([ - new File([{ name: 'image.png' }], 'test.png'), - ]); + const [{ mutation, variables }] = mockMutate.mock.calls[0]; + expect(mutation).toBe(uploadDesignMutation); + expect(variables).toStrictEqual({ + files: expect.any(Array), + iid: '1', + projectPath: 'project-path', + }); + expect(variables.files).toEqual(event.clipboardData.files.map((f) => new File([f], ''))); }); it('renames a design if it has an image.png filename', () => { + event.clipboardData.getData = () => 'image.png'; document.dispatchEvent(event); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledTimes(1); - expect(wrapper.vm.onUploadDesign).toHaveBeenCalledWith([ - new File([{ name: 'image.png' }], `design_${Date.now()}.png`), - ]); + const [{ mutation, variables }] = mockMutate.mock.calls[0]; + expect(mutation).toBe(uploadDesignMutation); + expect(variables).toStrictEqual({ + files: expect.any(Array), + iid: '1', + projectPath: 'project-path', + }); + expect(variables.files[0].name).toEqual(`design_${Date.now()}.png`); }); - it('does not call onUploadDesign with invalid paste', () => { + it('does not call upload with invalid paste', () => { event.clipboardData = { items: [{ type: 'text/plain' }, { type: 'text' }], files: [], @@ -677,28 +672,27 @@ describe('Design management index page', () => { document.dispatchEvent(event); - expect(wrapper.vm.onUploadDesign).not.toHaveBeenCalled(); + expect(mockMutate).not.toHaveBeenCalled(); }); it('removes onPaste listener after mouseleave event', async () => { findDesignsWrapper().trigger('mouseleave'); document.dispatchEvent(event); - expect(wrapper.vm.onUploadDesign).not.toHaveBeenCalled(); + expect(mockMutate).not.toHaveBeenCalled(); }); }); }); describe('when navigating', () => { - it('should trigger a scrollIntoView method if designs route is detected', () => { + it('should trigger a scrollIntoView method if designs route is detected', async () => { router.replace({ path: '/designs', }); createComponent({ loading: true }); - return wrapper.vm.$nextTick().then(() => { - expect(scrollIntoViewMock).toHaveBeenCalled(); - }); + await nextTick(); + expect(scrollIntoViewMock).toHaveBeenCalled(); }); }); @@ -707,7 +701,7 @@ describe('Design management index page', () => { createComponentWithApollo({}); await jest.runOnlyPendingTimers(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDesigns()).toHaveLength(3); expect(findDesigns().at(0).props('id')).toBe('1'); @@ -720,7 +714,7 @@ describe('Design management index page', () => { expect(moveDesignHandler).toHaveBeenCalled(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findDesigns().at(0).props('id')).toBe('2'); }); @@ -733,8 +727,8 @@ describe('Design management index page', () => { expect(draggableAttributes().disabled).toBe(true); await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises) - await wrapper.vm.$nextTick(); // kick off the DOM update - await wrapper.vm.$nextTick(); // kick off the DOM update for finally block + await nextTick(); // kick off the DOM update + await nextTick(); // kick off the DOM update for finally block expect(draggableAttributes().disabled).toBe(false); }); @@ -746,7 +740,7 @@ describe('Design management index page', () => { await moveDesigns(wrapper); - await wrapper.vm.$nextTick(); + await nextTick(); expect(createFlash).toHaveBeenCalledWith({ message: 'Houston, we have a problem' }); }); @@ -758,9 +752,9 @@ describe('Design management index page', () => { await moveDesigns(wrapper); - await wrapper.vm.$nextTick(); // kick off the DOM update + await nextTick(); // kick off the DOM update await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises) - await wrapper.vm.$nextTick(); // kick off the DOM update for flash + await nextTick(); // kick off the DOM update for flash expect(createFlash).toHaveBeenCalledWith({ message: 'Something went wrong when reordering designs. Please try again', |