diff options
Diffstat (limited to 'spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js')
-rw-r--r-- | spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js new file mode 100644 index 00000000000..051ffd27af4 --- /dev/null +++ b/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js @@ -0,0 +1,193 @@ +import { GlFormInput } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; + +import IssuableEditForm from '~/vue_shared/issuable/show/components/issuable_edit_form.vue'; +import IssuableEventHub from '~/vue_shared/issuable/show/event_hub'; +import MarkdownField from '~/vue_shared/components/markdown/field.vue'; + +import { mockIssuableShowProps, mockIssuable } from '../mock_data'; + +const issuableEditFormProps = { + issuable: mockIssuable, + ...mockIssuableShowProps, +}; + +const createComponent = ({ propsData = issuableEditFormProps } = {}) => + shallowMount(IssuableEditForm, { + propsData, + stubs: { + MarkdownField, + }, + slots: { + 'edit-form-actions': ` + <button class="js-save">Save changes</button> + <button class="js-cancel">Cancel</button> + `, + }, + }); + +describe('IssuableEditForm', () => { + let wrapper; + const assertEvent = (eventSpy) => { + expect(eventSpy).toHaveBeenNthCalledWith(1, 'update.issuable', expect.any(Function)); + expect(eventSpy).toHaveBeenNthCalledWith(2, 'close.form', expect.any(Function)); + }; + + beforeEach(() => { + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('watch', () => { + describe('issuable', () => { + it('sets title and description to `issuable.title` and `issuable.description` when those values are available', async () => { + wrapper.setProps({ + issuable: { + ...issuableEditFormProps.issuable, + title: 'Foo', + description: 'Foobar', + }, + }); + + await wrapper.vm.$nextTick(); + + expect(wrapper.vm.title).toBe('Foo'); + expect(wrapper.vm.description).toBe('Foobar'); + }); + + it('sets title and description to empty string when `issuable.title` and `issuable.description` is unavailable', async () => { + wrapper.setProps({ + issuable: { + ...issuableEditFormProps.issuable, + title: null, + description: null, + }, + }); + + await wrapper.vm.$nextTick(); + + expect(wrapper.vm.title).toBe(''); + expect(wrapper.vm.description).toBe(''); + }); + }); + }); + + describe('created', () => { + it('binds `update.issuable` and `close.form` event listeners', () => { + const eventOnSpy = jest.spyOn(IssuableEventHub, '$on'); + const wrapperTemp = createComponent(); + + assertEvent(eventOnSpy); + + wrapperTemp.destroy(); + }); + }); + + describe('beforeDestroy', () => { + it('unbinds `update.issuable` and `close.form` event listeners', () => { + const wrapperTemp = createComponent(); + const eventOffSpy = jest.spyOn(IssuableEventHub, '$off'); + + wrapperTemp.destroy(); + + assertEvent(eventOffSpy); + }); + }); + + describe('methods', () => { + describe('initAutosave', () => { + it('initializes `autosaveTitle` and `autosaveDescription` props', () => { + expect(wrapper.vm.autosaveTitle).toBeDefined(); + expect(wrapper.vm.autosaveDescription).toBeDefined(); + }); + }); + + describe('resetAutosave', () => { + it('calls `reset` on `autosaveTitle` and `autosaveDescription` props', () => { + jest.spyOn(wrapper.vm.autosaveTitle, 'reset').mockImplementation(jest.fn); + jest.spyOn(wrapper.vm.autosaveDescription, 'reset').mockImplementation(jest.fn); + + wrapper.vm.resetAutosave(); + + expect(wrapper.vm.autosaveTitle.reset).toHaveBeenCalled(); + expect(wrapper.vm.autosaveDescription.reset).toHaveBeenCalled(); + }); + }); + }); + + describe('template', () => { + it('renders title input field', () => { + const titleInputEl = wrapper.find('[data-testid="title"]'); + + expect(titleInputEl.exists()).toBe(true); + expect(titleInputEl.find(GlFormInput).attributes()).toMatchObject({ + 'aria-label': 'Title', + placeholder: 'Title', + }); + }); + + it('renders description textarea field', () => { + const descriptionEl = wrapper.find('[data-testid="description"]'); + + expect(descriptionEl.exists()).toBe(true); + expect(descriptionEl.find(MarkdownField).props()).toMatchObject({ + markdownPreviewPath: issuableEditFormProps.descriptionPreviewPath, + markdownDocsPath: issuableEditFormProps.descriptionHelpPath, + enableAutocomplete: issuableEditFormProps.enableAutocomplete, + textareaValue: mockIssuable.description, + }); + expect(descriptionEl.find('textarea').attributes()).toMatchObject({ + 'data-supports-quick-actions': 'true', + 'aria-label': 'Description', + placeholder: 'Write a comment or drag your files hereā¦', + }); + }); + + it('renders form actions', () => { + const actionsEl = wrapper.find('[data-testid="actions"]'); + + expect(actionsEl.find('button.js-save').exists()).toBe(true); + expect(actionsEl.find('button.js-cancel').exists()).toBe(true); + }); + + describe('events', () => { + const eventObj = { + preventDefault: jest.fn(), + stopPropagation: jest.fn(), + }; + + it('component emits `keydown-title` event with event object and issuableMeta params via gl-form-input', async () => { + const titleInputEl = wrapper.find(GlFormInput); + + titleInputEl.vm.$emit('keydown', eventObj, 'title'); + + expect(wrapper.emitted('keydown-title')).toBeTruthy(); + expect(wrapper.emitted('keydown-title')[0]).toMatchObject([ + eventObj, + { + issuableTitle: wrapper.vm.title, + issuableDescription: wrapper.vm.description, + }, + ]); + }); + + it('component emits `keydown-description` event with event object and issuableMeta params via textarea', async () => { + const descriptionInputEl = wrapper.find('[data-testid="description"] textarea'); + + descriptionInputEl.trigger('keydown', eventObj, 'description'); + + expect(wrapper.emitted('keydown-description')).toBeTruthy(); + expect(wrapper.emitted('keydown-description')[0]).toMatchObject([ + eventObj, + { + issuableTitle: wrapper.vm.title, + issuableDescription: wrapper.vm.description, + }, + ]); + }); + }); + }); +}); |