diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
commit | 43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch) | |
tree | dceebdc68925362117480a5d672bcff122fb625b /spec/frontend/blob/components | |
parent | 20c84b99005abd1c82101dfeff264ac50d2df211 (diff) |
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'spec/frontend/blob/components')
11 files changed, 122 insertions, 155 deletions
diff --git a/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap index a5690844053..1733c4d4bb4 100644 --- a/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap +++ b/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap @@ -10,7 +10,7 @@ exports[`Blob Header Editing rendering matches the snapshot 1`] = ` <gl-form-input-stub class="form-control js-snippet-file-name" name="snippet_file_name" - placeholder="Give your file a name to add code highlighting, e.g. example.rb for Ruby" + placeholder="File name (e.g. test.rb)" type="text" value="foo.md" /> diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap index fdbb9bdd0d0..4ae55f34e4c 100644 --- a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap +++ b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap @@ -22,7 +22,7 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = ` <clipboard-button-stub category="tertiary" - cssclass="btn-clipboard btn-transparent lh-100 position-static" + cssclass="gl-mr-2" gfm="\`foo/bar/dummy.md\`" size="medium" text="foo/bar/dummy.md" diff --git a/spec/frontend/blob/components/blob_content_error_spec.js b/spec/frontend/blob/components/blob_content_error_spec.js index 0f5885c2acf..203fab94a5c 100644 --- a/spec/frontend/blob/components/blob_content_error_spec.js +++ b/spec/frontend/blob/components/blob_content_error_spec.js @@ -18,10 +18,6 @@ describe('Blob Content Error component', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - describe('collapsed and too large blobs', () => { it.each` error | reason | options diff --git a/spec/frontend/blob/components/blob_content_spec.js b/spec/frontend/blob/components/blob_content_spec.js index f7b819b6e94..91af5f7bfed 100644 --- a/spec/frontend/blob/components/blob_content_spec.js +++ b/spec/frontend/blob/components/blob_content_spec.js @@ -29,10 +29,6 @@ describe('Blob Content component', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - describe('rendering', () => { it('renders loader if `loading: true`', () => { createComponent({ loading: true }); diff --git a/spec/frontend/blob/components/blob_edit_header_spec.js b/spec/frontend/blob/components/blob_edit_header_spec.js index c84b5896348..b0ce5f40d95 100644 --- a/spec/frontend/blob/components/blob_edit_header_spec.js +++ b/spec/frontend/blob/components/blob_edit_header_spec.js @@ -1,6 +1,5 @@ import { GlFormInput, GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; -import { nextTick } from 'vue'; import BlobEditHeader from '~/blob/components/blob_edit_header.vue'; describe('Blob Header Editing', () => { @@ -15,24 +14,22 @@ describe('Blob Header Editing', () => { }, }); }; + const findDeleteButton = () => wrapper.findAllComponents(GlButton).wrappers.find((x) => x.text() === 'Delete file'); + const findFormInput = () => wrapper.findComponent(GlFormInput); beforeEach(() => { createComponent(); }); - afterEach(() => { - wrapper.destroy(); - }); - describe('rendering', () => { it('matches the snapshot', () => { expect(wrapper.element).toMatchSnapshot(); }); it('contains a form input field', () => { - expect(wrapper.findComponent(GlFormInput).exists()).toBe(true); + expect(findFormInput().exists()).toBe(true); }); it('does not show delete button', () => { @@ -41,19 +38,16 @@ describe('Blob Header Editing', () => { }); describe('functionality', () => { - it('emits input event when the blob name is changed', async () => { - const inputComponent = wrapper.findComponent(GlFormInput); + it('emits input event when the blob name is changed', () => { + const inputComponent = findFormInput(); const newValue = 'bar.txt'; - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - name: newValue, - }); + // update `name` with `newValue` + inputComponent.vm.$emit('input', newValue); + // trigger change event which emits input event on wrapper inputComponent.vm.$emit('change'); - await nextTick(); - expect(wrapper.emitted().input[0]).toEqual([newValue]); + expect(wrapper.emitted().input).toEqual([[newValue]]); }); }); diff --git a/spec/frontend/blob/components/blob_header_default_actions_spec.js b/spec/frontend/blob/components/blob_header_default_actions_spec.js index 0f015715dc2..4c8c256121f 100644 --- a/spec/frontend/blob/components/blob_header_default_actions_spec.js +++ b/spec/frontend/blob/components/blob_header_default_actions_spec.js @@ -34,10 +34,6 @@ describe('Blob Header Default Actions', () => { buttons = wrapper.findAllComponents(GlButton); }); - afterEach(() => { - wrapper.destroy(); - }); - describe('renders', () => { const findCopyButton = () => wrapper.findByTestId('copyContentsButton'); const findViewRawButton = () => wrapper.findByTestId('viewRawButton'); @@ -49,7 +45,7 @@ describe('Blob Header Default Actions', () => { it('exactly 3 buttons with predefined actions', () => { expect(buttons.length).toBe(3); [BTN_COPY_CONTENTS_TITLE, BTN_RAW_TITLE, BTN_DOWNLOAD_TITLE].forEach((title, i) => { - expect(buttons.at(i).vm.$el.title).toBe(title); + expect(buttons.at(i).attributes('title')).toBe(title); }); }); @@ -71,7 +67,7 @@ describe('Blob Header Default Actions', () => { }); buttons = wrapper.findAllComponents(GlButton); - expect(buttons.at(0).attributes('disabled')).toBe('true'); + expect(buttons.at(0).attributes('disabled')).toBeDefined(); }); it('does not render the copy button if a rendering error is set', () => { @@ -91,10 +87,9 @@ describe('Blob Header Default Actions', () => { it('emits a copy event if overrideCopy is set to true', () => { createComponent({ overrideCopy: true }); - jest.spyOn(wrapper.vm, '$emit'); findCopyButton().vm.$emit('click'); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('copy'); + expect(wrapper.emitted('copy')).toHaveLength(1); }); }); diff --git a/spec/frontend/blob/components/blob_header_filepath_spec.js b/spec/frontend/blob/components/blob_header_filepath_spec.js index 8c32cba1ba4..be49146ff8a 100644 --- a/spec/frontend/blob/components/blob_header_filepath_spec.js +++ b/spec/frontend/blob/components/blob_header_filepath_spec.js @@ -21,10 +21,6 @@ describe('Blob Header Filepath', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - const findBadge = () => wrapper.findComponent(GlBadge); describe('rendering', () => { diff --git a/spec/frontend/blob/components/blob_header_spec.js b/spec/frontend/blob/components/blob_header_spec.js index 46740958090..47e09bb38bc 100644 --- a/spec/frontend/blob/components/blob_header_spec.js +++ b/spec/frontend/blob/components/blob_header_spec.js @@ -1,9 +1,14 @@ import { shallowMount, mount } from '@vue/test-utils'; -import { nextTick } from 'vue'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; import BlobHeader from '~/blob/components/blob_header.vue'; import DefaultActions from '~/blob/components/blob_header_default_actions.vue'; import BlobFilepath from '~/blob/components/blob_header_filepath.vue'; import ViewerSwitcher from '~/blob/components/blob_header_viewer_switcher.vue'; +import { + RICH_BLOB_VIEWER_TITLE, + SIMPLE_BLOB_VIEWER, + SIMPLE_BLOB_VIEWER_TITLE, +} from '~/blob/components/constants'; import TableContents from '~/blob/components/table_contents.vue'; import { Blob } from './mock_data'; @@ -11,12 +16,26 @@ import { Blob } from './mock_data'; describe('Blob Header Default Actions', () => { let wrapper; - function createComponent(blobProps = {}, options = {}, propsData = {}, shouldMount = false) { - const method = shouldMount ? mount : shallowMount; - const blobHash = 'foo-bar'; - wrapper = method.call(this, BlobHeader, { + const defaultProvide = { + blobHash: 'foo-bar', + }; + + const findDefaultActions = () => wrapper.findComponent(DefaultActions); + const findTableContents = () => wrapper.findComponent(TableContents); + const findViewSwitcher = () => wrapper.findComponent(ViewerSwitcher); + const findBlobFilePath = () => wrapper.findComponent(BlobFilepath); + const findRichTextEditorBtn = () => wrapper.findByLabelText(RICH_BLOB_VIEWER_TITLE); + const findSimpleTextEditorBtn = () => wrapper.findByLabelText(SIMPLE_BLOB_VIEWER_TITLE); + + function createComponent({ + blobProps = {}, + options = {}, + propsData = {}, + mountFn = shallowMount, + } = {}) { + wrapper = mountFn(BlobHeader, { provide: { - blobHash, + ...defaultProvide, }, propsData: { blob: { ...Blob, ...blobProps }, @@ -26,143 +45,123 @@ describe('Blob Header Default Actions', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - describe('rendering', () => { - const findDefaultActions = () => wrapper.findComponent(DefaultActions); - - const slots = { - prepend: 'Foo Prepend', - actions: 'Actions Bar', - }; - it('matches the snapshot', () => { createComponent(); expect(wrapper.element).toMatchSnapshot(); }); - it('renders all components', () => { - createComponent(); - expect(wrapper.findComponent(TableContents).exists()).toBe(true); - expect(wrapper.findComponent(ViewerSwitcher).exists()).toBe(true); - expect(findDefaultActions().exists()).toBe(true); - expect(wrapper.findComponent(BlobFilepath).exists()).toBe(true); + describe('default render', () => { + it.each` + findComponent | componentName + ${findTableContents} | ${'TableContents'} + ${findViewSwitcher} | ${'ViewSwitcher'} + ${findDefaultActions} | ${'DefaultActions'} + ${findBlobFilePath} | ${'BlobFilePath'} + `('renders $componentName component by default', ({ findComponent }) => { + createComponent(); + + expect(findComponent().exists()).toBe(true); + }); }); it('does not render viewer switcher if the blob has only the simple viewer', () => { createComponent({ - richViewer: null, + blobProps: { + richViewer: null, + }, }); - expect(wrapper.findComponent(ViewerSwitcher).exists()).toBe(false); + expect(findViewSwitcher().exists()).toBe(false); }); it('does not render viewer switcher if a corresponding prop is passed', () => { - createComponent( - {}, - {}, - { + createComponent({ + propsData: { hideViewerSwitcher: true, }, - ); - expect(wrapper.findComponent(ViewerSwitcher).exists()).toBe(false); + }); + expect(findViewSwitcher().exists()).toBe(false); }); it('does not render default actions is corresponding prop is passed', () => { - createComponent( - {}, - {}, - { + createComponent({ + propsData: { hideDefaultActions: true, }, - ); - expect(wrapper.findComponent(DefaultActions).exists()).toBe(false); + }); + expect(findDefaultActions().exists()).toBe(false); }); - Object.keys(slots).forEach((slot) => { - it('renders the slots', () => { - const slotContent = slots[slot]; - createComponent( - {}, - { - scopedSlots: { - [slot]: `<span>${slotContent}</span>`, - }, + it.each` + slotContent | key + ${'Foo Prepend'} | ${'prepend'} + ${'Actions Bar'} | ${'actions'} + `('renders the slot $key', ({ key, slotContent }) => { + createComponent({ + options: { + scopedSlots: { + [key]: `<span>${slotContent}</span>`, }, - {}, - true, - ); - expect(wrapper.text()).toContain(slotContent); + }, + mountFn: mount, }); + expect(wrapper.text()).toContain(slotContent); }); it('passes information about render error down to default actions', () => { - createComponent( - {}, - {}, - { + createComponent({ + propsData: { hasRenderError: true, }, - ); + }); expect(findDefaultActions().props('hasRenderError')).toBe(true); }); it('passes the correct isBinary value to default actions when viewing a binary file', () => { - createComponent({}, {}, { isBinary: true }); + createComponent({ propsData: { isBinary: true } }); expect(findDefaultActions().props('isBinary')).toBe(true); }); }); describe('functionality', () => { - const newViewer = 'Foo Bar'; - const activeViewerType = 'Alpha Beta'; - const factory = (hideViewerSwitcher = false) => { - createComponent( - {}, - {}, - { - activeViewerType, + createComponent({ + propsData: { + activeViewerType: SIMPLE_BLOB_VIEWER, hideViewerSwitcher, }, - ); + mountFn: mountExtended, + }); }; - it('by default sets viewer data based on activeViewerType', () => { + it('shows the correctly selected view by default', () => { factory(); - expect(wrapper.vm.viewer).toBe(activeViewerType); + + expect(findViewSwitcher().exists()).toBe(true); + expect(findRichTextEditorBtn().props().selected).toBe(false); + expect(findSimpleTextEditorBtn().props().selected).toBe(true); }); - it('sets viewer to null if the viewer switcher should be hidden', () => { + it('Does not show the viewer switcher should be hidden', () => { factory(true); - expect(wrapper.vm.viewer).toBe(null); + + expect(findViewSwitcher().exists()).toBe(false); }); it('watches the changes in viewer data and emits event when the change is registered', async () => { factory(); - jest.spyOn(wrapper.vm, '$emit'); - wrapper.vm.viewer = newViewer; - await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('viewer-changed', newViewer); - }); - - it('does not emit event if the switcher is not rendered', async () => { - factory(true); - - expect(wrapper.vm.showViewerSwitcher).toBe(false); - jest.spyOn(wrapper.vm, '$emit'); - wrapper.vm.viewer = newViewer; + await findRichTextEditorBtn().trigger('click'); - await nextTick(); - expect(wrapper.vm.$emit).not.toHaveBeenCalled(); + expect(wrapper.emitted('viewer-changed')).toBeDefined(); }); it('sets different icons depending on the blob file type', async () => { factory(); - expect(wrapper.vm.blobSwitcherDocIcon).toBe('document'); + + expect(findViewSwitcher().props('docIcon')).toBe('document'); + await wrapper.setProps({ blob: { ...Blob, @@ -172,7 +171,8 @@ describe('Blob Header Default Actions', () => { }, }, }); - expect(wrapper.vm.blobSwitcherDocIcon).toBe('table'); + + expect(findViewSwitcher().props('docIcon')).toBe('table'); }); }); }); diff --git a/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js b/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js index 1eac0733646..2ef87f6664b 100644 --- a/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js +++ b/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js @@ -18,14 +18,14 @@ describe('Blob Header Viewer Switcher', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); + const findSimpleViewerButton = () => wrapper.findComponent('[data-viewer="simple"]'); + const findRichViewerButton = () => wrapper.findComponent('[data-viewer="rich"]'); describe('intiialization', () => { it('is initialized with simple viewer as active', () => { createComponent(); - expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER); + expect(findSimpleViewerButton().props('selected')).toBe(true); + expect(findRichViewerButton().props('selected')).toBe(false); }); }); @@ -52,45 +52,34 @@ describe('Blob Header Viewer Switcher', () => { }); describe('viewer changes', () => { - let buttons; - let simpleBtn; - let richBtn; + it('does not switch the viewer if the selected one is already active', async () => { + createComponent(); + expect(findSimpleViewerButton().props('selected')).toBe(true); - function factory(propsData = {}) { - createComponent(propsData); - buttons = wrapper.findAllComponents(GlButton); - simpleBtn = buttons.at(0); - richBtn = buttons.at(1); - - jest.spyOn(wrapper.vm, '$emit'); - } - - it('does not switch the viewer if the selected one is already active', () => { - factory(); - expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER); - simpleBtn.vm.$emit('click'); - expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER); - expect(wrapper.vm.$emit).not.toHaveBeenCalled(); + findSimpleViewerButton().vm.$emit('click'); + await nextTick(); + + expect(findSimpleViewerButton().props('selected')).toBe(true); + expect(wrapper.emitted('input')).toBe(undefined); }); it('emits an event when a Rich Viewer button is clicked', async () => { - factory(); - expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER); - - richBtn.vm.$emit('click'); + createComponent(); + expect(findSimpleViewerButton().props('selected')).toBe(true); + findRichViewerButton().vm.$emit('click'); await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', RICH_BLOB_VIEWER); + + expect(wrapper.emitted('input')).toEqual([[RICH_BLOB_VIEWER]]); }); it('emits an event when a Simple Viewer button is clicked', async () => { - factory({ - value: RICH_BLOB_VIEWER, - }); - simpleBtn.vm.$emit('click'); + createComponent({ value: RICH_BLOB_VIEWER }); + findSimpleViewerButton().vm.$emit('click'); await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', SIMPLE_BLOB_VIEWER); + + expect(wrapper.emitted('input')).toEqual([[SIMPLE_BLOB_VIEWER]]); }); }); }); diff --git a/spec/frontend/blob/components/mock_data.js b/spec/frontend/blob/components/mock_data.js index b5803bf0cbc..6ecf5091591 100644 --- a/spec/frontend/blob/components/mock_data.js +++ b/spec/frontend/blob/components/mock_data.js @@ -47,11 +47,13 @@ export const BinaryBlob = { }; export const RichBlobContentMock = { + __typename: 'Blob', path: 'foo.md', richData: '<h1>Rich</h1>', }; export const SimpleBlobContentMock = { + __typename: 'Blob', path: 'foo.js', plainData: 'Plain', }; diff --git a/spec/frontend/blob/components/table_contents_spec.js b/spec/frontend/blob/components/table_contents_spec.js index 6af9cdcae7d..acfcef9704c 100644 --- a/spec/frontend/blob/components/table_contents_spec.js +++ b/spec/frontend/blob/components/table_contents_spec.js @@ -31,7 +31,6 @@ describe('Markdown table of contents component', () => { }); afterEach(() => { - wrapper.destroy(); resetHTMLFixture(); }); |