diff options
Diffstat (limited to 'spec/frontend/snippets/components')
8 files changed, 162 insertions, 32 deletions
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap index b1bbe2a9710..301ec5652a9 100644 --- a/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap +++ b/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap @@ -12,6 +12,7 @@ exports[`Snippet Blob Edit component rendering matches the snapshot 1`] = ` class="file-holder snippet" > <blob-header-edit-stub + data-qa-selector="snippet_file_name" value="lorem.txt" /> diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap index 334ceaa064f..9fd4cba5b87 100644 --- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap +++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap @@ -35,8 +35,8 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] = > <textarea aria-label="Description" - class="note-textarea js-gfm-input js-autosize markdown-area - qa-description-textarea" + class="note-textarea js-gfm-input js-autosize markdown-area" + data-qa-selector="snippet_description_field" data-supports-quick-actions="false" dir="auto" placeholder="Write a comment or drag your files hereā¦" diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap new file mode 100644 index 00000000000..9ebc4e81baf --- /dev/null +++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Snippet Description component matches the snapshot 1`] = ` +<markdown-field-view-stub + class="snippet-description" + data-qa-selector="snippet_description_field" +> + <div + class="md js-snippet-description" + > + <h2> + The property of Thor + </h2> + </div> +</markdown-field-view-stub> +`; diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js index 21a4ccf5a74..ba62a0a92ca 100644 --- a/spec/frontend/snippets/components/edit_spec.js +++ b/spec/frontend/snippets/components/edit_spec.js @@ -100,6 +100,7 @@ describe('Snippet Edit app', () => { }); const findSubmitButton = () => wrapper.find('[type=submit]'); + const findCancellButton = () => wrapper.find('[data-testid="snippet-cancel-btn"]'); describe('rendering', () => { it('renders loader while the query is in flight', () => { @@ -148,6 +149,21 @@ describe('Snippet Edit app', () => { expect(isBtnDisabled).toBe(expectation); }, ); + + it.each` + isNew | status | expectation + ${true} | ${`new`} | ${`/snippets`} + ${false} | ${`existing`} | ${newlyEditedSnippetUrl} + `('sets correct href for the cancel button on a $status snippet', ({ isNew, expectation }) => { + createComponent({ + data: { + snippet: { webUrl: newlyEditedSnippetUrl }, + newSnippet: isNew, + }, + }); + + expect(findCancellButton().attributes('href')).toBe(expectation); + }); }); describe('functionality', () => { diff --git a/spec/frontend/snippets/components/snippet_blob_view_spec.js b/spec/frontend/snippets/components/snippet_blob_view_spec.js index 1f6038bc7f0..d06489cffa9 100644 --- a/spec/frontend/snippets/components/snippet_blob_view_spec.js +++ b/spec/frontend/snippets/components/snippet_blob_view_spec.js @@ -3,6 +3,7 @@ import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue'; import BlobHeader from '~/blob/components/blob_header.vue'; import BlobEmbeddable from '~/blob/components/blob_embeddable.vue'; import BlobContent from '~/blob/components/blob_content.vue'; +import { BLOB_RENDER_EVENT_LOAD, BLOB_RENDER_EVENT_SHOW_SOURCE } from '~/blob/components/constants'; import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers'; import { SNIPPET_VISIBILITY_PRIVATE, @@ -29,6 +30,8 @@ describe('Blob Embeddable', () => { queries: { blobContent: { loading: contentLoading, + refetch: jest.fn(), + skip: true, }, }, }; @@ -84,9 +87,7 @@ describe('Blob Embeddable', () => { }); it('sets rich viewer correctly', () => { - const data = Object.assign({}, dataMock, { - activeViewerType: RichViewerMock.type, - }); + const data = { ...dataMock, activeViewerType: RichViewerMock.type }; createComponent({}, data); expect(wrapper.find(RichViewer).exists()).toBe(true); }); @@ -145,4 +146,35 @@ describe('Blob Embeddable', () => { }); }); }); + + describe('functionality', () => { + describe('render error', () => { + const findContentEl = () => wrapper.find(BlobContent); + + it('correctly sets blob on the blob-content-error component', () => { + createComponent(); + expect(findContentEl().props('blob')).toEqual(BlobMock); + }); + + it(`refetches blob content on ${BLOB_RENDER_EVENT_LOAD} event`, () => { + createComponent(); + + expect(wrapper.vm.$apollo.queries.blobContent.refetch).not.toHaveBeenCalled(); + findContentEl().vm.$emit(BLOB_RENDER_EVENT_LOAD); + expect(wrapper.vm.$apollo.queries.blobContent.refetch).toHaveBeenCalledTimes(1); + }); + + it(`sets '${SimpleViewerMock.type}' as active on ${BLOB_RENDER_EVENT_SHOW_SOURCE} event`, () => { + createComponent( + {}, + { + activeViewerType: RichViewerMock.type, + }, + ); + + findContentEl().vm.$emit(BLOB_RENDER_EVENT_SHOW_SOURCE); + expect(wrapper.vm.activeViewerType).toEqual(SimpleViewerMock.type); + }); + }); + }); }); diff --git a/spec/frontend/snippets/components/snippet_description_view_spec.js b/spec/frontend/snippets/components/snippet_description_view_spec.js new file mode 100644 index 00000000000..46467ef311e --- /dev/null +++ b/spec/frontend/snippets/components/snippet_description_view_spec.js @@ -0,0 +1,27 @@ +import SnippetDescription from '~/snippets/components/snippet_description_view.vue'; +import { shallowMount } from '@vue/test-utils'; + +describe('Snippet Description component', () => { + let wrapper; + const description = '<h2>The property of Thor</h2>'; + + function createComponent() { + wrapper = shallowMount(SnippetDescription, { + propsData: { + description, + }, + }); + } + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('matches the snapshot', () => { + expect(wrapper.element).toMatchSnapshot(); + }); +}); diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js index 16a66c70d6a..5230910b6f5 100644 --- a/spec/frontend/snippets/components/snippet_header_spec.js +++ b/spec/frontend/snippets/components/snippet_header_spec.js @@ -7,26 +7,27 @@ import { shallowMount } from '@vue/test-utils'; describe('Snippet header component', () => { let wrapper; const snippet = { - snippet: { - id: 'gid://gitlab/PersonalSnippet/50', - title: 'The property of Thor', - visibilityLevel: 'private', - webUrl: 'http://personal.dev.null/42', - userPermissions: { - adminSnippet: true, - updateSnippet: true, - reportSnippet: false, - }, - project: null, - author: { - name: 'Thor Odinson', - }, + id: 'gid://gitlab/PersonalSnippet/50', + title: 'The property of Thor', + visibilityLevel: 'private', + webUrl: 'http://personal.dev.null/42', + userPermissions: { + adminSnippet: true, + updateSnippet: true, + reportSnippet: false, + }, + project: null, + author: { + name: 'Thor Odinson', + }, + blob: { + binary: false, }, }; const mutationVariables = { mutation: DeleteSnippetMutation, variables: { - id: snippet.snippet.id, + id: snippet.id, }, }; const errorMsg = 'Foo bar'; @@ -46,10 +47,12 @@ describe('Snippet header component', () => { loading = false, permissions = {}, mutationRes = mutationTypes.RESOLVE, + snippetProps = {}, } = {}) { - const defaultProps = Object.assign({}, snippet); + // const defaultProps = Object.assign({}, snippet, snippetProps); + const defaultProps = Object.assign(snippet, snippetProps); if (permissions) { - Object.assign(defaultProps.snippet.userPermissions, { + Object.assign(defaultProps.userPermissions, { ...permissions, }); } @@ -65,7 +68,9 @@ describe('Snippet header component', () => { wrapper = shallowMount(SnippetHeader, { mocks: { $apollo }, propsData: { - ...defaultProps, + snippet: { + ...defaultProps, + }, }, stubs: { ApolloMutation, @@ -126,6 +131,17 @@ describe('Snippet header component', () => { expect(wrapper.find(GlModal).exists()).toBe(true); }); + it('renders Edit button as disabled for binary snippets', () => { + createComponent({ + snippetProps: { + blob: { + binary: true, + }, + }, + }); + expect(wrapper.find('[href*="edit"]').props('disabled')).toBe(true); + }); + describe('Delete mutation', () => { const { location } = window; @@ -156,14 +172,34 @@ describe('Snippet header component', () => { }); }); - it('closes modal and redirects to snippets listing in case of successful mutation', () => { - createComponent(); - wrapper.vm.closeDeleteModal = jest.fn(); + describe('in case of successful mutation, closes modal and redirects to correct listing', () => { + const createDeleteSnippet = (snippetProps = {}) => { + createComponent({ + snippetProps, + }); + wrapper.vm.closeDeleteModal = jest.fn(); - wrapper.vm.deleteSnippet(); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled(); - expect(window.location.pathname).toEqual('dashboard/snippets'); + wrapper.vm.deleteSnippet(); + return wrapper.vm.$nextTick(); + }; + + it('redirects to dashboard/snippets for personal snippet', () => { + return createDeleteSnippet().then(() => { + expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled(); + expect(window.location.pathname).toBe('dashboard/snippets'); + }); + }); + + it('redirects to project snippets for project snippet', () => { + const fullPath = 'foo/bar'; + return createDeleteSnippet({ + project: { + fullPath, + }, + }).then(() => { + expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled(); + expect(window.location.pathname).toBe(`${fullPath}/snippets`); + }); }); }); }); diff --git a/spec/frontend/snippets/components/snippet_title_spec.js b/spec/frontend/snippets/components/snippet_title_spec.js index b49b2008610..88261a75f6c 100644 --- a/spec/frontend/snippets/components/snippet_title_spec.js +++ b/spec/frontend/snippets/components/snippet_title_spec.js @@ -1,4 +1,5 @@ import SnippetTitle from '~/snippets/components/snippet_title.vue'; +import SnippetDescription from '~/snippets/components/snippet_description_view.vue'; import { GlSprintf } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; @@ -16,7 +17,7 @@ describe('Snippet header component', () => { }; function createComponent({ props = snippet } = {}) { - const defaultProps = Object.assign({}, props); + const defaultProps = { ...props }; wrapper = shallowMount(SnippetTitle, { propsData: { @@ -36,8 +37,9 @@ describe('Snippet header component', () => { it('renders snippets title and description', () => { createComponent(); + expect(wrapper.text().trim()).toContain(title); - expect(wrapper.find('.js-snippet-description').element.innerHTML).toBe(descriptionHtml); + expect(wrapper.find(SnippetDescription).props('description')).toBe(descriptionHtml); }); it('does not render recent changes time stamp if there were no updates', () => { |