165 lines
5 KiB
JavaScript
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();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|