diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:19:03 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:19:03 +0000 |
commit | 14bd84b61276ef29b97d23642d698de769bacfd2 (patch) | |
tree | f9eba90140c1bd874211dea17750a0d422c04080 /spec/frontend/issuable | |
parent | 891c388697b2db0d8ee0c8358a9bdbf6dc56d581 (diff) | |
download | gitlab-ce-14bd84b61276ef29b97d23642d698de769bacfd2.tar.gz |
Add latest changes from gitlab-org/gitlab@15-10-stable-eev15.10.0-rc42
Diffstat (limited to 'spec/frontend/issuable')
14 files changed, 169 insertions, 311 deletions
diff --git a/spec/frontend/issuable/components/csv_export_modal_spec.js b/spec/frontend/issuable/components/csv_export_modal_spec.js index f798f87b6b2..ccd53e64c4d 100644 --- a/spec/frontend/issuable/components/csv_export_modal_spec.js +++ b/spec/frontend/issuable/components/csv_export_modal_spec.js @@ -17,7 +17,7 @@ describe('CsvExportModal', () => { ...props, }, provide: { - issuableType: 'issues', + issuableType: 'issue', ...injectedProperties, }, stubs: { @@ -29,19 +29,15 @@ describe('CsvExportModal', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - const findModal = () => wrapper.findComponent(GlModal); const findIcon = () => wrapper.findComponent(GlIcon); describe('template', () => { describe.each` - issuableType | modalTitle - ${'issues'} | ${'Export issues'} - ${'merge-requests'} | ${'Export merge requests'} - `('with the issuableType "$issuableType"', ({ issuableType, modalTitle }) => { + issuableType | modalTitle | dataTrackLabel + ${'issue'} | ${'Export issues'} | ${'export_issues_csv'} + ${'merge_request'} | ${'Export merge requests'} | ${'export_merge-requests_csv'} + `('with the issuableType "$issuableType"', ({ issuableType, modalTitle, dataTrackLabel }) => { beforeEach(() => { wrapper = createComponent({ injectedProperties: { issuableType } }); }); @@ -57,9 +53,9 @@ describe('CsvExportModal', () => { href: 'export/csv/path', variant: 'confirm', 'data-method': 'post', - 'data-qa-selector': `export_${issuableType}_button`, + 'data-qa-selector': `export_issues_button`, 'data-track-action': 'click_button', - 'data-track-label': `export_${issuableType}_csv`, + 'data-track-label': dataTrackLabel, }, }); }); diff --git a/spec/frontend/issuable/components/csv_import_export_buttons_spec.js b/spec/frontend/issuable/components/csv_import_export_buttons_spec.js index 118c12d968b..a861148abb6 100644 --- a/spec/frontend/issuable/components/csv_import_export_buttons_spec.js +++ b/spec/frontend/issuable/components/csv_import_export_buttons_spec.js @@ -16,7 +16,7 @@ describe('CsvImportExportButtons', () => { glModalDirective = jest.fn(); return mountExtended(CsvImportExportButtons, { directives: { - GlTooltip: createMockDirective(), + GlTooltip: createMockDirective('gl-tooltip'), glModal: { bind(_, { value }) { glModalDirective(value); @@ -33,10 +33,6 @@ describe('CsvImportExportButtons', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - const findExportCsvButton = () => wrapper.findComponent(GlButton); const findImportDropdown = () => wrapper.findComponent(GlDropdown); const findImportCsvButton = () => wrapper.findByRole('menuitem', { name: 'Import CSV' }); diff --git a/spec/frontend/issuable/components/csv_import_modal_spec.js b/spec/frontend/issuable/components/csv_import_modal_spec.js index 6e954c91f46..9069d2b3ab3 100644 --- a/spec/frontend/issuable/components/csv_import_modal_spec.js +++ b/spec/frontend/issuable/components/csv_import_modal_spec.js @@ -32,10 +32,6 @@ describe('CsvImportModal', () => { formSubmitSpy = jest.spyOn(HTMLFormElement.prototype, 'submit').mockImplementation(); }); - afterEach(() => { - wrapper.destroy(); - }); - const findModal = () => wrapper.findComponent(GlModal); const findForm = () => wrapper.find('form'); const findFileInput = () => wrapper.findByLabelText('Upload CSV file'); diff --git a/spec/frontend/issuable/components/issuable_by_email_spec.js b/spec/frontend/issuable/components/issuable_by_email_spec.js index b04a6c0b8fd..4cc5775b54e 100644 --- a/spec/frontend/issuable/components/issuable_by_email_spec.js +++ b/spec/frontend/issuable/components/issuable_by_email_spec.js @@ -53,8 +53,6 @@ describe('IssuableByEmail', () => { }); afterEach(() => { - wrapper.destroy(); - wrapper = null; mockAxios.restore(); }); diff --git a/spec/frontend/issuable/components/issuable_header_warnings_spec.js b/spec/frontend/issuable/components/issuable_header_warnings_spec.js index 99aa6778e1e..ff772040d22 100644 --- a/spec/frontend/issuable/components/issuable_header_warnings_spec.js +++ b/spec/frontend/issuable/components/issuable_header_warnings_spec.js @@ -25,16 +25,11 @@ describe('IssuableHeaderWarnings', () => { store, provide, directives: { - GlTooltip: createMockDirective(), + GlTooltip: createMockDirective('gl-tooltip'), }, }); }; - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - describe.each` issuableType ${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR} diff --git a/spec/frontend/issuable/components/issue_assignees_spec.js b/spec/frontend/issuable/components/issue_assignees_spec.js index 9a33bfae240..8ed51120508 100644 --- a/spec/frontend/issuable/components/issue_assignees_spec.js +++ b/spec/frontend/issuable/components/issue_assignees_spec.js @@ -21,11 +21,6 @@ describe('IssueAssigneesComponent', () => { vm = wrapper.vm; }; - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - const findTooltipText = () => wrapper.find('.js-assignee-tooltip').text(); const findAvatars = () => wrapper.findAllComponents(UserAvatarLink); const findOverflowCounter = () => wrapper.find('.avatar-counter'); diff --git a/spec/frontend/issuable/components/issue_milestone_spec.js b/spec/frontend/issuable/components/issue_milestone_spec.js index eac53c5f761..232d6177862 100644 --- a/spec/frontend/issuable/components/issue_milestone_spec.js +++ b/spec/frontend/issuable/components/issue_milestone_spec.js @@ -1,160 +1,61 @@ -import { GlIcon } from '@gitlab/ui'; +import { GlIcon, GlTooltip } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; - import { mockMilestone } from 'jest/boards/mock_data'; import IssueMilestone from '~/issuable/components/issue_milestone.vue'; -const createComponent = (milestone = mockMilestone) => { - const Component = Vue.extend(IssueMilestone); - - return shallowMount(Component, { - propsData: { - milestone, - }, - }); -}; - -describe('IssueMilestoneComponent', () => { +describe('IssueMilestone component', () => { let wrapper; - let vm; - beforeEach(async () => { - wrapper = createComponent(); + const findTooltip = () => wrapper.findComponent(GlTooltip); - ({ vm } = wrapper); + const createComponent = (milestone = mockMilestone) => + shallowMount(IssueMilestone, { propsData: { milestone } }); - await nextTick(); + beforeEach(() => { + wrapper = createComponent(); }); - afterEach(() => { - wrapper.destroy(); + it('renders milestone icon', () => { + expect(wrapper.findComponent(GlIcon).props('name')).toBe('clock'); }); - describe('computed', () => { - describe('isMilestoneStarted', () => { - it('should return `false` when milestoneStart prop is not defined', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, start_date: '' }, - }); - await nextTick(); - - expect(wrapper.vm.isMilestoneStarted).toBe(false); - }); - - it('should return `true` when milestone start date is past current date', async () => { - await wrapper.setProps({ - milestone: { ...mockMilestone, start_date: '1990-07-22' }, - }); - await nextTick(); + it('renders milestone title', () => { + expect(wrapper.find('.milestone-title').text()).toBe(mockMilestone.title); + }); - expect(wrapper.vm.isMilestoneStarted).toBe(true); - }); + describe('tooltip', () => { + it('renders `Milestone`', () => { + expect(findTooltip().text()).toContain('Milestone'); }); - describe('isMilestonePastDue', () => { - it('should return `false` when milestoneDue prop is not defined', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, due_date: '' }, - }); - await nextTick(); - - expect(wrapper.vm.isMilestonePastDue).toBe(false); - }); - - it('should return `true` when milestone due is past current date', () => { - wrapper.setProps({ - milestone: { ...mockMilestone, due_date: '1990-07-22' }, - }); - - expect(wrapper.vm.isMilestonePastDue).toBe(true); - }); + it('renders milestone title', () => { + expect(findTooltip().text()).toContain(mockMilestone.title); }); - describe('milestoneDatesAbsolute', () => { - it('returns string containing absolute milestone due date', () => { - expect(vm.milestoneDatesAbsolute).toBe('(December 31, 2019)'); - }); + describe('humanized dates', () => { + it('renders `Expired` when there is a due date in the past', () => { + wrapper = createComponent({ ...mockMilestone, due_date: '2019-12-31', start_date: '' }); - it('returns string containing absolute milestone start date when due date is not present', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, due_date: '' }, - }); - await nextTick(); - - expect(wrapper.vm.milestoneDatesAbsolute).toBe('(January 1, 2018)'); + expect(findTooltip().text()).toContain('Expired 6 months ago(December 31, 2019)'); }); - it('returns empty string when both milestone start and due dates are not present', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, start_date: '', due_date: '' }, - }); - await nextTick(); + it('renders `remaining` when there is a due date in the future', () => { + wrapper = createComponent({ ...mockMilestone, due_date: '2020-12-31', start_date: '' }); - expect(wrapper.vm.milestoneDatesAbsolute).toBe(''); + expect(findTooltip().text()).toContain('5 months remaining(December 31, 2020)'); }); - }); - describe('milestoneDatesHuman', () => { - it('returns string containing milestone due date when date is yet to be due', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, due_date: `${new Date().getFullYear() + 10}-01-01` }, - }); - await nextTick(); + it('renders `Started` when there is a start date in the past', () => { + wrapper = createComponent({ ...mockMilestone, due_date: '', start_date: '2019-12-31' }); - expect(wrapper.vm.milestoneDatesHuman).toContain('years remaining'); + expect(findTooltip().text()).toContain('Started 6 months ago(December 31, 2019)'); }); - it('returns string containing milestone start date when date has already started and due date is not present', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, start_date: '1990-07-22', due_date: '' }, - }); - await nextTick(); + it('renders `Starts` when there is a start date in the future', () => { + wrapper = createComponent({ ...mockMilestone, due_date: '', start_date: '2020-12-31' }); - expect(wrapper.vm.milestoneDatesHuman).toContain('Started'); + expect(findTooltip().text()).toContain('Starts in 5 months(December 31, 2020)'); }); - - it('returns string containing milestone start date when date is yet to start and due date is not present', async () => { - wrapper.setProps({ - milestone: { - ...mockMilestone, - start_date: `${new Date().getFullYear() + 10}-01-01`, - due_date: '', - }, - }); - await nextTick(); - - expect(wrapper.vm.milestoneDatesHuman).toContain('Starts'); - }); - - it('returns empty string when milestone start and due dates are not present', async () => { - wrapper.setProps({ - milestone: { ...mockMilestone, start_date: '', due_date: '' }, - }); - await nextTick(); - - expect(wrapper.vm.milestoneDatesHuman).toBe(''); - }); - }); - }); - - describe('template', () => { - it('renders component root element with class `issue-milestone-details`', () => { - expect(vm.$el.classList.contains('issue-milestone-details')).toBe(true); - }); - - it('renders milestone icon', () => { - expect(wrapper.findComponent(GlIcon).props('name')).toBe('clock'); - }); - - it('renders milestone title', () => { - expect(vm.$el.querySelector('.milestone-title').innerText.trim()).toBe(mockMilestone.title); - }); - - it('renders milestone tooltip', () => { - expect(vm.$el.querySelector('.js-item-milestone').innerText.trim()).toContain( - mockMilestone.title, - ); }); }); }); diff --git a/spec/frontend/issuable/components/related_issuable_item_spec.js b/spec/frontend/issuable/components/related_issuable_item_spec.js index 3f9f048605a..3e23558ceb4 100644 --- a/spec/frontend/issuable/components/related_issuable_item_spec.js +++ b/spec/frontend/issuable/components/related_issuable_item_spec.js @@ -53,10 +53,6 @@ describe('RelatedIssuableItem', () => { }); } - afterEach(() => { - wrapper.destroy(); - }); - it('contains issuable-info-container class when canReorder is false', () => { mountComponent({ props: { canReorder: false } }); diff --git a/spec/frontend/issuable/components/status_box_spec.js b/spec/frontend/issuable/components/status_box_spec.js index 728b8958b9b..d26f287d90c 100644 --- a/spec/frontend/issuable/components/status_box_spec.js +++ b/spec/frontend/issuable/components/status_box_spec.js @@ -11,11 +11,6 @@ function factory(propsData) { describe('Merge request status box component', () => { const findBadge = () => wrapper.findComponent(GlBadge); - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - describe.each` issuableType | badgeText | initialState | badgeClass | badgeVariant | badgeIcon ${'merge_request'} | ${'Open'} | ${'opened'} | ${'issuable-status-badge-open'} | ${'success'} | ${'merge-request-open'} diff --git a/spec/frontend/issuable/popover/components/issue_popover_spec.js b/spec/frontend/issuable/popover/components/issue_popover_spec.js index 444165f61c7..a7605016039 100644 --- a/spec/frontend/issuable/popover/components/issue_popover_spec.js +++ b/spec/frontend/issuable/popover/components/issue_popover_spec.js @@ -33,10 +33,6 @@ describe('Issue Popover', () => { }); }; - afterEach(() => { - wrapper.destroy(); - }); - it('shows skeleton-loader while apollo is loading', () => { mountComponent(); diff --git a/spec/frontend/issuable/popover/components/mr_popover_spec.js b/spec/frontend/issuable/popover/components/mr_popover_spec.js index 5fdd1e6e8fc..d9e113eeaae 100644 --- a/spec/frontend/issuable/popover/components/mr_popover_spec.js +++ b/spec/frontend/issuable/popover/components/mr_popover_spec.js @@ -71,10 +71,6 @@ describe('MR Popover', () => { }); }; - afterEach(() => { - wrapper.destroy(); - }); - it('shows skeleton-loader while apollo is loading', () => { mountComponent(); diff --git a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js index 72fcab63ba7..f8e47bc0a4b 100644 --- a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js +++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js @@ -1,9 +1,9 @@ -import { GlFormGroup } from '@gitlab/ui'; +import { GlButton, GlFormGroup, GlFormRadioGroup, GlFormRadio } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; -import { nextTick } from 'vue'; import { TYPE_EPIC, TYPE_ISSUE } from '~/issues/constants'; import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue'; import IssueToken from '~/related_issues/components/issue_token.vue'; +import RelatedIssuableInput from '~/related_issues/components/related_issuable_input.vue'; import { linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants'; const issuable1 = { @@ -26,71 +26,60 @@ const issuable2 = { const pathIdSeparator = PathIdSeparator.Issue; -const findFormInput = (wrapper) => wrapper.find('input').element; - -const findRadioInput = (inputs, value) => - inputs.filter((input) => input.element.value === value)[0]; - -const findRadioInputs = (wrapper) => wrapper.findAll('[name="linked-issue-type-radio"]'); - -const constructWrapper = (props) => { - return shallowMount(AddIssuableForm, { - propsData: { - inputValue: '', - pendingReferences: [], - pathIdSeparator, - ...props, - }, - }); -}; - describe('AddIssuableForm', () => { let wrapper; - afterEach(() => { - // Jest doesn't blur an item even if it is destroyed, - // so blur the input manually after each test - const input = findFormInput(wrapper); - if (input) input.blur(); + const createComponent = (props = {}, mountFn = shallowMount) => { + wrapper = mountFn(AddIssuableForm, { + propsData: { + inputValue: '', + pendingReferences: [], + pathIdSeparator, + ...props, + }, + stubs: { + RelatedIssuableInput, + }, + }); + }; - if (wrapper) { - wrapper.destroy(); - wrapper = null; - } - }); + const findAddIssuableForm = () => wrapper.find('form'); + const findFormInput = () => wrapper.find('input').element; + const findRadioInput = (inputs, value) => + inputs.filter((input) => input.element.value === value)[0]; + const findAllIssueTokens = () => wrapper.findAllComponents(IssueToken); + const findRadioGroup = () => wrapper.findComponent(GlFormRadioGroup); + const findRadioInputs = () => wrapper.findAllComponents(GlFormRadio); + + const findFormGroup = () => wrapper.findComponent(GlFormGroup); + const findFormButtons = () => wrapper.findAllComponents(GlButton); + const findSubmitButton = () => findFormButtons().at(0); + const findRelatedIssuableInput = () => wrapper.findComponent(RelatedIssuableInput); describe('with data', () => { describe('without references', () => { describe('without any input text', () => { beforeEach(() => { - wrapper = shallowMount(AddIssuableForm, { - propsData: { - inputValue: '', - pendingReferences: [], - pathIdSeparator, - }, - }); + createComponent(); }); it('should have disabled submit button', () => { - expect(wrapper.vm.$refs.addButton.disabled).toBe(true); - expect(wrapper.vm.$refs.loadingIcon).toBeUndefined(); + expect(findSubmitButton().props('disabled')).toBe(true); + expect(findSubmitButton().props('loading')).toBe(false); }); }); describe('with input text', () => { beforeEach(() => { - wrapper = shallowMount(AddIssuableForm, { - propsData: { - inputValue: 'foo', - pendingReferences: [], - pathIdSeparator, - }, + createComponent({ + inputValue: 'foo', + pendingReferences: [], + pathIdSeparator, }); }); it('should not have disabled submit button', () => { - expect(wrapper.vm.$refs.addButton.disabled).toBe(false); + expect(findSubmitButton().props('disabled')).toBe(false); }); }); }); @@ -99,59 +88,56 @@ describe('AddIssuableForm', () => { const inputValue = 'foo #123'; beforeEach(() => { - wrapper = mount(AddIssuableForm, { - propsData: { - inputValue, - pendingReferences: [issuable1.reference, issuable2.reference], - pathIdSeparator, - }, + createComponent({ + inputValue, + pendingReferences: [issuable1.reference, issuable2.reference], + pathIdSeparator, }); - }); + }, mount); it('should put input value in place', () => { expect(findFormInput(wrapper).value).toBe(inputValue); }); it('should render pending issuables items', () => { - expect(wrapper.findAllComponents(IssueToken)).toHaveLength(2); + expect(findAllIssueTokens()).toHaveLength(2); }); it('should not have disabled submit button', () => { - expect(wrapper.vm.$refs.addButton.disabled).toBe(false); + expect(findSubmitButton().props('disabled')).toBe(false); }); }); describe('when issuable type is "issue"', () => { beforeEach(() => { - wrapper = mount(AddIssuableForm, { - propsData: { + createComponent( + { inputValue: '', issuableType: TYPE_ISSUE, pathIdSeparator, pendingReferences: [], }, - }); + mount, + ); }); it('does not show radio inputs', () => { - expect(findRadioInputs(wrapper).length).toBe(0); + expect(findRadioInputs()).toHaveLength(0); }); }); describe('when issuable type is "epic"', () => { beforeEach(() => { - wrapper = shallowMount(AddIssuableForm, { - propsData: { - inputValue: '', - issuableType: TYPE_EPIC, - pathIdSeparator, - pendingReferences: [], - }, + createComponent({ + inputValue: '', + issuableType: TYPE_EPIC, + pathIdSeparator, + pendingReferences: [], }); }); it('does not show radio inputs', () => { - expect(findRadioInputs(wrapper).length).toBe(0); + expect(findRadioInputs()).toHaveLength(0); }); }); @@ -163,17 +149,15 @@ describe('AddIssuableForm', () => { `( 'show header text as "$contextHeader" and footer text as "$contextFooter" issuableType is set to $issuableType', ({ issuableType, contextHeader, contextFooter }) => { - wrapper = shallowMount(AddIssuableForm, { - propsData: { - issuableType, - inputValue: '', - showCategorizedIssues: true, - pathIdSeparator, - pendingReferences: [], - }, + createComponent({ + issuableType, + inputValue: '', + showCategorizedIssues: true, + pathIdSeparator, + pendingReferences: [], }); - expect(wrapper.findComponent(GlFormGroup).attributes('label')).toBe(contextHeader); + expect(findFormGroup().attributes('label')).toBe(contextHeader); expect(wrapper.find('p.bold').text()).toContain(contextFooter); }, ); @@ -181,26 +165,24 @@ describe('AddIssuableForm', () => { describe('when it is a Linked Issues form', () => { beforeEach(() => { - wrapper = mount(AddIssuableForm, { - propsData: { - inputValue: '', - showCategorizedIssues: true, - issuableType: TYPE_ISSUE, - pathIdSeparator, - pendingReferences: [], - }, + createComponent({ + inputValue: '', + showCategorizedIssues: true, + issuableType: TYPE_ISSUE, + pathIdSeparator, + pendingReferences: [], }); }); it('shows radio inputs to allow categorisation of blocking issues', () => { - expect(findRadioInputs(wrapper).length).toBeGreaterThan(0); + expect(findRadioGroup().props('options').length).toBeGreaterThan(0); }); describe('form radio buttons', () => { let radioInputs; beforeEach(() => { - radioInputs = findRadioInputs(wrapper); + radioInputs = findRadioInputs(); }); it('shows "relates to" option', () => { @@ -216,58 +198,59 @@ describe('AddIssuableForm', () => { }); it('shows 3 options in total', () => { - expect(radioInputs.length).toBe(3); + expect(findRadioGroup().props('options')).toHaveLength(3); }); }); describe('when the form is submitted', () => { - it('emits an event with a "relates_to" link type when the "relates to" radio input selected', async () => { - jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); - - wrapper.vm.linkedIssueType = linkedIssueTypesMap.RELATES_TO; - wrapper.vm.onFormSubmit(); - - await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { - pendingReferences: '', - linkedIssueType: linkedIssueTypesMap.RELATES_TO, - }); + it('emits an event with a "relates_to" link type when the "relates to" radio input selected', () => { + findAddIssuableForm().trigger('submit'); + + expect(wrapper.emitted('addIssuableFormSubmit')).toEqual([ + [ + { + pendingReferences: '', + linkedIssueType: linkedIssueTypesMap.RELATES_TO, + }, + ], + ]); }); - it('emits an event with a "blocks" link type when the "blocks" radio input selected', async () => { - jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); - - wrapper.vm.linkedIssueType = linkedIssueTypesMap.BLOCKS; - wrapper.vm.onFormSubmit(); - - await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { - pendingReferences: '', - linkedIssueType: linkedIssueTypesMap.BLOCKS, - }); + it('emits an event with a "blocks" link type when the "blocks" radio input selected', () => { + findRadioGroup().vm.$emit('input', linkedIssueTypesMap.BLOCKS); + findAddIssuableForm().trigger('submit'); + + expect(wrapper.emitted('addIssuableFormSubmit')).toEqual([ + [ + { + pendingReferences: '', + linkedIssueType: linkedIssueTypesMap.BLOCKS, + }, + ], + ]); }); it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', async () => { - jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); - - wrapper.vm.linkedIssueType = linkedIssueTypesMap.IS_BLOCKED_BY; - wrapper.vm.onFormSubmit(); - - await nextTick(); - expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { - pendingReferences: '', - linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY, - }); + findRadioGroup().vm.$emit('input', linkedIssueTypesMap.IS_BLOCKED_BY); + findAddIssuableForm().trigger('submit'); + + expect(wrapper.emitted('addIssuableFormSubmit')).toEqual([ + [ + { + pendingReferences: '', + linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY, + }, + ], + ]); }); - it('shows error message when error is present', async () => { + it('shows error message when error is present', () => { const itemAddFailureMessage = 'Something went wrong while submitting.'; - wrapper.setProps({ + createComponent({ hasError: true, itemAddFailureMessage, }); - await nextTick(); expect(wrapper.find('.gl-field-error').exists()).toBe(true); expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage); }); @@ -283,27 +266,31 @@ describe('AddIssuableForm', () => { }; it('returns autocomplete object', () => { - wrapper = constructWrapper({ + createComponent({ autoCompleteSources, }); - expect(wrapper.vm.transformedAutocompleteSources).toBe(autoCompleteSources); + expect(findRelatedIssuableInput().props('autoCompleteSources')).toEqual( + autoCompleteSources, + ); - wrapper = constructWrapper({ + createComponent({ autoCompleteSources, confidential: false, }); - expect(wrapper.vm.transformedAutocompleteSources).toBe(autoCompleteSources); + expect(findRelatedIssuableInput().props('autoCompleteSources')).toEqual( + autoCompleteSources, + ); }); it('returns autocomplete sources with query `confidential_only`, when it is confidential', () => { - wrapper = constructWrapper({ + createComponent({ autoCompleteSources, confidential: true, }); - const actualSources = wrapper.vm.transformedAutocompleteSources; + const actualSources = findRelatedIssuableInput().props('autoCompleteSources'); expect(actualSources.epics).toContain('?confidential_only=true'); expect(actualSources.issues).toContain('?confidential_only=true'); diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js index ff8d5073005..b9580b90c12 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js @@ -1,5 +1,5 @@ import { nextTick } from 'vue'; -import { GlIcon } from '@gitlab/ui'; +import { GlIcon, GlCard } from '@gitlab/ui'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { issuable1, @@ -78,6 +78,9 @@ describe('RelatedIssuesBlock', () => { pathIdSeparator: PathIdSeparator.Issue, issuableType: 'issue', }, + stubs: { + GlCard, + }, slots: { 'header-text': headerText }, }); @@ -94,6 +97,9 @@ describe('RelatedIssuesBlock', () => { pathIdSeparator: PathIdSeparator.Issue, issuableType: 'issue', }, + stubs: { + GlCard, + }, slots: { 'header-actions': headerActions }, }); @@ -222,6 +228,9 @@ describe('RelatedIssuesBlock', () => { pathIdSeparator: PathIdSeparator.Issue, issuableType, }, + stubs: { + GlCard, + }, }); const iconComponent = wrapper.findComponent(GlIcon); @@ -239,6 +248,9 @@ describe('RelatedIssuesBlock', () => { relatedIssues: [issuable1, issuable2, issuable3], issuableType: TYPE_ISSUE, }, + stubs: { + GlCard, + }, }); }); diff --git a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js index 96c0b87e2cb..1383013aedb 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js @@ -7,7 +7,7 @@ import { issuable1, issuable2, } from 'jest/issuable/components/related_issuable_mock_data'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_CONFLICT, @@ -19,7 +19,7 @@ import RelatedIssuesBlock from '~/related_issues/components/related_issues_block import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue'; import relatedIssuesService from '~/related_issues/services/related_issues_service'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('RelatedIssuesRoot', () => { let wrapper; @@ -34,7 +34,6 @@ describe('RelatedIssuesRoot', () => { afterEach(() => { mock.restore(); - wrapper.destroy(); }); const createComponent = ({ props = {}, data = {} } = {}) => { |