diff options
Diffstat (limited to 'spec/frontend/snippets/components/snippet_blob_edit_spec.js')
-rw-r--r-- | spec/frontend/snippets/components/snippet_blob_edit_spec.js | 137 |
1 files changed, 110 insertions, 27 deletions
diff --git a/spec/frontend/snippets/components/snippet_blob_edit_spec.js b/spec/frontend/snippets/components/snippet_blob_edit_spec.js index 75688e61892..009074b4558 100644 --- a/spec/frontend/snippets/components/snippet_blob_edit_spec.js +++ b/spec/frontend/snippets/components/snippet_blob_edit_spec.js @@ -4,78 +4,161 @@ 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; - const value = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'; - const fileName = 'lorem.txt'; - const findHeader = () => wrapper.find(BlobHeaderEdit); - const findContent = () => wrapper.find(BlobContentEdit); + 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 = {}) { + function createComponent(props = {}, data = { isContentLoading: false }) { wrapper = shallowMount(SnippetBlobEdit, { propsData: { - value, - fileName, - isLoading: false, ...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(findHeader().exists()).toBe(true); - expect(findContent().exists()).toBe(true); + expect(findComponent(BlobHeaderEdit).exists()).toBe(true); + expect(findComponent(BlobContentEdit).exists()).toBe(true); }); - it('renders loader if isLoading equals true', () => { - createComponent({ isLoading: 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(findContent().exists()).toBe(false); + 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 content', () => { + it('does not fail without blob', () => { const spy = jest.spyOn(global.console, 'error'); - createComponent({ value: undefined }); + createComponent({ blob: undefined }); expect(spy).not.toHaveBeenCalled(); - expect(findContent().exists()).toBe(true); + expect(findComponent(BlobContentEdit).exists()).toBe(true); }); - it('emits "name-change" event when the file name gets changed', () => { - expect(wrapper.emitted('name-change')).toBeUndefined(); - const newFilename = 'foo.bar'; - findHeader().vm.$emit('input', newFilename); + 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('name-change')[0]).toEqual([newFilename]); + expect(wrapper.emitted('blob-updated')[0]).toEqual([ + expect.objectContaining({ + [prop]: newValue, + }), + ]); }); }); - it('emits "input" event when the file content gets changed', () => { - expect(wrapper.emitted('input')).toBeUndefined(); - const newValue = 'foo.bar'; - findContent().vm.$emit('input', newValue); + describe('fetching blob content', () => { + const bootstrapForExistingSnippet = resp => { + createComponent({ + blob: { + ...blob, + content: '', + }, + }); - return nextTick().then(() => { - expect(wrapper.emitted('input')[0]).toEqual([newValue]); + 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(); + }); }); }); }); |