summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/sidebar/labels_select_vue
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/sidebar/labels_select_vue')
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed_spec.js121
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js72
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);
});
});
});