summaryrefslogtreecommitdiff
path: root/spec/frontend/repository/components
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 20:02:30 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 20:02:30 +0000
commit41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch)
tree9c8d89a8624828992f06d892cd2f43818ff5dcc8 /spec/frontend/repository/components
parent0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff)
downloadgitlab-ce-41fe97390ceddf945f3d967b8fdb3de4c66b7dea.tar.gz
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'spec/frontend/repository/components')
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js106
-rw-r--r--spec/frontend/repository/components/blob_edit_spec.js100
-rw-r--r--spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js23
-rw-r--r--spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js27
-rw-r--r--spec/frontend/repository/components/blob_viewers/download_viewer_spec.js11
-rw-r--r--spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js11
-rw-r--r--spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js26
-rw-r--r--spec/frontend/repository/components/breadcrumbs_spec.js14
8 files changed, 180 insertions, 138 deletions
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 109e5cef49b..96c03419dd6 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
@@ -10,20 +11,26 @@ import BlobContent from '~/blob/components/blob_content.vue';
import BlobHeader from '~/blob/components/blob_header.vue';
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 WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
import ForkSuggestion from '~/repository/components/fork_suggestion.vue';
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/source_viewer.vue';
import blobInfoQuery from '~/repository/queries/blob_info.query.graphql';
+import userInfoQuery from '~/repository/queries/user_info.query.graphql';
+import applicationInfoQuery from '~/repository/queries/application_info.query.graphql';
+import CodeIntelligence from '~/code_navigation/components/app.vue';
import { redirectTo } from '~/lib/utils/url_utility';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import httpStatusCodes from '~/lib/utils/http_status';
import {
simpleViewerMock,
richViewerMock,
projectMock,
+ userInfoMock,
+ applicationInfoMock,
userPermissionsMock,
propsMock,
refMock,
@@ -35,9 +42,14 @@ jest.mock('~/lib/utils/common_utils');
let wrapper;
let mockResolver;
+let userInfoMockResolver;
+let applicationInfoMockResolver;
const mockAxios = new MockAdapter(axios);
+const createMockStore = () =>
+ new Vuex.Store({ actions: { fetchData: jest.fn, setInitialData: jest.fn() } });
+
const createComponent = async (mockData = {}, mountFn = shallowMount) => {
Vue.use(VueApollo);
@@ -71,10 +83,23 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
data: { isBinary, project },
});
- const fakeApollo = createMockApollo([[blobInfoQuery, mockResolver]]);
+ userInfoMockResolver = jest.fn().mockResolvedValue({
+ data: { ...userInfoMock },
+ });
+
+ applicationInfoMockResolver = jest.fn().mockResolvedValue({
+ data: { ...applicationInfoMock },
+ });
+
+ const fakeApollo = createMockApollo([
+ [blobInfoQuery, mockResolver],
+ [userInfoQuery, userInfoMockResolver],
+ [applicationInfoQuery, applicationInfoMockResolver],
+ ]);
wrapper = extendedWrapper(
mountFn(BlobContentViewer, {
+ store: createMockStore(),
apolloProvider: fakeApollo,
propsData: propsMock,
mixins: [{ data: () => ({ ref: refMock }) }],
@@ -96,16 +121,21 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
await waitForPromises();
};
+const execImmediately = (callback) => {
+ callback();
+};
+
describe('Blob content viewer component', () => {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findBlobHeader = () => wrapper.findComponent(BlobHeader);
- const findBlobEdit = () => wrapper.findComponent(BlobEdit);
- const findPipelineEditor = () => wrapper.findByTestId('pipeline-editor');
+ const findWebIdeLink = () => wrapper.findComponent(WebIdeLink);
const findBlobContent = () => wrapper.findComponent(BlobContent);
const findBlobButtonGroup = () => wrapper.findComponent(BlobButtonGroup);
const findForkSuggestion = () => wrapper.findComponent(ForkSuggestion);
+ const findCodeIntelligence = () => wrapper.findComponent(CodeIntelligence);
beforeEach(() => {
+ jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
isLoggedIn.mockReturnValue(true);
});
@@ -219,6 +249,26 @@ describe('Blob content viewer component', () => {
loadViewer.mockRestore();
});
+ it('renders a CodeIntelligence component with the correct props', async () => {
+ loadViewer.mockReturnValue(SourceViewer);
+
+ await createComponent();
+
+ expect(findCodeIntelligence().props()).toMatchObject({
+ codeNavigationPath: simpleViewerMock.codeNavigationPath,
+ blobPath: simpleViewerMock.path,
+ pathPrefix: simpleViewerMock.projectBlobPathRoot,
+ });
+ });
+
+ it('does not load a CodeIntelligence component when no viewers are loaded', async () => {
+ const url = 'some_file.js?format=json&viewer=rich';
+ mockAxios.onGet(url).replyOnce(httpStatusCodes.INTERNAL_SERVER_ERROR);
+ await createComponent({ blob: { ...richViewerMock, fileType: 'unknown' } });
+
+ expect(findCodeIntelligence().exists()).toBe(false);
+ });
+
it('does not render a BlobContent component if a Blob viewer is available', async () => {
loadViewer.mockReturnValue(() => true);
await createComponent({ blob: richViewerMock });
@@ -255,45 +305,43 @@ describe('Blob content viewer component', () => {
describe('BlobHeader action slot', () => {
const { ideEditPath, editBlobPath } = simpleViewerMock;
- it('renders BlobHeaderEdit buttons in simple viewer', async () => {
+ it('renders WebIdeLink button in simple viewer', async () => {
await createComponent({ inject: { BlobContent: true, BlobReplace: true } }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: true,
+ showGitpodButton: applicationInfoMock.gitpodEnabled,
+ gitpodEnabled: userInfoMock.currentUser.gitpodEnabled,
+ showPipelineEditorButton: true,
+ gitpodUrl: simpleViewerMock.gitpodBlobUrl,
+ pipelineEditorUrl: simpleViewerMock.pipelineEditorPath,
+ userPreferencesGitpodPath: userInfoMock.currentUser.preferencesGitpodPath,
+ userProfileEnableGitpodPath: userInfoMock.currentUser.profileEnableGitpodPath,
});
});
- it('renders BlobHeaderEdit button in rich viewer', async () => {
+ it('renders WebIdeLink button in rich viewer', async () => {
await createComponent({ blob: richViewerMock }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: true,
});
});
- it('renders BlobHeaderEdit button for binary files', async () => {
+ it('renders WebIdeLink button for binary files', async () => {
await createComponent({ blob: richViewerMock, isBinary: true }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: false,
});
});
- it('renders Pipeline Editor button for .gitlab-ci files', async () => {
- const pipelineEditorPath = 'some/path/.gitlab-ce';
- const blob = { ...simpleViewerMock, pipelineEditorPath };
- await createComponent({ blob, inject: { BlobContent: true, BlobReplace: true } }, mount);
-
- expect(findPipelineEditor().exists()).toBe(true);
- expect(findPipelineEditor().attributes('href')).toBe(pipelineEditorPath);
- });
-
describe('blob header binary file', () => {
it('passes the correct isBinary value when viewing a binary file', async () => {
await createComponent({ blob: richViewerMock, isBinary: true });
@@ -318,7 +366,7 @@ describe('Blob content viewer component', () => {
expect(findBlobHeader().props('hideViewerSwitcher')).toBe(true);
expect(findBlobHeader().props('isBinary')).toBe(true);
- expect(findBlobEdit().props('showEditButton')).toBe(false);
+ expect(findWebIdeLink().props('showEditButton')).toBe(false);
});
});
@@ -401,12 +449,12 @@ describe('Blob content viewer component', () => {
beforeEach(() => createComponent({}, mount));
it('simple edit redirects to the simple editor', () => {
- findBlobEdit().vm.$emit('edit', 'simple');
+ findWebIdeLink().vm.$emit('edit', 'simple');
expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.editBlobPath);
});
it('IDE edit redirects to the IDE editor', () => {
- findBlobEdit().vm.$emit('edit', 'ide');
+ findWebIdeLink().vm.$emit('edit', 'ide');
expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.ideEditPath);
});
@@ -435,7 +483,7 @@ describe('Blob content viewer component', () => {
mount,
);
- findBlobEdit().vm.$emit('edit', 'simple');
+ findWebIdeLink().vm.$emit('edit', 'simple');
await nextTick();
expect(findForkSuggestion().exists()).toBe(showForkSuggestion);
diff --git a/spec/frontend/repository/components/blob_edit_spec.js b/spec/frontend/repository/components/blob_edit_spec.js
deleted file mode 100644
index e2de7bc2957..00000000000
--- a/spec/frontend/repository/components/blob_edit_spec.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import BlobEdit from '~/repository/components/blob_edit.vue';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
-
-const DEFAULT_PROPS = {
- editPath: 'some_file.js/edit',
- webIdePath: 'some_file.js/ide/edit',
- showEditButton: true,
- needsToFork: false,
-};
-
-describe('BlobEdit component', () => {
- let wrapper;
-
- const createComponent = (consolidatedEditButton = false, props = {}) => {
- wrapper = shallowMount(BlobEdit, {
- propsData: {
- ...DEFAULT_PROPS,
- ...props,
- },
- provide: {
- glFeatures: {
- consolidatedEditButton,
- },
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- const findButtons = () => wrapper.findAll(GlButton);
- const findEditButton = () => wrapper.find('[data-testid="edit"]');
- const findWebIdeButton = () => wrapper.find('[data-testid="web-ide"]');
- const findWebIdeLink = () => wrapper.find(WebIdeLink);
-
- it('renders component', () => {
- createComponent();
-
- const { editPath, webIdePath } = DEFAULT_PROPS;
-
- expect(wrapper.props()).toMatchObject({
- editPath,
- webIdePath,
- });
- });
-
- it('renders both buttons', () => {
- createComponent();
-
- expect(findButtons()).toHaveLength(2);
- });
-
- it('renders the Edit button', () => {
- createComponent();
-
- expect(findEditButton().text()).toBe('Edit');
- expect(findEditButton()).not.toBeDisabled();
- });
-
- it('renders the Web IDE button', () => {
- createComponent();
-
- expect(findWebIdeButton().text()).toBe('Web IDE');
- expect(findWebIdeButton()).not.toBeDisabled();
- });
-
- it('renders WebIdeLink component', () => {
- createComponent(true);
-
- const { editPath: editUrl, webIdePath: webIdeUrl, needsToFork } = DEFAULT_PROPS;
-
- expect(findWebIdeLink().props()).toMatchObject({
- editUrl,
- webIdeUrl,
- isBlob: true,
- showEditButton: true,
- needsToFork,
- });
- });
-
- describe('Without Edit button', () => {
- const showEditButton = false;
-
- it('renders WebIdeLink component without an edit button', () => {
- createComponent(true, { showEditButton });
-
- expect(findWebIdeLink().props()).toMatchObject({ showEditButton });
- });
-
- it('does not render an Edit button', () => {
- createComponent(false, { showEditButton });
-
- expect(findEditButton().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js
new file mode 100644
index 00000000000..baf16b57d7d
--- /dev/null
+++ b/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js
@@ -0,0 +1,23 @@
+import { shallowMount } from '@vue/test-utils';
+import AudioViewer from '~/repository/components/blob_viewers/audio_viewer.vue';
+
+describe('Audio Viewer', () => {
+ let wrapper;
+
+ const DEFAULT_BLOB_DATA = {
+ rawPath: 'some/audio.mid',
+ };
+
+ const createComponent = () => {
+ wrapper = shallowMount(AudioViewer, { propsData: { blob: DEFAULT_BLOB_DATA } });
+ };
+
+ const findContent = () => wrapper.find('[data-testid="audio"]');
+
+ it('renders an audio source component', () => {
+ createComponent();
+
+ expect(findContent().exists()).toBe(true);
+ expect(findContent().attributes('src')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+});
diff --git a/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js
new file mode 100644
index 00000000000..7d43e4e660b
--- /dev/null
+++ b/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js
@@ -0,0 +1,27 @@
+import { shallowMount } from '@vue/test-utils';
+import CsvViewer from '~/repository/components/blob_viewers/csv_viewer.vue';
+
+describe('CSV Viewer', () => {
+ let wrapper;
+
+ const DEFAULT_BLOB_DATA = {
+ rawPath: 'some/file.csv',
+ name: 'file.csv',
+ };
+
+ const createComponent = () => {
+ wrapper = shallowMount(CsvViewer, {
+ propsData: { blob: DEFAULT_BLOB_DATA },
+ stubs: ['CsvViewer'],
+ });
+ };
+
+ const findCsvViewerComp = () => wrapper.find('[data-testid="csv"]');
+
+ it('renders a Source Editor component', () => {
+ createComponent();
+ expect(findCsvViewerComp().exists()).toBe(true);
+ expect(findCsvViewerComp().props('remoteFile')).toBeTruthy();
+ expect(findCsvViewerComp().props('csv')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+});
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 5fe25ced302..0a91e5ce890 100644
--- a/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js
@@ -23,6 +23,8 @@ describe('Text Viewer', () => {
});
};
+ const findLink = () => wrapper.findComponent(GlLink);
+
it('renders download human readable file size text', () => {
createComponent();
@@ -42,7 +44,7 @@ describe('Text Viewer', () => {
createComponent();
const { rawPath, name } = DEFAULT_BLOB_DATA;
- expect(wrapper.findComponent(GlLink).attributes()).toMatchObject({
+ expect(findLink().attributes()).toMatchObject({
rel: 'nofollow',
target: '_blank',
href: rawPath,
@@ -50,6 +52,13 @@ describe('Text Viewer', () => {
});
});
+ it('renders the correct link href when stored externally', () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ createComponent({ externalStorageUrl });
+
+ expect(findLink().attributes('href')).toBe(externalStorageUrl);
+ });
+
it('renders download icon', () => {
createComponent();
diff --git a/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
index 5caeb85834d..599443bf862 100644
--- a/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
@@ -10,9 +10,9 @@ describe('LFS Viewer', () => {
rawPath: '/some/file/path',
};
- const createComponent = () => {
+ const createComponent = (blobData = {}) => {
wrapper = shallowMount(LfsViewer, {
- propsData: { blob: { ...DEFAULT_BLOB_DATA } },
+ propsData: { blob: { ...DEFAULT_BLOB_DATA, ...blobData } },
stubs: { GlSprintf },
});
};
@@ -38,4 +38,11 @@ describe('LFS Viewer', () => {
download: name,
});
});
+
+ it('renders the correct link href when stored externally', () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ createComponent({ externalStorageUrl });
+
+ expect(findLink().attributes('href')).toBe(externalStorageUrl);
+ });
});
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 10eea691335..b61500ea0ad 100644
--- a/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js
@@ -1,4 +1,5 @@
import { GlButton } from '@gitlab/ui';
+import { nextTick } from 'vue';
import Component from '~/repository/components/blob_viewers/pdf_viewer.vue';
import PdfViewer from '~/blob/pdf/pdf_viewer.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -8,9 +9,9 @@ describe('PDF Viewer', () => {
const DEFAULT_BLOB_DATA = { rawPath: 'some/pdf_blob.pdf' };
- const createComponent = (rawSize = 999) => {
+ const createComponent = (rawSize = 999, externalStorageUrl) => {
wrapper = shallowMountExtended(Component, {
- propsData: { blob: { ...DEFAULT_BLOB_DATA, rawSize } },
+ propsData: { blob: { ...DEFAULT_BLOB_DATA, rawSize, externalStorageUrl } },
});
};
@@ -45,10 +46,14 @@ describe('PDF Viewer', () => {
});
describe('Too many pages', () => {
- beforeEach(() => {
- createComponent();
- findPDFViewer().vm.$emit('pdflabload', 100);
- });
+ const loadComponent = (externalStorageUrl) => {
+ const rawSize = 999;
+ const totalPages = 100;
+ createComponent(rawSize, externalStorageUrl);
+ findPDFViewer().vm.$emit('pdflabload', totalPages);
+ };
+
+ beforeEach(() => loadComponent());
it('does not a PDF Viewer component', () => {
expect(findPDFViewer().exists()).toBe(false);
@@ -56,6 +61,15 @@ describe('PDF Viewer', () => {
it('renders a download button', () => {
expect(findDownLoadButton().exists()).toBe(true);
+ expect(findDownLoadButton().attributes('href')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+
+ it('renders the correct href when stored externally', async () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ loadComponent(externalStorageUrl);
+ await nextTick();
+
+ expect(findDownLoadButton().attributes('href')).toBe(externalStorageUrl);
});
});
});
diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js
index 0e300291d05..0e3e7075e99 100644
--- a/spec/frontend/repository/components/breadcrumbs_spec.js
+++ b/spec/frontend/repository/components/breadcrumbs_spec.js
@@ -59,6 +59,20 @@ describe('Repository breadcrumbs component', () => {
expect(wrapper.findAll(RouterLinkStub).length).toEqual(linkCount);
});
+ it.each`
+ routeName | path | linkTo
+ ${'treePath'} | ${'app/assets/javascripts'} | ${'/-/tree/app/assets/javascripts'}
+ ${'treePathDecoded'} | ${'app/assets/javascripts'} | ${'/-/tree/app/assets/javascripts'}
+ ${'blobPath'} | ${'app/assets/index.js'} | ${'/-/blob/app/assets/index.js'}
+ ${'blobPathDecoded'} | ${'app/assets/index.js'} | ${'/-/blob/app/assets/index.js'}
+ `(
+ 'links to the correct router path when routeName is $routeName',
+ ({ routeName, path, linkTo }) => {
+ factory(path, {}, { name: routeName });
+ expect(wrapper.findAll(RouterLinkStub).at(3).props('to')).toEqual(linkTo);
+ },
+ );
+
it('escapes hash in directory path', () => {
factory('app/assets/javascripts#');