diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/sidebar/labels_select_widget')
7 files changed, 179 insertions, 74 deletions
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js index 8931584e12c..bf873f9162b 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js @@ -5,8 +5,7 @@ import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; -import { IssuableType } from '~/issue_show/constants'; -import { labelsQueries } from '~/sidebar/constants'; +import { workspaceLabelsQueries } from '~/sidebar/constants'; import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue'; import createLabelMutation from '~/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql'; import { @@ -50,11 +49,12 @@ describe('DropdownContentsCreateView', () => { const createComponent = ({ mutationHandler = createLabelSuccessHandler, - issuableType = IssuableType.Issue, + labelCreateType = 'project', + workspaceType = 'project', } = {}) => { const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]); mockApollo.clients.defaultClient.cache.writeQuery({ - query: labelsQueries[issuableType].workspaceQuery, + query: workspaceLabelsQueries[workspaceType].query, data: workspaceLabelsQueryResponse.data, variables: { fullPath: '', @@ -66,8 +66,10 @@ describe('DropdownContentsCreateView', () => { localVue, apolloProvider: mockApollo, propsData: { - issuableType, fullPath: '', + attrWorkspacePath: '', + labelCreateType, + workspaceType, }, }); }; @@ -128,9 +130,11 @@ describe('DropdownContentsCreateView', () => { it('emits a `hideCreateView` event on Cancel button click', () => { createComponent(); - findCancelButton().vm.$emit('click'); + const event = { stopPropagation: jest.fn() }; + findCancelButton().vm.$emit('click', event); expect(wrapper.emitted('hideCreateView')).toHaveLength(1); + expect(event.stopPropagation).toHaveBeenCalled(); }); describe('when label title and selected color are set', () => { @@ -174,7 +178,7 @@ describe('DropdownContentsCreateView', () => { }); it('calls a mutation with `groupPath` variable on the epic', () => { - createComponent({ issuableType: IssuableType.Epic }); + createComponent({ labelCreateType: 'group', workspaceType: 'group' }); fillLabelAttributes(); findCreateButton().vm.$emit('click'); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js index fac3331a2b8..2980409fdce 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js @@ -10,7 +10,6 @@ import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; -import { IssuableType } from '~/issue_show/constants'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants'; import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue'; @@ -43,6 +42,7 @@ describe('DropdownContentsLabelsView', () => { initialState = mockConfig, queryHandler = successfulQueryHandler, injected = {}, + searchKey = '', } = {}) => { const mockApollo = createMockApollo([[projectLabelsQuery, queryHandler]]); @@ -56,7 +56,9 @@ describe('DropdownContentsLabelsView', () => { propsData: { ...initialState, localSelectedLabels, - issuableType: IssuableType.Issue, + searchKey, + labelCreateType: 'project', + workspaceType: 'project', }, stubs: { GlSearchBoxByType, @@ -68,7 +70,6 @@ describe('DropdownContentsLabelsView', () => { wrapper.destroy(); }); - const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType); const findLabels = () => wrapper.findAllComponents(LabelItem); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findObserver = () => wrapper.findComponent(GlIntersectionObserver); @@ -81,12 +82,6 @@ describe('DropdownContentsLabelsView', () => { } describe('when loading labels', () => { - it('renders disabled search input field', async () => { - createComponent(); - await makeObserverAppear(); - expect(findSearchInput().props('disabled')).toBe(true); - }); - it('renders loading icon', async () => { createComponent(); await makeObserverAppear(); @@ -107,10 +102,6 @@ describe('DropdownContentsLabelsView', () => { await waitForPromises(); }); - it('renders enabled search input field', async () => { - expect(findSearchInput().props('disabled')).toBe(false); - }); - it('does not render loading icon', async () => { expect(findLoadingIcon().exists()).toBe(false); }); @@ -132,9 +123,9 @@ describe('DropdownContentsLabelsView', () => { }, }, }), + searchKey: '123', }); await makeObserverAppear(); - findSearchInput().vm.$emit('input', '123'); await waitForPromises(); await nextTick(); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js index 36704ac5ef3..8bcef347c96 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js @@ -4,6 +4,8 @@ import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_w import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue'; import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue'; import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue'; +import DropdownHeader from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue'; +import DropdownFooter from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_footer.vue'; import { mockLabels } from './mock_data'; @@ -26,7 +28,7 @@ const GlDropdownStub = { describe('DropdownContent', () => { let wrapper; - const createComponent = ({ props = {}, injected = {}, data = {} } = {}) => { + const createComponent = ({ props = {}, data = {} } = {}) => { wrapper = shallowMount(DropdownContents, { propsData: { labelsCreateTitle: 'test', @@ -37,8 +39,10 @@ describe('DropdownContent', () => { footerManageLabelTitle: 'manage', dropdownButtonText: 'Labels', variant: 'sidebar', - issuableType: 'issue', fullPath: 'test', + workspaceType: 'project', + labelCreateType: 'project', + attrWorkspacePath: 'path', ...props, }, data() { @@ -46,11 +50,6 @@ describe('DropdownContent', () => { ...data, }; }, - provide: { - allowLabelCreate: true, - labelsManagePath: 'foo/bar', - ...injected, - }, stubs: { GlDropdown: GlDropdownStub, }, @@ -63,13 +62,10 @@ describe('DropdownContent', () => { const findCreateView = () => wrapper.findComponent(DropdownContentsCreateView); const findLabelsView = () => wrapper.findComponent(DropdownContentsLabelsView); + const findDropdownHeader = () => wrapper.findComponent(DropdownHeader); + const findDropdownFooter = () => wrapper.findComponent(DropdownFooter); const findDropdown = () => wrapper.findComponent(GlDropdownStub); - const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]'); - const findDropdownHeader = () => wrapper.find('[data-testid="dropdown-header"]'); - const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]'); - const findGoBackButton = () => wrapper.find('[data-testid="go-back-button"]'); - it('calls dropdown `show` method on `isVisible` prop change', async () => { createComponent(); await wrapper.setProps({ @@ -136,6 +132,16 @@ describe('DropdownContent', () => { expect(findDropdownHeader().exists()).toBe(true); }); + it('sets searchKey for labels view on input event from header', async () => { + createComponent(); + + expect(wrapper.vm.searchKey).toEqual(''); + findDropdownHeader().vm.$emit('input', '123'); + await nextTick(); + + expect(findLabelsView().props('searchKey')).toEqual('123'); + }); + describe('Create view', () => { beforeEach(() => { createComponent({ data: { showDropdownContentsCreateView: true } }); @@ -149,16 +155,8 @@ describe('DropdownContent', () => { expect(findDropdownFooter().exists()).toBe(false); }); - it('does not render create label button', () => { - expect(findCreateLabelButton().exists()).toBe(false); - }); - - it('renders go back button', () => { - expect(findGoBackButton().exists()).toBe(true); - }); - - it('changes the view to Labels view on back button click', async () => { - findGoBackButton().vm.$emit('click', new MouseEvent('click')); + it('changes the view to Labels view on `toggleDropdownContentsCreateView` event', async () => { + findDropdownHeader().vm.$emit('toggleDropdownContentsCreateView'); await nextTick(); expect(findCreateView().exists()).toBe(false); @@ -198,32 +196,5 @@ describe('DropdownContent', () => { expect(findDropdownFooter().exists()).toBe(true); }); - - it('does not render go back button', () => { - expect(findGoBackButton().exists()).toBe(false); - }); - - it('does not render create label button if `allowLabelCreate` is false', () => { - createComponent({ injected: { allowLabelCreate: false } }); - - expect(findCreateLabelButton().exists()).toBe(false); - }); - - describe('when `allowLabelCreate` is true', () => { - beforeEach(() => { - createComponent(); - }); - - it('renders create label button', () => { - expect(findCreateLabelButton().exists()).toBe(true); - }); - - it('changes the view to Create on create label button click', async () => { - findCreateLabelButton().trigger('click'); - - await nextTick(); - expect(findLabelsView().exists()).toBe(false); - }); - }); }); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_footer_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_footer_spec.js new file mode 100644 index 00000000000..0508a059195 --- /dev/null +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_footer_spec.js @@ -0,0 +1,57 @@ +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import DropdownFooter from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_footer.vue'; + +describe('DropdownFooter', () => { + let wrapper; + + const createComponent = ({ props = {}, injected = {} } = {}) => { + wrapper = shallowMount(DropdownFooter, { + propsData: { + footerCreateLabelTitle: 'create', + footerManageLabelTitle: 'manage', + ...props, + }, + provide: { + allowLabelCreate: true, + labelsManagePath: 'foo/bar', + ...injected, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]'); + + describe('Labels view', () => { + beforeEach(() => { + createComponent(); + }); + + it('does not render create label button if `allowLabelCreate` is false', () => { + createComponent({ injected: { allowLabelCreate: false } }); + + expect(findCreateLabelButton().exists()).toBe(false); + }); + + describe('when `allowLabelCreate` is true', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders create label button', () => { + expect(findCreateLabelButton().exists()).toBe(true); + }); + + it('emits `toggleDropdownContentsCreateView` event on create label button click', async () => { + findCreateLabelButton().trigger('click'); + + await nextTick(); + expect(wrapper.emitted('toggleDropdownContentsCreateView')).toEqual([[]]); + }); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_header_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_header_spec.js new file mode 100644 index 00000000000..592559ef305 --- /dev/null +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_header_spec.js @@ -0,0 +1,75 @@ +import { GlSearchBoxByType } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import DropdownHeader from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue'; + +describe('DropdownHeader', () => { + let wrapper; + + const createComponent = ({ + showDropdownContentsCreateView = false, + labelsFetchInProgress = false, + } = {}) => { + wrapper = extendedWrapper( + shallowMount(DropdownHeader, { + propsData: { + showDropdownContentsCreateView, + labelsFetchInProgress, + labelsCreateTitle: 'Create label', + labelsListTitle: 'Select label', + searchKey: '', + }, + stubs: { + GlSearchBoxByType, + }, + }), + ); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType); + const findGoBackButton = () => wrapper.findByTestId('go-back-button'); + + beforeEach(() => { + createComponent(); + }); + + describe('Create view', () => { + beforeEach(() => { + createComponent({ showDropdownContentsCreateView: true }); + }); + + it('renders go back button', () => { + expect(findGoBackButton().exists()).toBe(true); + }); + + it('does not render search input field', async () => { + expect(findSearchInput().exists()).toBe(false); + }); + }); + + describe('Labels view', () => { + beforeEach(() => { + createComponent(); + }); + + it('does not render go back button', () => { + expect(findGoBackButton().exists()).toBe(false); + }); + + it.each` + labelsFetchInProgress | disabled + ${true} | ${true} + ${false} | ${false} + `( + 'when labelsFetchInProgress is $labelsFetchInProgress, renders search input with disabled prop to $disabled', + ({ labelsFetchInProgress, disabled }) => { + createComponent({ labelsFetchInProgress }); + expect(findSearchInput().props('disabled')).toBe(disabled); + }, + ); + }); +}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js index b5441d711a5..d4203528874 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js @@ -41,6 +41,8 @@ describe('LabelsSelectRoot', () => { propsData: { ...config, issuableType: IssuableType.Issue, + labelCreateType: 'project', + workspaceType: 'project', }, stubs: { SidebarEditableItem, @@ -121,11 +123,11 @@ describe('LabelsSelectRoot', () => { }); }); - it('emits `updateSelectedLabels` event on dropdown contents `setLabels` event', async () => { + it('emits `updateSelectedLabels` event on dropdown contents `setLabels` event if iid is not set', async () => { const label = { id: 'gid://gitlab/ProjectLabel/1' }; - createComponent(); + createComponent({ config: { ...mockConfig, iid: undefined } }); findDropdownContents().vm.$emit('setLabels', [label]); - expect(wrapper.emitted('updateSelectedLabels')).toEqual([[[label]]]); + expect(wrapper.emitted('updateSelectedLabels')).toEqual([[{ labels: [label] }]]); }); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js index 23a457848d9..5c5bf5f2187 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js @@ -40,12 +40,12 @@ export const mockConfig = { labelsListTitle: 'Assign labels', labelsCreateTitle: 'Create label', variant: 'sidebar', - selectedLabels: [mockRegularLabel, mockScopedLabel], labelsSelectInProgress: false, labelsFilterBasePath: '/gitlab-org/my-project/issues', labelsFilterParam: 'label_name', footerCreateLabelTitle: 'create', footerManageLabelTitle: 'manage', + attrWorkspacePath: 'test', }; export const mockSuggestedColors = { @@ -80,6 +80,7 @@ export const createLabelSuccessfulResponse = { color: '#dc143c', description: null, title: 'ewrwrwer', + textColor: '#000000', __typename: 'Label', }, errors: [], @@ -91,6 +92,7 @@ export const createLabelSuccessfulResponse = { export const workspaceLabelsQueryResponse = { data: { workspace: { + id: 'gid://gitlab/Project/126', labels: { nodes: [ { @@ -98,12 +100,14 @@ export const workspaceLabelsQueryResponse = { description: null, id: 'gid://gitlab/ProjectLabel/1', title: 'Label1', + textColor: '#000000', }, { color: '#2f7b2e', description: null, id: 'gid://gitlab/ProjectLabel/2', title: 'Label2', + textColor: '#000000', }, ], }, @@ -123,6 +127,7 @@ export const issuableLabelsQueryResponse = { description: null, id: 'gid://gitlab/ProjectLabel/1', title: 'Label1', + textColor: '#000000', }, ], }, |