diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/sidebar/labels_select_vue')
2 files changed, 83 insertions, 110 deletions
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed_spec.js index 8c1693e8dcc..a7f9391cb5f 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed_spec.js @@ -1,95 +1,74 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlIcon } from '@gitlab/ui'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import DropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import dropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue'; +import { mockCollapsedLabels as mockLabels, mockRegularLabel } from './mock_data'; -import { mockCollapsedLabels as mockLabels } from './mock_data'; - -const createComponent = (labels = mockLabels) => { - const Component = Vue.extend(dropdownValueCollapsedComponent); +describe('DropdownValueCollapsedComponent', () => { + let wrapper; - return mountComponent(Component, { - labels, - }); -}; + const defaultProps = { + labels: [], + }; -describe('DropdownValueCollapsedComponent', () => { - let vm; + const mockManyLabels = [...mockLabels, ...mockLabels, ...mockLabels]; - beforeEach(() => { - vm = createComponent(); - }); + const createComponent = ({ props = {} } = {}) => { + wrapper = shallowMount(DropdownValueCollapsedComponent, { + propsData: { ...defaultProps, ...props }, + directives: { + GlTooltip: createMockDirective(), + }, + }); + }; afterEach(() => { - vm.$destroy(); + wrapper.destroy(); }); - describe('computed', () => { - describe('labelsList', () => { - it('returns default text when `labels` prop is empty array', () => { - const vmEmptyLabels = createComponent([]); + const findGlIcon = () => wrapper.findComponent(GlIcon); + const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip'); - expect(vmEmptyLabels.labelsList).toBe('Labels'); - vmEmptyLabels.$destroy(); - }); - - it('returns labels names separated by coma when `labels` prop has more than one item', () => { - const labels = mockLabels.concat(mockLabels); - const vmMoreLabels = createComponent(labels); + describe('template', () => { + it('renders tags icon element', () => { + createComponent(); - const expectedText = labels.map((label) => label.title).join(', '); + expect(findGlIcon().exists()).toBe(true); + }); - expect(vmMoreLabels.labelsList).toBe(expectedText); - vmMoreLabels.$destroy(); - }); + it('emits onValueClick event on click', async () => { + createComponent(); - it('returns labels names separated by coma with remaining labels count and `and more` phrase when `labels` prop has more than five items', () => { - const mockMoreLabels = Object.assign([], mockLabels); - for (let i = 0; i < 6; i += 1) { - mockMoreLabels.unshift(mockLabels[0]); - } + wrapper.trigger('click'); - const vmMoreLabels = createComponent(mockMoreLabels); + await wrapper.vm.$nextTick(); - const expectedText = `${mockMoreLabels - .slice(0, 5) - .map((label) => label.title) - .join(', ')}, and ${mockMoreLabels.length - 5} more`; + expect(wrapper.emitted('onValueClick')[0]).toBeDefined(); + }); - expect(vmMoreLabels.labelsList).toBe(expectedText); - vmMoreLabels.$destroy(); + describe.each` + scenario | labels | expectedResult | expectedText + ${'`labels` is empty'} | ${[]} | ${'default text'} | ${'Labels'} + ${'`labels` has 1 item'} | ${[mockRegularLabel]} | ${'label name'} | ${'Foo Label'} + ${'`labels` has 2 items'} | ${mockLabels} | ${'comma separated label names'} | ${'Foo Label, Foo::Bar'} + ${'`labels` has more than 5 items'} | ${mockManyLabels} | ${'comma separated label names with "and more" phrase'} | ${'Foo Label, Foo::Bar, Foo Label, Foo::Bar, Foo Label, and 1 more'} + `('when $scenario', ({ labels, expectedResult, expectedText }) => { + beforeEach(() => { + createComponent({ + props: { + labels, + }, + }); }); - it('returns first label name when `labels` prop has only one item present', () => { - const text = mockLabels.map((label) => label.title).join(', '); - - expect(vm.labelsList).toBe(text); + it('renders labels count', () => { + expect(wrapper.text()).toBe(`${labels.length}`); }); - }); - }); - - describe('methods', () => { - describe('handleClick', () => { - it('emits onValueClick event on component', () => { - jest.spyOn(vm, '$emit').mockImplementation(() => {}); - vm.handleClick(); - expect(vm.$emit).toHaveBeenCalledWith('onValueClick'); + it(`renders "${expectedResult}" as tooltip`, () => { + expect(getTooltip().value).toBe(expectedText); }); }); }); - - describe('template', () => { - it('renders component container element with tooltip`', () => { - expect(vm.$el.title).toBe(vm.labelsList); - }); - - it('renders tags icon element', () => { - expect(vm.$el.querySelector('[data-testid="labels-icon"]')).not.toBeNull(); - }); - - it('renders labels count', () => { - expect(vm.$el.querySelector('span').innerText.trim()).toBe(`${vm.labels.length}`); - }); - }); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js index d9b7cd5afa2..a60e6f52862 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js @@ -1,3 +1,4 @@ +import { cloneDeep } from 'lodash'; import * as types from '~/vue_shared/components/sidebar/labels_select_vue/store/mutation_types'; import mutations from '~/vue_shared/components/sidebar/labels_select_vue/store/mutations'; @@ -153,47 +154,40 @@ describe('LabelsSelect Mutations', () => { }); describe(`${types.UPDATE_SELECTED_LABELS}`, () => { - let labels; - - beforeEach(() => { - labels = [ - { id: 1, title: 'scoped' }, - { id: 2, title: 'scoped::one', set: false }, - { id: 3, title: 'scoped::test', set: true }, - { id: 4, title: '' }, - ]; - }); - - it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => { - const updatedLabelIds = [2]; - const state = { - labels, - }; - mutations[types.UPDATE_SELECTED_LABELS](state, { labels: [{ id: 2 }] }); - - state.labels.forEach((label) => { - if (updatedLabelIds.includes(label.id)) { - expect(label.touched).toBe(true); - expect(label.set).toBe(true); - } + const labels = [ + { id: 1, title: 'scoped' }, + { id: 2, title: 'scoped::label::one', set: false }, + { id: 3, title: 'scoped::label::two', set: false }, + { id: 4, title: 'scoped::label::three', set: true }, + { id: 5, title: 'scoped::one', set: false }, + { id: 6, title: 'scoped::two', set: false }, + { id: 7, title: 'scoped::three', set: true }, + { id: 8, title: '' }, + ]; + + it.each` + label | labelGroupIds + ${labels[0]} | ${[]} + ${labels[1]} | ${[labels[2], labels[3]]} + ${labels[2]} | ${[labels[1], labels[3]]} + ${labels[3]} | ${[labels[1], labels[2]]} + ${labels[4]} | ${[labels[5], labels[6]]} + ${labels[5]} | ${[labels[4], labels[6]]} + ${labels[6]} | ${[labels[4], labels[5]]} + ${labels[7]} | ${[]} + `('updates `touched` and `set` props for $label.title', ({ label, labelGroupIds }) => { + const state = { labels: cloneDeep(labels) }; + + mutations[types.UPDATE_SELECTED_LABELS](state, { labels: [{ id: label.id }] }); + + expect(state.labels[label.id - 1]).toMatchObject({ + touched: true, + set: !labels[label.id - 1].set, }); - }); - describe('when label is scoped', () => { - it('unsets the currently selected scoped label and sets the current label', () => { - const state = { - labels, - }; - mutations[types.UPDATE_SELECTED_LABELS](state, { - labels: [{ id: 2, title: 'scoped::one' }], - }); - - expect(state.labels).toEqual([ - { id: 1, title: 'scoped' }, - { id: 2, title: 'scoped::one', set: true, touched: true }, - { id: 3, title: 'scoped::test', set: false }, - { id: 4, title: '' }, - ]); + labelGroupIds.forEach((l) => { + expect(state.labels[l.id - 1].touched).toBeFalsy(); + expect(state.labels[l.id - 1].set).toBe(false); }); }); }); |