debian-mirror-gitlab/spec/frontend/snippets/components/snippet_blob_view_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

312 lines
10 KiB
JavaScript
Raw Normal View History

2023-06-20 00:43:36 +05:30
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMount } from '@vue/test-utils';
2020-10-24 23:57:45 +05:30
import {
Blob as BlobMock,
SimpleViewerMock,
RichViewerMock,
RichBlobContentMock,
SimpleBlobContentMock,
} from 'jest/blob/components/mock_data';
2023-06-20 00:43:36 +05:30
import GetBlobContent from 'shared_queries/snippet/snippet_blob_content.query.graphql';
2020-03-13 15:44:24 +05:30
import BlobContent from '~/blob/components/blob_content.vue';
2021-03-11 19:13:27 +05:30
import BlobHeader from '~/blob/components/blob_header.vue';
2020-06-23 00:09:42 +05:30
import {
BLOB_RENDER_EVENT_LOAD,
BLOB_RENDER_EVENT_SHOW_SOURCE,
BLOB_RENDER_ERRORS,
} from '~/blob/components/constants';
2021-03-11 19:13:27 +05:30
import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue';
2022-10-11 01:57:18 +05:30
import { VISIBILITY_LEVEL_PUBLIC_STRING } from '~/visibility_level/constants';
2021-03-11 19:13:27 +05:30
import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers';
2023-06-20 00:43:36 +05:30
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
2020-03-13 15:44:24 +05:30
describe('Blob Embeddable', () => {
let wrapper;
2023-06-20 00:43:36 +05:30
let requestHandlers;
2020-03-13 15:44:24 +05:30
const snippet = {
id: 'gid://foo.bar/snippet',
webUrl: 'https://foo.bar',
2022-10-11 01:57:18 +05:30
visibilityLevel: VISIBILITY_LEVEL_PUBLIC_STRING,
2020-03-13 15:44:24 +05:30
};
const dataMock = {
activeViewerType: SimpleViewerMock.type,
};
2023-06-20 00:43:36 +05:30
const mockDefaultHandler = ({ path, nodes } = { path: BlobMock.path }) => {
const renderedNodes = nodes || [
{ __typename: 'Blob', path, richData: 'richData', plainData: 'plainData' },
];
return jest.fn().mockResolvedValue({
data: {
snippets: {
__typename: 'Snippet',
id: '1',
nodes: [
{
__typename: 'Snippet',
id: '2',
blobs: {
__typename: 'Blob',
hasUnretrievableBlobs: false,
nodes: renderedNodes,
},
},
],
},
},
});
};
const createMockApolloProvider = (handler) => {
Vue.use(VueApollo);
requestHandlers = handler;
return createMockApollo([[GetBlobContent, requestHandlers]]);
};
2020-07-28 23:09:34 +05:30
function createComponent({
snippetProps = {},
data = dataMock,
blob = BlobMock,
2023-06-20 00:43:36 +05:30
handler = mockDefaultHandler(),
2020-07-28 23:09:34 +05:30
} = {}) {
2023-06-20 00:43:36 +05:30
wrapper = shallowMount(SnippetBlobView, {
apolloProvider: createMockApolloProvider(handler),
2020-03-13 15:44:24 +05:30
propsData: {
snippet: {
...snippet,
2020-07-28 23:09:34 +05:30
...snippetProps,
2020-03-13 15:44:24 +05:30
},
2020-07-28 23:09:34 +05:30
blob,
2020-03-13 15:44:24 +05:30
},
data() {
return {
...data,
};
},
2023-06-20 00:43:36 +05:30
stubs: {
BlobHeader,
BlobContent,
},
2020-03-13 15:44:24 +05:30
});
}
2023-06-20 00:43:36 +05:30
const findBlobHeader = () => wrapper.findComponent(BlobHeader);
const findBlobContent = () => wrapper.findComponent(BlobContent);
const findSimpleViewer = () => wrapper.findComponent(SimpleViewer);
const findRichViewer = () => wrapper.findComponent(RichViewer);
2020-03-13 15:44:24 +05:30
describe('rendering', () => {
it('renders correct components', () => {
createComponent();
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().exists()).toBe(true);
expect(findBlobContent().exists()).toBe(true);
2020-03-13 15:44:24 +05:30
});
2023-06-20 00:43:36 +05:30
it('sets simple viewer correctly', async () => {
2020-03-13 15:44:24 +05:30
createComponent();
2023-06-20 00:43:36 +05:30
await waitForPromises();
expect(findSimpleViewer().exists()).toBe(true);
2020-03-13 15:44:24 +05:30
});
2023-06-20 00:43:36 +05:30
it('sets rich viewer correctly', async () => {
2020-05-24 23:13:21 +05:30
const data = { ...dataMock, activeViewerType: RichViewerMock.type };
2020-07-28 23:09:34 +05:30
createComponent({
data,
});
2023-06-20 00:43:36 +05:30
await waitForPromises();
expect(findRichViewer().exists()).toBe(true);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('correctly switches viewer type', async () => {
2020-03-13 15:44:24 +05:30
createComponent();
2023-06-20 00:43:36 +05:30
await waitForPromises();
expect(findSimpleViewer().exists()).toBe(true);
2020-03-13 15:44:24 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, RichViewerMock.type);
await waitForPromises();
2020-03-13 15:44:24 +05:30
2023-06-20 00:43:36 +05:30
expect(findRichViewer().exists()).toBe(true);
2022-04-04 11:22:00 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, SimpleViewerMock.type);
await waitForPromises();
expect(findSimpleViewer().exists()).toBe(true);
2020-03-13 15:44:24 +05:30
});
2020-06-23 00:09:42 +05:30
it('passes information about render error down to blob header', () => {
createComponent({
blob: {
...BlobMock,
simpleViewer: {
...SimpleViewerMock,
renderError: BLOB_RENDER_ERRORS.REASONS.COLLAPSED.id,
},
},
});
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('hasRenderError')).toBe(true);
2020-06-23 00:09:42 +05:30
});
2020-10-24 23:57:45 +05:30
describe('bob content in multi-file scenario', () => {
const SimpleBlobContentMock2 = {
...SimpleBlobContentMock,
plainData: 'Another Plain Foo',
};
const RichBlobContentMock2 = {
...SimpleBlobContentMock,
richData: 'Another Rich Foo',
};
2023-06-20 00:43:36 +05:30
const MixedSimpleBlobContentMock = {
...SimpleBlobContentMock,
richData: '<h1>Rich</h1>',
};
const MixedRichBlobContentMock = {
...RichBlobContentMock,
plainData: 'Plain',
};
2020-10-24 23:57:45 +05:30
it.each`
2023-06-20 00:43:36 +05:30
snippetBlobs | description | currentBlob | expectedContent | activeViewerType
${[SimpleBlobContentMock]} | ${'one existing textual blob'} | ${SimpleBlobContentMock} | ${SimpleBlobContentMock.plainData} | ${SimpleViewerMock.type}
${[RichBlobContentMock]} | ${'one existing rich blob'} | ${RichBlobContentMock} | ${RichBlobContentMock.richData} | ${RichViewerMock.type}
${[SimpleBlobContentMock, MixedRichBlobContentMock]} | ${'mixed blobs with current textual blob'} | ${SimpleBlobContentMock} | ${SimpleBlobContentMock.plainData} | ${SimpleViewerMock.type}
${[MixedSimpleBlobContentMock, RichBlobContentMock]} | ${'mixed blobs with current rich blob'} | ${RichBlobContentMock} | ${RichBlobContentMock.richData} | ${RichViewerMock.type}
${[SimpleBlobContentMock, SimpleBlobContentMock2]} | ${'textual blobs with current textual blob'} | ${SimpleBlobContentMock} | ${SimpleBlobContentMock.plainData} | ${SimpleViewerMock.type}
${[RichBlobContentMock, RichBlobContentMock2]} | ${'rich blobs with current rich blob'} | ${RichBlobContentMock} | ${RichBlobContentMock.richData} | ${RichViewerMock.type}
2020-10-24 23:57:45 +05:30
`(
'renders correct content for $description',
2023-06-20 00:43:36 +05:30
async ({ snippetBlobs, currentBlob, expectedContent, activeViewerType }) => {
2020-10-24 23:57:45 +05:30
createComponent({
2023-06-20 00:43:36 +05:30
handler: mockDefaultHandler({ path: currentBlob.path, nodes: snippetBlobs }),
data: { activeViewerType },
2020-10-24 23:57:45 +05:30
blob: {
...BlobMock,
path: currentBlob.path,
},
});
2023-06-20 00:43:36 +05:30
await waitForPromises();
2020-10-24 23:57:45 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobContent().props('content')).toBe(expectedContent);
2020-10-24 23:57:45 +05:30
},
);
});
2020-03-13 15:44:24 +05:30
describe('URLS with hash', () => {
afterEach(() => {
window.location.hash = '';
});
2022-11-25 23:54:43 +05:30
describe('if hash starts with #LC', () => {
beforeEach(() => {
window.location.hash = '#LC2';
});
2023-06-20 00:43:36 +05:30
it('renders simple viewer by default', async () => {
2022-11-25 23:54:43 +05:30
createComponent({
data: {},
});
2023-06-20 00:43:36 +05:30
await waitForPromises();
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('activeViewerType')).toBe(SimpleViewerMock.type);
expect(findSimpleViewer().exists()).toBe(true);
2020-07-28 23:09:34 +05:30
});
2020-03-13 15:44:24 +05:30
2022-11-25 23:54:43 +05:30
describe('switchViewer()', () => {
it('switches to the passed viewer', async () => {
createComponent();
2023-06-20 00:43:36 +05:30
await waitForPromises();
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, RichViewerMock.type);
await waitForPromises();
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('activeViewerType')).toBe(RichViewerMock.type);
expect(findRichViewer().exists()).toBe(true);
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, SimpleViewerMock.type);
await waitForPromises();
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('activeViewerType')).toBe(SimpleViewerMock.type);
expect(findSimpleViewer().exists()).toBe(true);
2022-11-25 23:54:43 +05:30
});
});
2020-03-13 15:44:24 +05:30
});
2022-11-25 23:54:43 +05:30
describe('if hash starts with anything else', () => {
beforeEach(() => {
window.location.hash = '#last-headline';
});
2020-03-13 15:44:24 +05:30
2023-06-20 00:43:36 +05:30
it('renders rich viewer by default', async () => {
2022-11-25 23:54:43 +05:30
createComponent({
data: {},
});
2023-06-20 00:43:36 +05:30
await waitForPromises();
2022-04-04 11:22:00 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('activeViewerType')).toBe(RichViewerMock.type);
expect(findRichViewer().exists()).toBe(true);
2022-11-25 23:54:43 +05:30
});
2022-04-04 11:22:00 +05:30
2022-11-25 23:54:43 +05:30
describe('switchViewer()', () => {
it('switches to the passed viewer', async () => {
createComponent();
2023-06-20 00:43:36 +05:30
await waitForPromises();
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, SimpleViewerMock.type);
await waitForPromises();
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
expect(findBlobHeader().props('activeViewerType')).toBe(SimpleViewerMock.type);
expect(findSimpleViewer().exists()).toBe(true);
2022-11-25 23:54:43 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE, RichViewerMock.type);
await waitForPromises();
expect(findBlobHeader().props('activeViewerType')).toBe(RichViewerMock.type);
expect(findRichViewer().exists()).toBe(true);
2022-11-25 23:54:43 +05:30
});
2020-03-13 15:44:24 +05:30
});
});
});
});
2020-05-24 23:13:21 +05:30
describe('functionality', () => {
describe('render error', () => {
it('correctly sets blob on the blob-content-error component', () => {
createComponent();
2023-06-20 00:43:36 +05:30
expect(findBlobContent().props('blob')).toEqual(BlobMock);
2020-05-24 23:13:21 +05:30
});
2023-06-20 00:43:36 +05:30
it(`refetches blob content on ${BLOB_RENDER_EVENT_LOAD} event`, async () => {
2020-05-24 23:13:21 +05:30
createComponent();
2023-06-20 00:43:36 +05:30
await waitForPromises();
expect(requestHandlers).toHaveBeenCalledTimes(1);
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_LOAD);
await waitForPromises();
2020-05-24 23:13:21 +05:30
2023-06-20 00:43:36 +05:30
expect(requestHandlers).toHaveBeenCalledTimes(2);
2020-05-24 23:13:21 +05:30
});
it(`sets '${SimpleViewerMock.type}' as active on ${BLOB_RENDER_EVENT_SHOW_SOURCE} event`, () => {
2020-07-28 23:09:34 +05:30
createComponent({
data: {
2020-05-24 23:13:21 +05:30
activeViewerType: RichViewerMock.type,
},
2020-07-28 23:09:34 +05:30
});
2020-05-24 23:13:21 +05:30
2023-06-20 00:43:36 +05:30
findBlobContent().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE);
2020-05-24 23:13:21 +05:30
expect(wrapper.vm.activeViewerType).toEqual(SimpleViewerMock.type);
});
});
});
2020-03-13 15:44:24 +05:30
});