From edaa33dee2ff2f7ea3fac488d41558eb5f86d68c Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 20 Jan 2022 09:16:11 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-7-stable-ee --- .../components/blob_button_group_spec.js | 47 +++++++++--- .../components/blob_content_viewer_spec.js | 28 +------ .../repository/components/blob_controls_spec.js | 88 ++++++++++++++++++++++ .../repository/components/breadcrumbs_spec.js | 8 ++ .../repository/components/last_commit_spec.js | 2 + .../repository/components/preview/index_spec.js | 6 ++ .../repository/components/table/index_spec.js | 2 + .../repository/components/table/row_spec.js | 2 + .../repository/components/tree_content_spec.js | 8 ++ .../components/upload_blob_modal_spec.js | 4 + spec/frontend/repository/mock_data.js | 23 +++++- 11 files changed, 182 insertions(+), 36 deletions(-) create mode 100644 spec/frontend/repository/components/blob_controls_spec.js (limited to 'spec/frontend/repository') diff --git a/spec/frontend/repository/components/blob_button_group_spec.js b/spec/frontend/repository/components/blob_button_group_spec.js index 9f9d574a8ed..d5b882bd715 100644 --- a/spec/frontend/repository/components/blob_button_group_spec.js +++ b/spec/frontend/repository/components/blob_button_group_spec.js @@ -1,6 +1,5 @@ import { GlButton } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; import BlobButtonGroup from '~/repository/components/blob_button_group.vue'; import DeleteBlobModal from '~/repository/components/delete_blob_modal.vue'; import UploadBlobModal from '~/repository/components/upload_blob_modal.vue'; @@ -16,6 +15,7 @@ const DEFAULT_PROPS = { projectPath: 'some/project/path', isLocked: false, canLock: true, + showForkSuggestion: false, }; const DEFAULT_INJECT = { @@ -27,7 +27,7 @@ describe('BlobButtonGroup component', () => { let wrapper; const createComponent = (props = {}) => { - wrapper = shallowMount(BlobButtonGroup, { + wrapper = mountExtended(BlobButtonGroup, { propsData: { ...DEFAULT_PROPS, ...props, @@ -35,9 +35,6 @@ describe('BlobButtonGroup component', () => { provide: { ...DEFAULT_INJECT, }, - directives: { - GlModal: createMockDirective(), - }, }); }; @@ -47,7 +44,8 @@ describe('BlobButtonGroup component', () => { const findDeleteBlobModal = () => wrapper.findComponent(DeleteBlobModal); const findUploadBlobModal = () => wrapper.findComponent(UploadBlobModal); - const findReplaceButton = () => wrapper.find('[data-testid="replace"]'); + const findDeleteButton = () => wrapper.findByTestId('delete'); + const findReplaceButton = () => wrapper.findByTestId('replace'); it('renders component', () => { createComponent(); @@ -63,6 +61,8 @@ describe('BlobButtonGroup component', () => { describe('buttons', () => { beforeEach(() => { createComponent(); + jest.spyOn(findUploadBlobModal().vm, 'show'); + jest.spyOn(findDeleteBlobModal().vm, 'show'); }); it('renders both the replace and delete button', () => { @@ -75,10 +75,37 @@ describe('BlobButtonGroup component', () => { }); it('triggers the UploadBlobModal from the replace button', () => { - const { value } = getBinding(findReplaceButton().element, 'gl-modal'); - const modalId = findUploadBlobModal().props('modalId'); + findReplaceButton().trigger('click'); + + expect(findUploadBlobModal().vm.show).toHaveBeenCalled(); + }); + + it('triggers the DeleteBlobModal from the delete button', () => { + findDeleteButton().trigger('click'); + + expect(findDeleteBlobModal().vm.show).toHaveBeenCalled(); + }); + + describe('showForkSuggestion set to true', () => { + beforeEach(() => { + createComponent({ showForkSuggestion: true }); + jest.spyOn(findUploadBlobModal().vm, 'show'); + jest.spyOn(findDeleteBlobModal().vm, 'show'); + }); + + it('does not trigger the UploadBlobModal from the replace button', () => { + findReplaceButton().trigger('click'); + + expect(findUploadBlobModal().vm.show).not.toHaveBeenCalled(); + expect(wrapper.emitted().fork).toBeTruthy(); + }); + + it('does not trigger the DeleteBlobModal from the delete button', () => { + findDeleteButton().trigger('click'); - expect(modalId).toEqual(value); + expect(findDeleteBlobModal().vm.show).not.toHaveBeenCalled(); + expect(wrapper.emitted().fork).toBeTruthy(); + }); }); }); diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js index 9e00a2d0408..d3b60ec3768 100644 --- a/spec/frontend/repository/components/blob_content_viewer_spec.js +++ b/spec/frontend/repository/components/blob_content_viewer_spec.js @@ -83,6 +83,8 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => { }), ); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ project, isBinary }); await waitForPromises(); @@ -336,35 +338,11 @@ describe('Blob content viewer component', () => { deletePath: webPath, canPushCode: pushCode, canLock: true, - isLocked: true, + isLocked: false, emptyRepo: empty, }); }); - it.each` - canPushCode | canDownloadCode | username | canLock - ${true} | ${true} | ${'root'} | ${true} - ${false} | ${true} | ${'root'} | ${false} - ${true} | ${false} | ${'root'} | ${false} - ${true} | ${true} | ${'peter'} | ${false} - `( - 'passes the correct lock states', - async ({ canPushCode, canDownloadCode, username, canLock }) => { - gon.current_username = username; - - await createComponent( - { - pushCode: canPushCode, - downloadCode: canDownloadCode, - empty, - }, - mount, - ); - - expect(findBlobButtonGroup().props('canLock')).toBe(canLock); - }, - ); - it('does not render if not logged in', async () => { isLoggedIn.mockReturnValueOnce(false); diff --git a/spec/frontend/repository/components/blob_controls_spec.js b/spec/frontend/repository/components/blob_controls_spec.js new file mode 100644 index 00000000000..03e389ea5cb --- /dev/null +++ b/spec/frontend/repository/components/blob_controls_spec.js @@ -0,0 +1,88 @@ +import { createLocalVue } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import { nextTick } from 'vue'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import BlobControls from '~/repository/components/blob_controls.vue'; +import blobControlsQuery from '~/repository/queries/blob_controls.query.graphql'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import createRouter from '~/repository/router'; +import { updateElementsVisibility } from '~/repository/utils/dom'; +import { blobControlsDataMock, refMock } from '../mock_data'; + +jest.mock('~/repository/utils/dom'); + +let router; +let wrapper; +let mockResolver; + +const localVue = createLocalVue(); + +const createComponent = async () => { + localVue.use(VueApollo); + + const project = { ...blobControlsDataMock }; + const projectPath = 'some/project'; + + router = createRouter(projectPath, refMock); + + router.replace({ name: 'blobPath', params: { path: '/some/file.js' } }); + + mockResolver = jest.fn().mockResolvedValue({ data: { project } }); + + wrapper = shallowMountExtended(BlobControls, { + localVue, + router, + apolloProvider: createMockApollo([[blobControlsQuery, mockResolver]]), + propsData: { projectPath }, + mixins: [{ data: () => ({ ref: refMock }) }], + }); + + await waitForPromises(); +}; + +describe('Blob controls component', () => { + const findFindButton = () => wrapper.findByTestId('find'); + const findBlameButton = () => wrapper.findByTestId('blame'); + const findHistoryButton = () => wrapper.findByTestId('history'); + const findPermalinkButton = () => wrapper.findByTestId('permalink'); + + beforeEach(() => createComponent()); + + afterEach(() => wrapper.destroy()); + + it('renders a find button with the correct href', () => { + expect(findFindButton().attributes('href')).toBe('find/file.js'); + }); + + it('renders a blame button with the correct href', () => { + expect(findBlameButton().attributes('href')).toBe('blame/file.js'); + }); + + it('renders a history button with the correct href', () => { + expect(findHistoryButton().attributes('href')).toBe('history/file.js'); + }); + + it('renders a permalink button with the correct href', () => { + expect(findPermalinkButton().attributes('href')).toBe('permalink/file.js'); + }); + + it.each` + name | path + ${'blobPathDecoded'} | ${null} + ${'treePathDecoded'} | ${'myFile.js'} + `( + 'does not render any buttons if router name is $name and router path is $path', + async ({ name, path }) => { + router.replace({ name, params: { path } }); + + await nextTick(); + + expect(findFindButton().exists()).toBe(false); + expect(findBlameButton().exists()).toBe(false); + expect(findHistoryButton().exists()).toBe(false); + expect(findPermalinkButton().exists()).toBe(false); + expect(updateElementsVisibility).toHaveBeenCalledWith('.tree-controls', true); + }, + ); +}); diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js index eb957c635ac..ad2cbd70187 100644 --- a/spec/frontend/repository/components/breadcrumbs_spec.js +++ b/spec/frontend/repository/components/breadcrumbs_spec.js @@ -75,6 +75,8 @@ describe('Repository breadcrumbs component', () => { it('does not render add to tree dropdown when permissions are false', async () => { factory('/', { canCollaborate: false }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ userPermissions: { forkProject: false, createMergeRequestIn: false } }); await wrapper.vm.$nextTick(); @@ -100,6 +102,8 @@ describe('Repository breadcrumbs component', () => { it('renders add to tree dropdown when permissions are true', async () => { factory('/', { canCollaborate: true }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ userPermissions: { forkProject: true, createMergeRequestIn: true } }); await wrapper.vm.$nextTick(); @@ -117,6 +121,8 @@ describe('Repository breadcrumbs component', () => { }); it('renders the modal once loaded', async () => { + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } }); await wrapper.vm.$nextTick(); @@ -139,6 +145,8 @@ describe('Repository breadcrumbs component', () => { }); it('renders the modal once loaded', async () => { + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } }); await wrapper.vm.$nextTick(); diff --git a/spec/frontend/repository/components/last_commit_spec.js b/spec/frontend/repository/components/last_commit_spec.js index ebea7dde34a..fe05a981845 100644 --- a/spec/frontend/repository/components/last_commit_spec.js +++ b/spec/frontend/repository/components/last_commit_spec.js @@ -43,6 +43,8 @@ function factory(commit = createCommitData(), loading = false) { }, }, }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ commit }); vm.vm.$apollo.queries.commit.loading = loading; } diff --git a/spec/frontend/repository/components/preview/index_spec.js b/spec/frontend/repository/components/preview/index_spec.js index 466eed52739..2490258a048 100644 --- a/spec/frontend/repository/components/preview/index_spec.js +++ b/spec/frontend/repository/components/preview/index_spec.js @@ -34,6 +34,8 @@ describe('Repository file preview component', () => { name: 'README.md', }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ readme: { html: '
test
' } }); return vm.vm.$nextTick(() => { @@ -47,6 +49,8 @@ describe('Repository file preview component', () => { name: 'README.md', }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ readme: { html: '
test
' } }); return vm.vm @@ -63,6 +67,8 @@ describe('Repository file preview component', () => { name: 'README.md', }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ loading: 1 }); return vm.vm.$nextTick(() => { diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js index c8dddefc4f2..2cd88944f81 100644 --- a/spec/frontend/repository/components/table/index_spec.js +++ b/spec/frontend/repository/components/table/index_spec.js @@ -89,6 +89,8 @@ describe('Repository table component', () => { `('renders table caption for $ref in $path', ({ path, ref }) => { factory({ path }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ ref }); return vm.vm.$nextTick(() => { diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js index 7f59dbfe0d1..440baa72a3c 100644 --- a/spec/frontend/repository/components/table/row_spec.js +++ b/spec/frontend/repository/components/table/row_spec.js @@ -40,6 +40,8 @@ function factory(propsData = {}) { }, }); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ escapedRef: 'main' }); } diff --git a/spec/frontend/repository/components/tree_content_spec.js b/spec/frontend/repository/components/tree_content_spec.js index 9c5d07eede3..00ad1fc05f6 100644 --- a/spec/frontend/repository/components/tree_content_spec.js +++ b/spec/frontend/repository/components/tree_content_spec.js @@ -46,6 +46,8 @@ describe('Repository table component', () => { it('renders file preview', async () => { factory('/'); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ entries: { blobs: [{ name: 'README.md' }] } }); await vm.vm.$nextTick(); @@ -134,6 +136,8 @@ describe('Repository table component', () => { it('is not rendered if less than 1000 files', async () => { factory('/'); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ fetchCounter: 5, clickedShowMore: false }); await vm.vm.$nextTick(); @@ -153,6 +157,8 @@ describe('Repository table component', () => { factory('/'); const blobs = new Array(totalBlobs).fill('fakeBlob'); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ entries: { blobs }, pagesLoaded }); await vm.vm.$nextTick(); @@ -173,6 +179,8 @@ describe('Repository table component', () => { ${200} | ${100} `('exponentially increases page size, to a maximum of 100', ({ fetchCounter, pageSize }) => { factory('/'); + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax vm.setData({ fetchCounter }); vm.vm.fetchFiles(); diff --git a/spec/frontend/repository/components/upload_blob_modal_spec.js b/spec/frontend/repository/components/upload_blob_modal_spec.js index e9dfa3cd495..6b8b0752485 100644 --- a/spec/frontend/repository/components/upload_blob_modal_spec.js +++ b/spec/frontend/repository/components/upload_blob_modal_spec.js @@ -109,6 +109,8 @@ describe('UploadBlobModal', () => { if (canPushCode) { describe('when changing the branch name', () => { it('displays the MR toggle', async () => { + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ target: 'Not main' }); await wrapper.vm.$nextTick(); @@ -120,6 +122,8 @@ describe('UploadBlobModal', () => { describe('completed form', () => { beforeEach(() => { + // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details + // eslint-disable-next-line no-restricted-syntax wrapper.setData({ file: { type: 'jpg' }, filePreviewURL: 'http://file.com?format=jpg', diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js index 74d35daf578..a5ee17ba672 100644 --- a/spec/frontend/repository/mock_data.js +++ b/spec/frontend/repository/mock_data.js @@ -13,7 +13,9 @@ export const simpleViewerMock = { ideForkAndEditPath: 'some_file.js/fork/ide', canModifyBlob: true, canCurrentUserPushToBranch: true, + archived: false, storedExternally: false, + externalStorage: 'lfs', rawPath: 'some_file.js', replacePath: 'some_file.js/replace', pipelineEditorPath: '', @@ -50,7 +52,7 @@ export const projectMock = { nodes: [ { id: 'test', - path: simpleViewerMock.path, + path: 'locked_file.js', user: { id: '123', username: 'root' }, }, ], @@ -63,3 +65,22 @@ export const projectMock = { export const propsMock = { path: 'some_file.js', projectPath: 'some/path' }; export const refMock = 'default-ref'; + +export const blobControlsDataMock = { + id: '1234', + repository: { + blobs: { + nodes: [ + { + id: '5678', + findFilePath: 'find/file.js', + blamePath: 'blame/file.js', + historyPath: 'history/file.js', + permalinkPath: 'permalink/file.js', + storedExternally: false, + externalStorage: '', + }, + ], + }, + }, +}; -- cgit v1.2.3