diff options
Diffstat (limited to 'spec/frontend/repository')
15 files changed, 217 insertions, 170 deletions
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js index d3b60ec3768..109e5cef49b 100644 --- a/spec/frontend/repository/components/blob_content_viewer_spec.js +++ b/spec/frontend/repository/components/blob_content_viewer_spec.js @@ -1,8 +1,8 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import { nextTick } from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; @@ -12,10 +12,10 @@ import BlobButtonGroup from '~/repository/components/blob_button_group.vue'; import BlobContentViewer from '~/repository/components/blob_content_viewer.vue'; import BlobEdit from '~/repository/components/blob_edit.vue'; import ForkSuggestion from '~/repository/components/fork_suggestion.vue'; -import { loadViewer, viewerProps } from '~/repository/components/blob_viewers'; +import { loadViewer } from '~/repository/components/blob_viewers'; import DownloadViewer from '~/repository/components/blob_viewers/download_viewer.vue'; import EmptyViewer from '~/repository/components/blob_viewers/empty_viewer.vue'; -import SourceViewer from '~/vue_shared/components/source_viewer.vue'; +import SourceViewer from '~/vue_shared/components/source_viewer/source_viewer.vue'; import blobInfoQuery from '~/repository/queries/blob_info.query.graphql'; import { redirectTo } from '~/lib/utils/url_utility'; import { isLoggedIn } from '~/lib/utils/common_utils'; @@ -36,11 +36,10 @@ jest.mock('~/lib/utils/common_utils'); let wrapper; let mockResolver; -const localVue = createLocalVue(); const mockAxios = new MockAdapter(axios); const createComponent = async (mockData = {}, mountFn = shallowMount) => { - localVue.use(VueApollo); + Vue.use(VueApollo); const { blob = simpleViewerMock, @@ -51,6 +50,7 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => { createMergeRequestIn = userPermissionsMock.createMergeRequestIn, isBinary, inject = {}, + highlightJs = true, } = mockData; const project = { @@ -75,11 +75,17 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => { wrapper = extendedWrapper( mountFn(BlobContentViewer, { - localVue, apolloProvider: fakeApollo, propsData: propsMock, mixins: [{ data: () => ({ ref: refMock }) }], - provide: { ...inject }, + provide: { + targetBranch: 'test', + originalBranch: 'default-ref', + ...inject, + glFeatures: { + highlightJs, + }, + }, }), ); @@ -100,7 +106,6 @@ describe('Blob content viewer component', () => { const findForkSuggestion = () => wrapper.findComponent(ForkSuggestion); beforeEach(() => { - gon.features = { highlightJs: true }; isLoggedIn.mockReturnValue(true); }); @@ -138,6 +143,15 @@ describe('Blob content viewer component', () => { }); describe('legacy viewers', () => { + it('loads a legacy viewer when a the fileType is text and the highlightJs feature is turned off', async () => { + await createComponent({ + blob: { ...simpleViewerMock, fileType: 'text', highlightJs: false }, + }); + + expect(mockAxios.history.get).toHaveLength(1); + expect(mockAxios.history.get[0].url).toEqual('some_file.js?format=json&viewer=simple'); + }); + it('loads a legacy viewer when a viewer component is not available', async () => { await createComponent({ blob: { ...simpleViewerMock, fileType: 'unknown' } }); @@ -203,44 +217,39 @@ describe('Blob content viewer component', () => { describe('Blob viewer', () => { afterEach(() => { loadViewer.mockRestore(); - viewerProps.mockRestore(); }); it('does not render a BlobContent component if a Blob viewer is available', async () => { loadViewer.mockReturnValue(() => true); await createComponent({ blob: richViewerMock }); - + await waitForPromises(); expect(findBlobContent().exists()).toBe(false); }); it.each` - viewer | loadViewerReturnValue | viewerPropsReturnValue - ${'empty'} | ${EmptyViewer} | ${{}} - ${'download'} | ${DownloadViewer} | ${{ filePath: '/some/file/path', fileName: 'test.js', fileSize: 100 }} - ${'text'} | ${SourceViewer} | ${{ content: 'test', autoDetect: true }} - `( - 'renders viewer component for $viewer files', - async ({ viewer, loadViewerReturnValue, viewerPropsReturnValue }) => { - loadViewer.mockReturnValue(loadViewerReturnValue); - viewerProps.mockReturnValue(viewerPropsReturnValue); - - createComponent({ - blob: { - ...simpleViewerMock, - fileType: 'null', - simpleViewer: { - ...simpleViewerMock.simpleViewer, - fileType: viewer, - }, + viewer | loadViewerReturnValue + ${'empty'} | ${EmptyViewer} + ${'download'} | ${DownloadViewer} + ${'text'} | ${SourceViewer} + `('renders viewer component for $viewer files', async ({ viewer, loadViewerReturnValue }) => { + loadViewer.mockReturnValue(loadViewerReturnValue); + + createComponent({ + blob: { + ...simpleViewerMock, + fileType: 'null', + simpleViewer: { + ...simpleViewerMock.simpleViewer, + fileType: viewer, }, - }); + }, + }); - await nextTick(); + await waitForPromises(); - expect(loadViewer).toHaveBeenCalledWith(viewer); - expect(wrapper.findComponent(loadViewerReturnValue).exists()).toBe(true); - }, - ); + expect(loadViewer).toHaveBeenCalledWith(viewer, false); + expect(wrapper.findComponent(loadViewerReturnValue).exists()).toBe(true); + }); }); describe('BlobHeader action slot', () => { @@ -354,6 +363,19 @@ describe('Blob content viewer component', () => { }); describe('blob info query', () => { + it.each` + highlightJs | shouldFetchRawText + ${true} | ${true} + ${false} | ${false} + `( + 'calls blob info query with shouldFetchRawText: $shouldFetchRawText when highlightJs (feature flag): $highlightJs', + async ({ highlightJs, shouldFetchRawText }) => { + await createComponent({ highlightJs }); + + expect(mockResolver).toHaveBeenCalledWith(expect.objectContaining({ shouldFetchRawText })); + }, + ); + it('is called with originalBranch value if the prop has a value', async () => { await createComponent({ inject: { originalBranch: 'some-branch' } }); diff --git a/spec/frontend/repository/components/blob_controls_spec.js b/spec/frontend/repository/components/blob_controls_spec.js index 03e389ea5cb..6da1861ea7c 100644 --- a/spec/frontend/repository/components/blob_controls_spec.js +++ b/spec/frontend/repository/components/blob_controls_spec.js @@ -1,6 +1,6 @@ -import { createLocalVue } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; 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'; @@ -16,10 +16,8 @@ let router; let wrapper; let mockResolver; -const localVue = createLocalVue(); - const createComponent = async () => { - localVue.use(VueApollo); + Vue.use(VueApollo); const project = { ...blobControlsDataMock }; const projectPath = 'some/project'; @@ -31,7 +29,6 @@ const createComponent = async () => { mockResolver = jest.fn().mockResolvedValue({ data: { project } }); wrapper = shallowMountExtended(BlobControls, { - localVue, router, apolloProvider: createMockApollo([[blobControlsQuery, mockResolver]]), propsData: { projectPath }, diff --git a/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js index c71b2b3c55c..5fe25ced302 100644 --- a/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js +++ b/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js @@ -6,42 +6,33 @@ import DownloadViewer from '~/repository/components/blob_viewers/download_viewer describe('Text Viewer', () => { let wrapper; - const DEFAULT_PROPS = { - fileName: 'file_name.js', - filePath: '/some/file/path', - fileSize: 2269674, + const DEFAULT_BLOB_DATA = { + name: 'file_name.js', + rawPath: '/some/file/path', + rawSize: 2269674, }; - const createComponent = (props = {}) => { + const createComponent = (blobData = {}) => { wrapper = shallowMount(DownloadViewer, { propsData: { - ...DEFAULT_PROPS, - ...props, + blob: { + ...DEFAULT_BLOB_DATA, + ...blobData, + }, }, }); }; - it('renders component', () => { - createComponent(); - - const { fileName, filePath, fileSize } = DEFAULT_PROPS; - expect(wrapper.props()).toMatchObject({ - fileName, - filePath, - fileSize, - }); - }); - it('renders download human readable file size text', () => { createComponent(); - const downloadText = `Download (${numberToHumanSize(DEFAULT_PROPS.fileSize)})`; + const downloadText = `Download (${numberToHumanSize(DEFAULT_BLOB_DATA.rawSize)})`; expect(wrapper.text()).toBe(downloadText); }); it('renders download text', () => { createComponent({ - fileSize: 0, + rawSize: 0, }); expect(wrapper.text()).toBe('Download'); @@ -49,13 +40,13 @@ describe('Text Viewer', () => { it('renders download link', () => { createComponent(); - const { filePath, fileName } = DEFAULT_PROPS; + const { rawPath, name } = DEFAULT_BLOB_DATA; expect(wrapper.findComponent(GlLink).attributes()).toMatchObject({ rel: 'nofollow', target: '_blank', - href: filePath, - download: fileName, + href: rawPath, + download: name, }); }); diff --git a/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js index 6735dddf51e..c23de0efdfd 100644 --- a/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js +++ b/spec/frontend/repository/components/blob_viewers/image_viewer_spec.js @@ -4,13 +4,13 @@ import ImageViewer from '~/repository/components/blob_viewers/image_viewer.vue'; describe('Image Viewer', () => { let wrapper; - const propsData = { - url: 'some/image.png', - alt: 'image.png', + const DEFAULT_BLOB_DATA = { + rawPath: 'some/image.png', + name: 'image.png', }; const createComponent = () => { - wrapper = shallowMount(ImageViewer, { propsData }); + wrapper = shallowMount(ImageViewer, { propsData: { blob: DEFAULT_BLOB_DATA } }); }; const findImage = () => wrapper.find('[data-testid="image"]'); @@ -19,7 +19,7 @@ describe('Image Viewer', () => { createComponent(); expect(findImage().exists()).toBe(true); - expect(findImage().attributes('src')).toBe(propsData.url); - expect(findImage().attributes('alt')).toBe(propsData.alt); + expect(findImage().attributes('src')).toBe(DEFAULT_BLOB_DATA.rawPath); + expect(findImage().attributes('alt')).toBe(DEFAULT_BLOB_DATA.name); }); }); diff --git a/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js new file mode 100644 index 00000000000..5caeb85834d --- /dev/null +++ b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js @@ -0,0 +1,41 @@ +import { GlLink, GlSprintf } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import LfsViewer from '~/repository/components/blob_viewers/lfs_viewer.vue'; + +describe('LFS Viewer', () => { + let wrapper; + + const DEFAULT_BLOB_DATA = { + name: 'file_name.js', + rawPath: '/some/file/path', + }; + + const createComponent = () => { + wrapper = shallowMount(LfsViewer, { + propsData: { blob: { ...DEFAULT_BLOB_DATA } }, + stubs: { GlSprintf }, + }); + }; + + const findLink = () => wrapper.findComponent(GlLink); + + beforeEach(() => createComponent()); + + afterEach(() => wrapper.destroy()); + + it('renders the correct text', () => { + expect(wrapper.text()).toBe( + 'This content could not be displayed because it is stored in LFS. You can download it instead.', + ); + }); + + it('renders download link', () => { + const { rawPath, name } = DEFAULT_BLOB_DATA; + + expect(findLink().attributes()).toMatchObject({ + target: '_blank', + href: rawPath, + download: name, + }); + }); +}); diff --git a/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js index fd910002529..10eea691335 100644 --- a/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js +++ b/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js @@ -6,10 +6,12 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; describe('PDF Viewer', () => { let wrapper; - const defaultPropsData = { url: 'some/pdf_blob.pdf' }; + const DEFAULT_BLOB_DATA = { rawPath: 'some/pdf_blob.pdf' }; - const createComponent = (fileSize = 999) => { - wrapper = shallowMountExtended(Component, { propsData: { ...defaultPropsData, fileSize } }); + const createComponent = (rawSize = 999) => { + wrapper = shallowMountExtended(Component, { + propsData: { blob: { ...DEFAULT_BLOB_DATA, rawSize } }, + }); }; const findPDFViewer = () => wrapper.findComponent(PdfViewer); @@ -20,7 +22,7 @@ describe('PDF Viewer', () => { createComponent(); expect(findPDFViewer().exists()).toBe(true); - expect(findPDFViewer().props('pdf')).toBe(defaultPropsData.url); + expect(findPDFViewer().props('pdf')).toBe(DEFAULT_BLOB_DATA.rawPath); }); describe('Too large', () => { diff --git a/spec/frontend/repository/components/blob_viewers/video_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/video_viewer_spec.js index 34448c03b31..2e79a1496ce 100644 --- a/spec/frontend/repository/components/blob_viewers/video_viewer_spec.js +++ b/spec/frontend/repository/components/blob_viewers/video_viewer_spec.js @@ -4,10 +4,10 @@ import VideoViewer from '~/repository/components/blob_viewers/video_viewer.vue'; describe('Video Viewer', () => { let wrapper; - const propsData = { url: 'some/video.mp4' }; + const DEFAULT_BLOB_DATA = { rawPath: 'some/video.mp4' }; const createComponent = () => { - wrapper = shallowMountExtended(VideoViewer, { propsData }); + wrapper = shallowMountExtended(VideoViewer, { propsData: { blob: { ...DEFAULT_BLOB_DATA } } }); }; const findVideo = () => wrapper.findByTestId('video'); @@ -16,7 +16,7 @@ describe('Video Viewer', () => { createComponent(); expect(findVideo().exists()).toBe(true); - expect(findVideo().attributes('src')).toBe(propsData.url); + expect(findVideo().attributes('src')).toBe(DEFAULT_BLOB_DATA.rawPath); expect(findVideo().attributes('controls')).not.toBeUndefined(); }); }); diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js index ad2cbd70187..0e300291d05 100644 --- a/spec/frontend/repository/components/breadcrumbs_spec.js +++ b/spec/frontend/repository/components/breadcrumbs_spec.js @@ -1,5 +1,6 @@ import { GlDropdown } from '@gitlab/ui'; import { shallowMount, RouterLinkStub } from '@vue/test-utils'; +import { nextTick } from 'vue'; import Breadcrumbs from '~/repository/components/breadcrumbs.vue'; import UploadBlobModal from '~/repository/components/upload_blob_modal.vue'; import NewDirectoryModal from '~/repository/components/new_directory_modal.vue'; @@ -79,7 +80,7 @@ describe('Repository breadcrumbs component', () => { // eslint-disable-next-line no-restricted-syntax wrapper.setData({ userPermissions: { forkProject: false, createMergeRequestIn: false } }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(GlDropdown).exists()).toBe(false); }); @@ -106,7 +107,7 @@ describe('Repository breadcrumbs component', () => { // eslint-disable-next-line no-restricted-syntax wrapper.setData({ userPermissions: { forkProject: true, createMergeRequestIn: true } }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(GlDropdown).exists()).toBe(true); }); @@ -125,7 +126,7 @@ describe('Repository breadcrumbs component', () => { // eslint-disable-next-line no-restricted-syntax wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findUploadBlobModal().exists()).toBe(true); }); @@ -149,7 +150,7 @@ describe('Repository breadcrumbs component', () => { // eslint-disable-next-line no-restricted-syntax wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findNewDirectoryModal().exists()).toBe(true); }); diff --git a/spec/frontend/repository/components/last_commit_spec.js b/spec/frontend/repository/components/last_commit_spec.js index fe05a981845..bb710c3a96c 100644 --- a/spec/frontend/repository/components/last_commit_spec.js +++ b/spec/frontend/repository/components/last_commit_spec.js @@ -1,5 +1,6 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import LastCommit from '~/repository/components/last_commit.vue'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; @@ -63,7 +64,7 @@ describe('Repository last commit component', () => { `('$label when loading icon $loading is true', async ({ loading }) => { factory(createCommitData(), loading); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find(GlLoadingIcon).exists()).toBe(loading); }); @@ -71,7 +72,7 @@ describe('Repository last commit component', () => { it('renders commit widget', async () => { factory(); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.element).toMatchSnapshot(); }); @@ -79,7 +80,7 @@ describe('Repository last commit component', () => { it('renders short commit ID', async () => { factory(); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('[data-testid="last-commit-id-label"]').text()).toEqual('12345678'); }); @@ -87,7 +88,7 @@ describe('Repository last commit component', () => { it('hides pipeline components when pipeline does not exist', async () => { factory(createCommitData({ pipeline: null })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.js-commit-pipeline').exists()).toBe(false); }); @@ -95,7 +96,7 @@ describe('Repository last commit component', () => { it('renders pipeline components', async () => { factory(); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.js-commit-pipeline').exists()).toBe(true); }); @@ -103,7 +104,7 @@ describe('Repository last commit component', () => { it('hides author component when author does not exist', async () => { factory(createCommitData({ author: null })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.js-user-link').exists()).toBe(false); expect(vm.find(UserAvatarLink).exists()).toBe(false); @@ -112,7 +113,7 @@ describe('Repository last commit component', () => { it('does not render description expander when description is null', async () => { factory(createCommitData({ descriptionHtml: null })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.text-expander').exists()).toBe(false); expect(vm.find('.commit-row-description').exists()).toBe(false); @@ -121,11 +122,11 @@ describe('Repository last commit component', () => { it('expands commit description when clicking expander', async () => { factory(createCommitData({ descriptionHtml: 'Test description' })); - await vm.vm.$nextTick(); + await nextTick(); vm.find('.text-expander').vm.$emit('click'); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.commit-row-description').isVisible()).toBe(true); expect(vm.find('.text-expander').classes('open')).toBe(true); @@ -134,7 +135,7 @@ describe('Repository last commit component', () => { it('strips the first newline of the description', async () => { factory(createCommitData({ descriptionHtml: '
Update ADOPTERS.md' })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.commit-row-description').html()).toBe( '<pre class="commit-row-description gl-mb-3">Update ADOPTERS.md</pre>', @@ -144,7 +145,7 @@ describe('Repository last commit component', () => { it('renders the signature HTML as returned by the backend', async () => { factory(createCommitData({ signatureHtml: '<button>Verified</button>' })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.element).toMatchSnapshot(); }); @@ -152,7 +153,7 @@ describe('Repository last commit component', () => { it('sets correct CSS class if the commit message is empty', async () => { factory(createCommitData({ message: '' })); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find('.item-title').classes()).toContain(emptyMessageClass); }); diff --git a/spec/frontend/repository/components/preview/index_spec.js b/spec/frontend/repository/components/preview/index_spec.js index 2490258a048..0d9bfc62ed5 100644 --- a/spec/frontend/repository/components/preview/index_spec.js +++ b/spec/frontend/repository/components/preview/index_spec.js @@ -1,5 +1,6 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import { handleLocationHash } from '~/lib/utils/common_utils'; import Preview from '~/repository/components/preview/index.vue'; @@ -28,7 +29,7 @@ describe('Repository file preview component', () => { vm.destroy(); }); - it('renders file HTML', () => { + it('renders file HTML', async () => { factory({ webPath: 'http://test.com', name: 'README.md', @@ -38,12 +39,11 @@ describe('Repository file preview component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ readme: { html: '<div class="blob">test</div>' } }); - return vm.vm.$nextTick(() => { - expect(vm.element).toMatchSnapshot(); - }); + await nextTick(); + expect(vm.element).toMatchSnapshot(); }); - it('handles hash after render', () => { + it('handles hash after render', async () => { factory({ webPath: 'http://test.com', name: 'README.md', @@ -53,15 +53,11 @@ describe('Repository file preview component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ readme: { html: '<div class="blob">test</div>' } }); - return vm.vm - .$nextTick() - .then(vm.vm.$nextTick()) - .then(() => { - expect(handleLocationHash).toHaveBeenCalled(); - }); + await nextTick(); + expect(handleLocationHash).toHaveBeenCalled(); }); - it('renders loading icon', () => { + it('renders loading icon', async () => { factory({ webPath: 'http://test.com', name: 'README.md', @@ -71,8 +67,7 @@ describe('Repository file preview component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ loading: 1 }); - return vm.vm.$nextTick(() => { - expect(vm.find(GlLoadingIcon).exists()).toBe(true); - }); + await nextTick(); + expect(vm.find(GlLoadingIcon).exists()).toBe(true); }); }); diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js index 2cd88944f81..07c151ad935 100644 --- a/spec/frontend/repository/components/table/index_spec.js +++ b/spec/frontend/repository/components/table/index_spec.js @@ -1,5 +1,6 @@ import { GlDeprecatedSkeletonLoading as GlSkeletonLoading, GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import Table from '~/repository/components/table/index.vue'; import TableRow from '~/repository/components/table/row.vue'; @@ -86,18 +87,17 @@ describe('Repository table component', () => { ${'/'} | ${'main'} ${'app/assets'} | ${'main'} ${'/'} | ${'test'} - `('renders table caption for $ref in $path', ({ path, ref }) => { + `('renders table caption for $ref in $path', async ({ 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(() => { - expect(vm.find('.table').attributes('aria-label')).toEqual( - `Files, directories, and submodules in the path ${path} for commit reference ${ref}`, - ); - }); + await nextTick(); + expect(vm.find('.table').attributes('aria-label')).toEqual( + `Files, directories, and submodules in the path ${path} for commit reference ${ref}`, + ); }); it('shows loading icon', () => { @@ -140,7 +140,7 @@ describe('Repository table component', () => { showMoreButton().vm.$emit('click'); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.emitted('showMore')).toHaveLength(1); }); diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js index 440baa72a3c..22570b2d6ed 100644 --- a/spec/frontend/repository/components/table/row_spec.js +++ b/spec/frontend/repository/components/table/row_spec.js @@ -1,5 +1,6 @@ import { GlBadge, GlLink, GlIcon, GlIntersectionObserver } from '@gitlab/ui'; import { shallowMount, RouterLinkStub } from '@vue/test-utils'; +import { nextTick } from 'vue'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import TableRow from '~/repository/components/table/row.vue'; import FileIcon from '~/vue_shared/components/file_icon.vue'; @@ -53,7 +54,7 @@ describe('Repository table row component', () => { vm.destroy(); }); - it('renders table row', () => { + it('renders table row', async () => { factory({ id: '1', sha: '123', @@ -62,12 +63,11 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.element).toMatchSnapshot(); - }); + await nextTick(); + expect(vm.element).toMatchSnapshot(); }); - it('renders a symlink table row', () => { + it('renders a symlink table row', async () => { factory({ id: '1', sha: '123', @@ -77,12 +77,11 @@ describe('Repository table row component', () => { mode: FILE_SYMLINK_MODE, }); - return vm.vm.$nextTick().then(() => { - expect(vm.element).toMatchSnapshot(); - }); + await nextTick(); + expect(vm.element).toMatchSnapshot(); }); - it('renders table row for path with special character', () => { + it('renders table row for path with special character', async () => { factory({ id: '1', sha: '123', @@ -91,9 +90,8 @@ describe('Repository table row component', () => { currentPath: 'test$', }); - return vm.vm.$nextTick().then(() => { - expect(vm.element).toMatchSnapshot(); - }); + await nextTick(); + expect(vm.element).toMatchSnapshot(); }); it('renders a gl-hover-load directive', () => { @@ -116,7 +114,7 @@ describe('Repository table row component', () => { ${'tree'} | ${RouterLinkStub} | ${'RouterLink'} ${'blob'} | ${RouterLinkStub} | ${'RouterLink'} ${'commit'} | ${'a'} | ${'hyperlink'} - `('renders a $componentName for type $type', ({ type, component }) => { + `('renders a $componentName for type $type', async ({ type, component }) => { factory({ id: '1', sha: '123', @@ -125,16 +123,15 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find(component).exists()).toBe(true); - }); + await nextTick(); + expect(vm.find(component).exists()).toBe(true); }); it.each` path ${'test#'} ${'Ă„nderungen'} - `('renders link for $path', ({ path }) => { + `('renders link for $path', async ({ path }) => { factory({ id: '1', sha: '123', @@ -143,14 +140,13 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find({ ref: 'link' }).props('to')).toEqual({ - path: `/-/tree/main/${encodeURIComponent(path)}`, - }); + await nextTick(); + expect(vm.find({ ref: 'link' }).props('to')).toEqual({ + path: `/-/tree/main/${encodeURIComponent(path)}`, }); }); - it('renders link for directory with hash', () => { + it('renders link for directory with hash', async () => { factory({ id: '1', sha: '123', @@ -159,12 +155,11 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find('.tree-item-link').props('to')).toEqual({ path: '/-/tree/main/test%23' }); - }); + await nextTick(); + expect(vm.find('.tree-item-link').props('to')).toEqual({ path: '/-/tree/main/test%23' }); }); - it('renders commit ID for submodule', () => { + it('renders commit ID for submodule', async () => { factory({ id: '1', sha: '123', @@ -173,12 +168,11 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find('.commit-sha').text()).toContain('1'); - }); + await nextTick(); + expect(vm.find('.commit-sha').text()).toContain('1'); }); - it('renders link with href', () => { + it('renders link with href', async () => { factory({ id: '1', sha: '123', @@ -188,12 +182,11 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find('a').attributes('href')).toEqual('https://test.com'); - }); + await nextTick(); + expect(vm.find('a').attributes('href')).toEqual('https://test.com'); }); - it('renders LFS badge', () => { + it('renders LFS badge', async () => { factory({ id: '1', sha: '123', @@ -203,12 +196,11 @@ describe('Repository table row component', () => { lfsOid: '1', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find(GlBadge).exists()).toBe(true); - }); + await nextTick(); + expect(vm.find(GlBadge).exists()).toBe(true); }); - it('renders commit and web links with href for submodule', () => { + it('renders commit and web links with href for submodule', async () => { factory({ id: '1', sha: '123', @@ -219,13 +211,12 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find('a').attributes('href')).toEqual('https://test.com'); - expect(vm.find(GlLink).attributes('href')).toEqual('https://test.com/commit'); - }); + await nextTick(); + expect(vm.find('a').attributes('href')).toEqual('https://test.com'); + expect(vm.find(GlLink).attributes('href')).toEqual('https://test.com/commit'); }); - it('renders lock icon', () => { + it('renders lock icon', async () => { factory({ id: '1', sha: '123', @@ -234,10 +225,9 @@ describe('Repository table row component', () => { currentPath: '/', }); - return vm.vm.$nextTick().then(() => { - expect(vm.find(GlIcon).exists()).toBe(true); - expect(vm.find(GlIcon).props('name')).toBe('lock'); - }); + await nextTick(); + expect(vm.find(GlIcon).exists()).toBe(true); + expect(vm.find(GlIcon).props('name')).toBe('lock'); }); it('renders loading icon when path is loading', () => { diff --git a/spec/frontend/repository/components/tree_content_spec.js b/spec/frontend/repository/components/tree_content_spec.js index 00ad1fc05f6..9d3a5394df8 100644 --- a/spec/frontend/repository/components/tree_content_spec.js +++ b/spec/frontend/repository/components/tree_content_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql'; import FilePreview from '~/repository/components/preview/index.vue'; import FileTable from '~/repository/components/table/index.vue'; @@ -50,7 +51,7 @@ describe('Repository table component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ entries: { blobs: [{ name: 'README.md' }] } }); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.find(FilePreview).exists()).toBe(true); }); @@ -60,7 +61,7 @@ describe('Repository table component', () => { jest.spyOn(vm.vm, 'fetchFiles').mockImplementation(() => {}); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.vm.fetchFiles).toHaveBeenCalled(); expect(resetRequestedCommits).toHaveBeenCalled(); @@ -111,7 +112,7 @@ describe('Repository table component', () => { it('is changes hasShowMore to false when "showMore" event is emitted', async () => { findFileTable().vm.$emit('showMore'); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.vm.hasShowMore).toBe(false); }); @@ -119,7 +120,7 @@ describe('Repository table component', () => { it('changes clickedShowMore when "showMore" event is emitted', async () => { findFileTable().vm.$emit('showMore'); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.vm.clickedShowMore).toBe(true); }); @@ -140,7 +141,7 @@ describe('Repository table component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ fetchCounter: 5, clickedShowMore: false }); - await vm.vm.$nextTick(); + await nextTick(); expect(vm.vm.hasShowMore).toBe(false); }); @@ -161,7 +162,7 @@ describe('Repository table component', () => { // eslint-disable-next-line no-restricted-syntax vm.setData({ entries: { blobs }, pagesLoaded }); - await vm.vm.$nextTick(); + await nextTick(); expect(findFileTable().props('hasMore')).toBe(limitReached); }); diff --git a/spec/frontend/repository/components/upload_blob_modal_spec.js b/spec/frontend/repository/components/upload_blob_modal_spec.js index 6b8b0752485..bf024baa627 100644 --- a/spec/frontend/repository/components/upload_blob_modal_spec.js +++ b/spec/frontend/repository/components/upload_blob_modal_spec.js @@ -2,6 +2,7 @@ import { GlModal, GlFormInput, GlFormTextarea, GlToggle, GlAlert } from '@gitlab import { shallowMount } from '@vue/test-utils'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; +import { nextTick } from 'vue'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; import httpStatusCodes from '~/lib/utils/http_status'; @@ -113,7 +114,7 @@ describe('UploadBlobModal', () => { // eslint-disable-next-line no-restricted-syntax wrapper.setData({ target: 'Not main' }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findMrToggle().exists()).toBe(true); }); @@ -202,7 +203,7 @@ describe('UploadBlobModal', () => { wrapper.vm.uploadFile = jest.fn(); wrapper.vm.replaceFile = jest.fn(); wrapper.vm.submitForm(); - await wrapper.vm.$nextTick(); + await nextTick(); }; const submitRequest = async () => { diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js index a5ee17ba672..5a6551cb94a 100644 --- a/spec/frontend/repository/mock_data.js +++ b/spec/frontend/repository/mock_data.js @@ -5,16 +5,20 @@ export const simpleViewerMock = { rawSize: 123, rawTextBlob: 'raw content', fileType: 'text', + language: 'javascript', path: 'some_file.js', webPath: 'some_file.js', editBlobPath: 'some_file.js/edit', ideEditPath: 'some_file.js/ide/edit', forkAndEditPath: 'some_file.js/fork/edit', ideForkAndEditPath: 'some_file.js/fork/ide', + environmentFormattedExternalUrl: '', + environmentExternalUrlForRouteMap: '', canModifyBlob: true, canCurrentUserPushToBranch: true, archived: false, storedExternally: false, + externalStorageUrl: '', externalStorage: 'lfs', rawPath: 'some_file.js', replacePath: 'some_file.js/replace', @@ -46,6 +50,7 @@ export const userPermissionsMock = { }; export const projectMock = { + __typename: 'Project', id: '1234', userPermissions: userPermissionsMock, pathLocks: { |