gitlab-org--gitlab-foss/spec/frontend/snippets/components/snippet_blob_edit_spec.js

165 lines
5 KiB
JavaScript

import SnippetBlobEdit from '~/snippets/components/snippet_blob_edit.vue';
import BlobHeaderEdit from '~/blob/components/blob_edit_header.vue';
import BlobContentEdit from '~/blob/components/blob_edit_content.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import waitForPromises from 'helpers/wait_for_promises';
jest.mock('~/blob/utils', () => jest.fn());
jest.mock('~/lib/utils/url_utility', () => ({
getBaseURL: jest.fn().mockReturnValue('foo/'),
joinPaths: jest
.fn()
.mockName('joinPaths')
.mockReturnValue('contentApiURL'),
}));
jest.mock('~/flash');
let flashSpy;
describe('Snippet Blob Edit component', () => {
let wrapper;
let axiosMock;
const contentMock = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
const pathMock = 'lorem.txt';
const rawPathMock = 'foo/bar';
const blob = {
path: pathMock,
content: contentMock,
rawPath: rawPathMock,
};
const findComponent = component => wrapper.find(component);
function createComponent(props = {}, data = { isContentLoading: false }) {
wrapper = shallowMount(SnippetBlobEdit, {
propsData: {
...props,
},
data() {
return {
...data,
};
},
});
flashSpy = jest.spyOn(wrapper.vm, 'flashAPIFailure');
}
beforeEach(() => {
axiosMock = new AxiosMockAdapter(axios);
createComponent();
});
afterEach(() => {
axiosMock.restore();
wrapper.destroy();
});
describe('rendering', () => {
it('matches the snapshot', () => {
createComponent({ blob });
expect(wrapper.element).toMatchSnapshot();
});
it('renders required components', () => {
expect(findComponent(BlobHeaderEdit).exists()).toBe(true);
expect(findComponent(BlobContentEdit).exists()).toBe(true);
});
it('renders loader if existing blob is supplied but no content is fetched yet', () => {
createComponent({ blob }, { isContentLoading: true });
expect(wrapper.contains(GlLoadingIcon)).toBe(true);
expect(findComponent(BlobContentEdit).exists()).toBe(false);
});
it('does not render loader if when blob is not supplied', () => {
createComponent();
expect(wrapper.contains(GlLoadingIcon)).toBe(false);
expect(findComponent(BlobContentEdit).exists()).toBe(true);
});
});
describe('functionality', () => {
it('does not fail without blob', () => {
const spy = jest.spyOn(global.console, 'error');
createComponent({ blob: undefined });
expect(spy).not.toHaveBeenCalled();
expect(findComponent(BlobContentEdit).exists()).toBe(true);
});
it.each`
emitter | prop
${BlobHeaderEdit} | ${'filePath'}
${BlobContentEdit} | ${'content'}
`('emits "blob-updated" event when the $prop gets changed', ({ emitter, prop }) => {
expect(wrapper.emitted('blob-updated')).toBeUndefined();
const newValue = 'foo.bar';
findComponent(emitter).vm.$emit('input', newValue);
return nextTick().then(() => {
expect(wrapper.emitted('blob-updated')[0]).toEqual([
expect.objectContaining({
[prop]: newValue,
}),
]);
});
});
describe('fetching blob content', () => {
const bootstrapForExistingSnippet = resp => {
createComponent({
blob: {
...blob,
content: '',
},
});
if (resp === 500) {
axiosMock.onGet('contentApiURL').reply(500);
} else {
axiosMock.onGet('contentApiURL').reply(200, contentMock);
}
};
const bootstrapForNewSnippet = () => {
createComponent();
};
it('fetches blob content with the additional query', () => {
bootstrapForExistingSnippet();
return waitForPromises().then(() => {
expect(joinPaths).toHaveBeenCalledWith('foo/', rawPathMock);
expect(findComponent(BlobHeaderEdit).props('value')).toBe(pathMock);
expect(findComponent(BlobContentEdit).props('value')).toBe(contentMock);
});
});
it('flashes the error message if fetching content fails', () => {
bootstrapForExistingSnippet(500);
return waitForPromises().then(() => {
expect(flashSpy).toHaveBeenCalled();
expect(findComponent(BlobContentEdit).props('value')).toBe('');
});
});
it('does not fetch content for new snippet', () => {
bootstrapForNewSnippet();
return waitForPromises().then(() => {
// we keep using waitForPromises to make sure we do not run failed test
expect(findComponent(BlobHeaderEdit).props('value')).toBe('');
expect(findComponent(BlobContentEdit).props('value')).toBe('');
expect(joinPaths).not.toHaveBeenCalled();
});
});
});
});
});