diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/sidebar')
16 files changed, 316 insertions, 76 deletions
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js index d90fafb6bf7..9db86fa775f 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js @@ -4,10 +4,7 @@ import { shallowMount } from '@vue/test-utils'; import LabelsSelect from '~/labels_select'; import BaseComponent from '~/vue_shared/components/sidebar/labels_select/base.vue'; -import { - mockConfig, - mockLabels, -} from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockConfig, mockLabels } from './mock_data'; const createComponent = (config = mockConfig) => shallowMount(BaseComponent, { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js index e2e11c94c0d..d02d924bd2b 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js @@ -3,16 +3,14 @@ import Vue from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import dropdownButtonComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_button.vue'; -import { - mockConfig, - mockLabels, -} from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockConfig, mockLabels } from './mock_data'; -const componentConfig = Object.assign({}, mockConfig, { +const componentConfig = { + ...mockConfig, fieldName: 'label_id[]', labels: mockLabels, showExtraOptions: false, -}); +}; const createComponent = (config = componentConfig) => { const Component = Vue.extend(dropdownButtonComponent); @@ -34,7 +32,7 @@ describe('DropdownButtonComponent', () => { describe('computed', () => { describe('dropdownToggleText', () => { it('returns text as `Label` when `labels` prop is empty array', () => { - const mockEmptyLabels = Object.assign({}, componentConfig, { labels: [] }); + const mockEmptyLabels = { ...componentConfig, labels: [] }; const vmEmptyLabels = createComponent(mockEmptyLabels); expect(vmEmptyLabels.dropdownToggleText).toBe('Label'); @@ -42,9 +40,7 @@ describe('DropdownButtonComponent', () => { }); it('returns first label name with remaining label count when `labels` prop has more than one item', () => { - const mockMoreLabels = Object.assign({}, componentConfig, { - labels: mockLabels.concat(mockLabels), - }); + const mockMoreLabels = { ...componentConfig, labels: mockLabels.concat(mockLabels) }; const vmMoreLabels = createComponent(mockMoreLabels); expect(vmMoreLabels.dropdownToggleText).toBe( @@ -54,9 +50,7 @@ describe('DropdownButtonComponent', () => { }); it('returns first label name when `labels` prop has only one item present', () => { - const singleLabel = Object.assign({}, componentConfig, { - labels: [mockLabels[0]], - }); + const singleLabel = { ...componentConfig, labels: [mockLabels[0]] }; const vmSingleLabel = createComponent(singleLabel); expect(vmSingleLabel.dropdownToggleText).toBe(mockLabels[0].title); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js index d0299523137..edec3b138b3 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js @@ -3,7 +3,7 @@ import Vue from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import dropdownCreateLabelComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue'; -import { mockSuggestedColors } from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockSuggestedColors } from './mock_data'; const createComponent = headerTitle => { const Component = Vue.extend(dropdownCreateLabelComponent); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js index 784bbaf8e6a..7e9e242a4f5 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js @@ -3,7 +3,7 @@ import Vue from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import dropdownFooterComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_footer.vue'; -import { mockConfig } from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockConfig } from './mock_data'; const createComponent = ( labelsWebUrl = mockConfig.labelsWebUrl, diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js index 887c04268d1..e09f0006359 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js @@ -3,7 +3,7 @@ import Vue from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import dropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue'; -import { mockLabels } from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockLabels } from './mock_data'; const createComponent = (labels = mockLabels) => { const Component = Vue.extend(dropdownValueCollapsedComponent); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js index 06355c0dd65..c33cffb421d 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js @@ -2,10 +2,7 @@ import { mount } from '@vue/test-utils'; import DropdownValueComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_value.vue'; import { GlLabel } from '@gitlab/ui'; -import { - mockConfig, - mockLabels, -} from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; +import { mockConfig, mockLabels } from './mock_data'; const createComponent = ( labels = mockLabels, diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select/mock_data.js new file mode 100644 index 00000000000..6564c012e67 --- /dev/null +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/mock_data.js @@ -0,0 +1,57 @@ +export const mockLabels = [ + { + id: 26, + title: 'Foo Label', + description: 'Foobar', + color: '#BADA55', + text_color: '#FFFFFF', + }, + { + id: 27, + title: 'Foo::Bar', + description: 'Foobar', + color: '#0033CC', + text_color: '#FFFFFF', + }, +]; + +export const mockSuggestedColors = [ + '#0033CC', + '#428BCA', + '#44AD8E', + '#A8D695', + '#5CB85C', + '#69D100', + '#004E00', + '#34495E', + '#7F8C8D', + '#A295D6', + '#5843AD', + '#8E44AD', + '#FFECDB', + '#AD4363', + '#D10069', + '#CC0033', + '#FF0000', + '#D9534F', + '#D1D100', + '#F0AD4E', + '#AD8D43', +]; + +export const mockConfig = { + showCreate: true, + isProject: true, + abilityName: 'issue', + context: { + labels: mockLabels, + }, + namespace: 'gitlab-org', + updatePath: '/gitlab-org/my-project/issue/1', + labelsPath: '/gitlab-org/my-project/-/labels.json', + labelsWebUrl: '/gitlab-org/my-project/-/labels', + labelFilterBasePath: '/gitlab-org/my-project/issues', + canEdit: true, + suggestedColors: mockSuggestedColors, + emptyValueText: 'None', +}; diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js index e2d31a41e82..214eb239432 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js @@ -33,9 +33,32 @@ describe('DropdownButton', () => { wrapper.destroy(); }); + describe('methods', () => { + describe('handleButtonClick', () => { + it('calls action `toggleDropdownContents` and stops event propagation when `state.variant` is "standalone"', () => { + const event = { + stopPropagation: jest.fn(), + }; + wrapper = createComponent({ + ...mockConfig, + variant: 'standalone', + }); + + jest.spyOn(wrapper.vm, 'toggleDropdownContents'); + + wrapper.vm.handleButtonClick(event); + + expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled(); + expect(event.stopPropagation).toHaveBeenCalled(); + + wrapper.destroy(); + }); + }); + }); + describe('template', () => { it('renders component container element', () => { - expect(wrapper.is('gl-deprecated-button-stub')).toBe(true); + expect(wrapper.is('gl-button-stub')).toBe(true); }); it('renders button text element', () => { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js index d7ca7ce30a9..04320a72be6 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js @@ -1,7 +1,7 @@ import Vuex from 'vuex'; import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { GlDeprecatedButton, GlIcon, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui'; +import { GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui'; import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue'; import labelSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store'; @@ -127,12 +127,12 @@ describe('DropdownContentsCreateView', () => { it('renders dropdown back button element', () => { const backBtnEl = wrapper .find('.dropdown-title') - .findAll(GlDeprecatedButton) + .findAll(GlButton) .at(0); expect(backBtnEl.exists()).toBe(true); expect(backBtnEl.attributes('aria-label')).toBe('Go back'); - expect(backBtnEl.find(GlIcon).props('name')).toBe('arrow-left'); + expect(backBtnEl.props('icon')).toBe('arrow-left'); }); it('renders dropdown title element', () => { @@ -145,12 +145,12 @@ describe('DropdownContentsCreateView', () => { it('renders dropdown close button element', () => { const closeBtnEl = wrapper .find('.dropdown-title') - .findAll(GlDeprecatedButton) + .findAll(GlButton) .at(1); expect(closeBtnEl.exists()).toBe(true); expect(closeBtnEl.attributes('aria-label')).toBe('Close'); - expect(closeBtnEl.find(GlIcon).props('name')).toBe('close'); + expect(closeBtnEl.props('icon')).toBe('close'); }); it('renders label title input element', () => { @@ -192,7 +192,7 @@ describe('DropdownContentsCreateView', () => { it('renders create button element', () => { const createBtnEl = wrapper .find('.dropdown-actions') - .findAll(GlDeprecatedButton) + .findAll(GlButton) .at(0); expect(createBtnEl.exists()).toBe(true); @@ -213,7 +213,7 @@ describe('DropdownContentsCreateView', () => { it('renders cancel button element', () => { const cancelBtnEl = wrapper .find('.dropdown-actions') - .findAll(GlDeprecatedButton) + .findAll(GlButton) .at(1); expect(cancelBtnEl.exists()).toBe(true); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js index 3e6dbdb7ecb..74c769f86a3 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js @@ -1,9 +1,10 @@ import Vuex from 'vuex'; import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { GlDeprecatedButton, GlLoadingIcon, GlIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui'; +import { GlButton, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue'; +import LabelItem from '~/vue_shared/components/sidebar/labels_select_vue/label_item.vue'; import defaultState from '~/vue_shared/components/sidebar/labels_select_vue/store/state'; import mutations from '~/vue_shared/components/sidebar/labels_select_vue/store/mutations'; @@ -41,13 +42,19 @@ const createComponent = (initialState = mockConfig) => { describe('DropdownContentsLabelsView', () => { let wrapper; + let wrapperStandalone; beforeEach(() => { wrapper = createComponent(); + wrapperStandalone = createComponent({ + ...mockConfig, + variant: 'standalone', + }); }); afterEach(() => { wrapper.destroy(); + wrapperStandalone.destroy(); }); describe('computed', () => { @@ -72,16 +79,6 @@ describe('DropdownContentsLabelsView', () => { }); describe('methods', () => { - describe('getDropdownLabelBoxStyle', () => { - it('returns an object containing `backgroundColor` based on provided `label` param', () => { - expect(wrapper.vm.getDropdownLabelBoxStyle(mockRegularLabel)).toEqual( - expect.objectContaining({ - backgroundColor: mockRegularLabel.color, - }), - ); - }); - }); - describe('isLabelSelected', () => { it('returns true when provided `label` param is one of the selected labels', () => { expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true); @@ -165,13 +162,24 @@ describe('DropdownContentsLabelsView', () => { }); describe('handleLabelClick', () => { - it('calls action `updateSelectedLabels` with provided `label` param', () => { + beforeEach(() => { jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation(); + }); + it('calls action `updateSelectedLabels` with provided `label` param', () => { wrapper.vm.handleLabelClick(mockRegularLabel); expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockRegularLabel]); }); + + it('calls action `toggleDropdownContents` when `state.allowMultiselect` is false', () => { + jest.spyOn(wrapper.vm, 'toggleDropdownContents'); + wrapper.vm.$store.state.allowMultiselect = false; + + wrapper.vm.handleLabelClick(mockRegularLabel); + + expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled(); + }); }); }); @@ -198,12 +206,15 @@ describe('DropdownContentsLabelsView', () => { expect(titleEl.text()).toBe('Assign labels'); }); + it('does not render dropdown title element when `state.variant` is "standalone"', () => { + expect(wrapperStandalone.find('.dropdown-title').exists()).toBe(false); + }); + it('renders dropdown close button element', () => { - const closeButtonEl = wrapper.find('.dropdown-title').find(GlDeprecatedButton); + const closeButtonEl = wrapper.find('.dropdown-title').find(GlButton); expect(closeButtonEl.exists()).toBe(true); - expect(closeButtonEl.find(GlIcon).exists()).toBe(true); - expect(closeButtonEl.find(GlIcon).props('name')).toBe('close'); + expect(closeButtonEl.props('icon')).toBe('close'); }); it('renders label search input element', () => { @@ -214,16 +225,7 @@ describe('DropdownContentsLabelsView', () => { }); it('renders label elements for all labels', () => { - const labelsEl = wrapper.findAll('.dropdown-content li'); - const labelItemEl = labelsEl.at(0).find(GlLink); - - expect(labelsEl.length).toBe(mockLabels.length); - expect(labelItemEl.exists()).toBe(true); - expect(labelItemEl.find(GlIcon).props('name')).toBe('mobile-issue-close'); - expect(labelItemEl.find('.dropdown-label-box').attributes('style')).toBe( - 'background-color: rgb(186, 218, 85);', - ); - expect(labelItemEl.find(GlLink).text()).toContain(mockLabels[0].title); + expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length); }); it('renders label element with "is-focused" when value of `currentHighlightItem` is more than -1', () => { @@ -233,9 +235,9 @@ describe('DropdownContentsLabelsView', () => { return wrapper.vm.$nextTick(() => { const labelsEl = wrapper.findAll('.dropdown-content li'); - const labelItemEl = labelsEl.at(0).find(GlLink); + const labelItemEl = labelsEl.at(0).find(LabelItem); - expect(labelItemEl.attributes('class')).toContain('is-focused'); + expect(labelItemEl.props('highlight')).toBe(true); }); }); @@ -247,19 +249,42 @@ describe('DropdownContentsLabelsView', () => { return wrapper.vm.$nextTick(() => { const noMatchEl = wrapper.find('.dropdown-content li'); - expect(noMatchEl.exists()).toBe(true); + expect(noMatchEl.isVisible()).toBe(true); expect(noMatchEl.text()).toContain('No matching results'); }); }); it('renders footer list items', () => { - const createLabelBtn = wrapper.find('.dropdown-footer').find(GlDeprecatedButton); - const manageLabelsLink = wrapper.find('.dropdown-footer').find(GlLink); - - expect(createLabelBtn.exists()).toBe(true); - expect(createLabelBtn.text()).toBe('Create label'); + const createLabelLink = wrapper + .find('.dropdown-footer') + .findAll(GlLink) + .at(0); + const manageLabelsLink = wrapper + .find('.dropdown-footer') + .findAll(GlLink) + .at(1); + + expect(createLabelLink.exists()).toBe(true); + expect(createLabelLink.text()).toBe('Create label'); expect(manageLabelsLink.exists()).toBe(true); expect(manageLabelsLink.text()).toBe('Manage labels'); }); + + it('does not render "Create label" footer link when `state.allowLabelCreate` is `false`', () => { + wrapper.vm.$store.state.allowLabelCreate = false; + + return wrapper.vm.$nextTick(() => { + const createLabelLink = wrapper + .find('.dropdown-footer') + .findAll(GlLink) + .at(0); + + expect(createLabelLink.text()).not.toBe('Create label'); + }); + }); + + it('does not render footer list items when `state.variant` is "standalone"', () => { + expect(wrapperStandalone.find('.dropdown-footer').exists()).toBe(false); + }); }); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js new file mode 100644 index 00000000000..401d208da5c --- /dev/null +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js @@ -0,0 +1,111 @@ +import { shallowMount } from '@vue/test-utils'; + +import { GlIcon, GlLink } from '@gitlab/ui'; +import LabelItem from '~/vue_shared/components/sidebar/labels_select_vue/label_item.vue'; +import { mockRegularLabel } from './mock_data'; + +const createComponent = ({ label = mockRegularLabel, highlight = true } = {}) => + shallowMount(LabelItem, { + propsData: { + label, + highlight, + }, + }); + +describe('LabelItem', () => { + let wrapper; + + beforeEach(() => { + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('computed', () => { + describe('labelBoxStyle', () => { + it('returns an object containing `backgroundColor` based on `label` prop', () => { + expect(wrapper.vm.labelBoxStyle).toEqual( + expect.objectContaining({ + backgroundColor: mockRegularLabel.color, + }), + ); + }); + }); + }); + + describe('methods', () => { + describe('handleClick', () => { + it('sets value of `isSet` data prop to opposite of its current value', () => { + wrapper.setData({ + isSet: true, + }); + + wrapper.vm.handleClick(); + expect(wrapper.vm.isSet).toBe(false); + wrapper.vm.handleClick(); + expect(wrapper.vm.isSet).toBe(true); + }); + + it('emits event `clickLabel` on component with `label` prop as param', () => { + wrapper.vm.handleClick(); + + expect(wrapper.emitted('clickLabel')).toBeTruthy(); + expect(wrapper.emitted('clickLabel')[0]).toEqual([mockRegularLabel]); + }); + }); + }); + + describe('template', () => { + it('renders gl-link component', () => { + expect(wrapper.find(GlLink).exists()).toBe(true); + }); + + it('renders gl-link component with class `is-focused` when `highlight` prop is true', () => { + wrapper.setProps({ + highlight: true, + }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find(GlLink).classes()).toContain('is-focused'); + }); + }); + + it('renders visible gl-icon component when `isSet` prop is true', () => { + wrapper.setData({ + isSet: true, + }); + + return wrapper.vm.$nextTick(() => { + const iconEl = wrapper.find(GlIcon); + + expect(iconEl.isVisible()).toBe(true); + expect(iconEl.props('name')).toBe('mobile-issue-close'); + }); + }); + + it('renders visible span element as placeholder instead of gl-icon when `isSet` prop is false', () => { + wrapper.setData({ + isSet: false, + }); + + return wrapper.vm.$nextTick(() => { + const placeholderEl = wrapper.find('[data-testid="no-icon"]'); + + expect(placeholderEl.isVisible()).toBe(true); + }); + }); + + it('renders label color element', () => { + const colorEl = wrapper.find('[data-testid="label-color-box"]'); + + expect(colorEl.exists()).toBe(true); + expect(colorEl.attributes('style')).toBe('background-color: rgb(186, 218, 85);'); + }); + + it('renders label title', () => { + expect(wrapper.text()).toContain(mockRegularLabel.title); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js index 126fd5438c4..ee4e9090e5d 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js @@ -89,6 +89,19 @@ describe('LabelsSelectRoot', () => { expect(wrapper.attributes('class')).toContain('labels-select-wrapper position-relative'); }); + it('renders component root element with CSS class `is-standalone` when `state.variant` is "standalone"', () => { + const wrapperStandalone = createComponent({ + ...mockConfig, + variant: 'standalone', + }); + + return wrapperStandalone.vm.$nextTick(() => { + expect(wrapperStandalone.classes()).toContain('is-standalone'); + + wrapperStandalone.destroy(); + }); + }); + it('renders `dropdown-value-collapsed` component when `allowLabelCreate` prop is `true`', () => { expect(wrapper.find(DropdownValueCollapsed).exists()).toBe(true); }); @@ -101,13 +114,16 @@ describe('LabelsSelectRoot', () => { const wrapperDropdownValue = createComponent(mockConfig, { default: 'None', }); + wrapperDropdownValue.vm.$store.state.showDropdownButton = false; - const valueComp = wrapperDropdownValue.find(DropdownValue); + return wrapperDropdownValue.vm.$nextTick(() => { + const valueComp = wrapperDropdownValue.find(DropdownValue); - expect(valueComp.exists()).toBe(true); - expect(valueComp.text()).toBe('None'); + expect(valueComp.exists()).toBe(true); + expect(valueComp.text()).toBe('None'); - wrapperDropdownValue.destroy(); + wrapperDropdownValue.destroy(); + }); }); it('renders `dropdown-button` component when `showDropdownButton` prop is `true`', () => { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js index a863cddbaee..e1008d13fc2 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js @@ -30,15 +30,16 @@ export const mockConfig = { allowLabelEdit: true, allowLabelCreate: true, allowScopedLabels: true, + allowMultiselect: true, labelsListTitle: 'Assign labels', labelsCreateTitle: 'Create label', + variant: 'sidebar', dropdownOnly: false, selectedLabels: [mockRegularLabel, mockScopedLabel], labelsSelectInProgress: false, labelsFetchPath: '/gitlab-org/my-project/-/labels.json', labelsManagePath: '/gitlab-org/my-project/-/labels', labelsFilterBasePath: '/gitlab-org/my-project/issues', - scopedLabelsDocumentationPath: '/help/user/project/labels.md#scoped-labels-premium', }; export const mockSuggestedColors = { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js index 6e2363ba96f..072d8fe2fe2 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js @@ -15,7 +15,7 @@ describe('LabelsSelect Actions', () => { }; beforeEach(() => { - state = Object.assign({}, defaultState()); + state = { ...defaultState() }; }); describe('setInitialState', () => { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/getters_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/getters_spec.js index bfceaa0828b..b866117efcf 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/getters_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/getters_spec.js @@ -5,19 +5,25 @@ describe('LabelsSelect Getters', () => { it('returns string "Label" when state.labels has no selected labels', () => { const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]; - expect(getters.dropdownButtonText({ labels })).toBe('Label'); + expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe( + 'Label', + ); }); it('returns label title when state.labels has only 1 label', () => { const labels = [{ id: 1, title: 'Foobar', set: true }]; - expect(getters.dropdownButtonText({ labels })).toBe('Foobar'); + expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe( + 'Foobar', + ); }); it('returns first label title and remaining labels count when state.labels has more than 1 label', () => { const labels = [{ id: 1, title: 'Foo', set: true }, { id: 2, title: 'Bar', set: true }]; - expect(getters.dropdownButtonText({ labels })).toBe('Foo +1 more'); + expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe( + 'Foo +1 more', + ); }); }); @@ -28,4 +34,16 @@ describe('LabelsSelect Getters', () => { expect(getters.selectedLabelsList({ selectedLabels })).toEqual([1, 2, 3, 4]); }); }); + + describe('isDropdownVariantSidebar', () => { + it('returns `true` when `state.variant` is "sidebar"', () => { + expect(getters.isDropdownVariantSidebar({ variant: 'sidebar' })).toBe(true); + }); + }); + + describe('isDropdownVariantStandalone', () => { + it('returns `true` when `state.variant` is "standalone"', () => { + expect(getters.isDropdownVariantStandalone({ variant: 'standalone' })).toBe(true); + }); + }); }); 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 f6ca98fcc71..8081806e314 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 @@ -29,6 +29,7 @@ describe('LabelsSelect Mutations', () => { const state = { dropdownOnly: false, showDropdownButton: false, + variant: 'sidebar', }; mutations[types.TOGGLE_DROPDOWN_CONTENTS](state); @@ -155,11 +156,11 @@ describe('LabelsSelect Mutations', () => { const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]; it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => { - const updatedLabelIds = [2, 4]; + const updatedLabelIds = [2]; const state = { labels, }; - mutations[types.UPDATE_SELECTED_LABELS](state, { labels }); + mutations[types.UPDATE_SELECTED_LABELS](state, { labels: [{ id: 2 }] }); state.labels.forEach(label => { if (updatedLabelIds.includes(label.id)) { |