diff options
Diffstat (limited to 'spec/frontend/issuable/related_issues/components')
4 files changed, 93 insertions, 179 deletions
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 bfbe4ec8e70..17a195df494 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 @@ -48,7 +48,10 @@ describe('AddIssuableForm', () => { const input = findFormInput(wrapper); if (input) input.blur(); - wrapper.destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); describe('with data', () => { diff --git a/spec/frontend/issuable/related_issues/components/issue_token_spec.js b/spec/frontend/issuable/related_issues/components/issue_token_spec.js index 553721fa783..f2cb9042ba6 100644 --- a/spec/frontend/issuable/related_issues/components/issue_token_spec.js +++ b/spec/frontend/issuable/related_issues/components/issue_token_spec.js @@ -1,241 +1,146 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; import { PathIdSeparator } from '~/related_issues/constants'; -import issueToken from '~/related_issues/components/issue_token.vue'; +import IssueToken from '~/related_issues/components/issue_token.vue'; describe('IssueToken', () => { const idKey = 200; const displayReference = 'foo/bar#123'; - const title = 'some title'; - const pathIdSeparator = PathIdSeparator.Issue; const eventNamespace = 'pendingIssuable'; - let IssueToken; - let vm; + const path = '/foo/bar/issues/123'; + const pathIdSeparator = PathIdSeparator.Issue; + const title = 'some title'; - beforeEach(() => { - IssueToken = Vue.extend(issueToken); - }); + let wrapper; + + const defaultProps = { + idKey, + displayReference, + pathIdSeparator, + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(IssueToken, { + propsData: { ...defaultProps, ...props }, + }); + }; afterEach(() => { - if (vm) { - vm.$destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; } }); + const findLink = () => wrapper.find({ ref: 'link' }); + const findReference = () => wrapper.find({ ref: 'reference' }); + const findReferenceIcon = () => wrapper.find('[data-testid="referenceIcon"]'); + const findRemoveBtn = () => wrapper.find('[data-testid="removeBtn"]'); + const findTitle = () => wrapper.find({ ref: 'title' }); + describe('with reference supplied', () => { beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - }, - }).$mount(); + createComponent(); }); it('shows reference', () => { - expect(vm.$el.textContent.trim()).toEqual(displayReference); + expect(wrapper.text()).toContain(displayReference); }); it('does not link without path specified', () => { - expect(vm.$refs.link.tagName.toLowerCase()).toEqual('span'); - expect(vm.$refs.link.getAttribute('href')).toBeNull(); + expect(findLink().element.tagName).toBe('SPAN'); + expect(findLink().attributes('href')).toBeUndefined(); }); }); describe('with reference and title supplied', () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - title, - }, - }).$mount(); - }); - it('shows reference and title', () => { - expect(vm.$refs.reference.textContent.trim()).toEqual(displayReference); - expect(vm.$refs.title.textContent.trim()).toEqual(title); - }); - }); - - describe('with path supplied', () => { - const path = '/foo/bar/issues/123'; - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - title, - path, - }, - }).$mount(); - }); + createComponent({ + title, + }); - it('links reference and title', () => { - expect(vm.$refs.link.getAttribute('href')).toEqual(path); + expect(findReference().text()).toBe(displayReference); + expect(findTitle().text()).toBe(title); }); }); - describe('with state supplied', () => { - describe("`state: 'opened'`", () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - state: 'opened', - }, - }).$mount(); + describe('with path and title supplied', () => { + it('links reference and title', () => { + createComponent({ + path, + title, }); - it('shows green circle icon', () => { - expect(vm.$el.querySelector('.issue-token-state-icon-open.fa.fa-circle-o')).toBeDefined(); - }); - }); - - describe("`state: 'reopened'`", () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - state: 'reopened', - }, - }).$mount(); - }); - - it('shows green circle icon', () => { - expect(vm.$el.querySelector('.issue-token-state-icon-open.fa.fa-circle-o')).toBeDefined(); - }); + expect(findLink().attributes('href')).toBe(path); }); + }); - describe("`state: 'closed'`", () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - state: 'closed', - }, - }).$mount(); + describe('with state supplied', () => { + it.each` + state | icon | cssClass + ${'opened'} | ${'issue-open-m'} | ${'issue-token-state-icon-open'} + ${'reopened'} | ${'issue-open-m'} | ${'issue-token-state-icon-open'} + ${'closed'} | ${'issue-close'} | ${'issue-token-state-icon-closed'} + `('shows "$icon" icon when "$state"', ({ state, icon, cssClass }) => { + createComponent({ + path, + state, }); - it('shows red minus icon', () => { - expect(vm.$el.querySelector('.issue-token-state-icon-closed.fa.fa-minus')).toBeDefined(); - }); + expect(findReferenceIcon().props('name')).toBe(icon); + expect(findReferenceIcon().classes()).toContain(cssClass); }); }); describe('with reference, title, state', () => { const state = 'opened'; - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - title, - state, - }, - }).$mount(); - }); it('shows reference, title, and state', () => { - const stateIcon = vm.$refs.reference.querySelector('svg'); + createComponent({ + title, + state, + }); - expect(stateIcon.getAttribute('aria-label')).toEqual(state); - expect(vm.$refs.reference.textContent.trim()).toEqual(displayReference); - expect(vm.$refs.title.textContent.trim()).toEqual(title); + expect(findReferenceIcon().attributes('aria-label')).toBe(state); + expect(findReference().text()).toBe(displayReference); + expect(findTitle().text()).toBe(title); }); }); describe('with canRemove', () => { describe('`canRemove: false` (default)', () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - }, - }).$mount(); - }); - it('does not have remove button', () => { - expect(vm.$el.querySelector('.issue-token-remove-button')).toBeNull(); + createComponent(); + + expect(findRemoveBtn().exists()).toBe(false); }); }); describe('`canRemove: true`', () => { beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - canRemove: true, - }, - }).$mount(); + createComponent({ + eventNamespace, + canRemove: true, + }); }); it('has remove button', () => { - expect(vm.$el.querySelector('.issue-token-remove-button')).toBeDefined(); + expect(findRemoveBtn().exists()).toBe(true); }); - }); - }); - - describe('methods', () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - }, - }).$mount(); - }); - it('when getting checked', () => { - jest.spyOn(vm, '$emit').mockImplementation(() => {}); - vm.onRemoveRequest(); + it('emits event when clicked', () => { + findRemoveBtn().trigger('click'); - expect(vm.$emit).toHaveBeenCalledWith('pendingIssuableRemoveRequest', vm.idKey); - }); - }); + const emitted = wrapper.emitted(`${eventNamespace}RemoveRequest`); - describe('tooltip', () => { - beforeEach(() => { - vm = new IssueToken({ - propsData: { - idKey, - eventNamespace, - displayReference, - pathIdSeparator, - canRemove: true, - }, - }).$mount(); - }); - - it('should not be escaped', () => { - const { originalTitle } = vm.$refs.removeButton.dataset; + expect(emitted).toHaveLength(1); + expect(emitted[0]).toEqual([idKey]); + }); - expect(originalTitle).toEqual(`Remove ${displayReference}`); + it('tooltip should not be escaped', () => { + expect(findRemoveBtn().attributes('data-original-title')).toBe( + `Remove ${displayReference}`, + ); + }); }); }); }); 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 0f88e4d71fe..b758b85beef 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 @@ -18,7 +18,10 @@ describe('RelatedIssuesBlock', () => { const findIssueCountBadgeAddButton = () => wrapper.find(GlButton); afterEach(() => { - wrapper.destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); describe('with defaults', () => { diff --git a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js index 6cf0b9d21ea..39bc244297b 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js @@ -14,7 +14,10 @@ describe('RelatedIssuesList', () => { let wrapper; afterEach(() => { - wrapper.destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); describe('with defaults', () => { |