diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-21 12:09:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-21 12:09:48 +0300 |
commit | a7d30d92f88b05dbd2a666ebed522bcbcd0058f1 (patch) | |
tree | f44759ab815d9a3567eae3483856eb4e880a26f8 /spec/frontend | |
parent | b86ad5f488abdef5b568d000dd44cf174abbf4fc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
9 files changed, 226 insertions, 75 deletions
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js index 60474767f2d..fb9d823107e 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js @@ -105,6 +105,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => { describe('when labels are updated over existing labels', () => { const testLabelsPayload = [ { id: 5, set: true }, + { id: 6, set: false }, { id: 7, set: true }, ]; const expectedLabels = [{ id: 5 }, { id: 7 }]; diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 0b90912a584..e245325b956 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -27,6 +27,7 @@ import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql' import actions from '~/boards/stores/actions'; import * as types from '~/boards/stores/mutation_types'; import mutations from '~/boards/stores/mutations'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { mockLists, @@ -1572,12 +1573,13 @@ describe('setActiveIssueLabels', () => { const getters = { activeBoardItem: mockIssue }; const testLabelIds = labels.map((label) => label.id); const input = { - addLabelIds: testLabelIds, + labelIds: testLabelIds, removeLabelIds: [], projectPath: 'h/b', + labels, }; - it('should assign labels on success, and sets loading state for labels', (done) => { + it('should assign labels on success', (done) => { jest .spyOn(gqlClient, 'mutate') .mockResolvedValue({ data: { updateIssue: { issue: { labels: { nodes: labels } } } } }); @@ -1594,14 +1596,6 @@ describe('setActiveIssueLabels', () => { { ...state, ...getters }, [ { - type: types.SET_LABELS_LOADING, - payload: true, - }, - { - type: types.SET_LABELS_LOADING, - payload: false, - }, - { type: types.UPDATE_BOARD_ITEM_BY_ID, payload, }, @@ -1618,6 +1612,64 @@ describe('setActiveIssueLabels', () => { await expect(actions.setActiveIssueLabels({ getters }, input)).rejects.toThrow(Error); }); + + describe('labels_widget FF on', () => { + beforeEach(() => { + window.gon = { + features: { labelsWidget: true }, + }; + + getters.activeBoardItem = { ...mockIssue, labels }; + }); + + afterEach(() => { + window.gon = { + features: {}, + }; + }); + + it('should assign labels', () => { + const payload = { + itemId: getters.activeBoardItem.id, + prop: 'labels', + value: labels, + }; + + testAction( + actions.setActiveIssueLabels, + input, + { ...state, ...getters }, + [ + { + type: types.UPDATE_BOARD_ITEM_BY_ID, + payload, + }, + ], + [], + ); + }); + + it('should remove label', () => { + const payload = { + itemId: getters.activeBoardItem.id, + prop: 'labels', + value: [labels[1]], + }; + + testAction( + actions.setActiveIssueLabels, + { ...input, removeLabelIds: [getIdFromGraphQLId(labels[0].id)] }, + { ...state, ...getters }, + [ + { + type: types.UPDATE_BOARD_ITEM_BY_ID, + payload, + }, + ], + [], + ); + }); + }); }); describe('setActiveItemSubscribed', () => { 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..03d015b5624 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 @@ -51,6 +51,7 @@ describe('DropdownContentsCreateView', () => { const createComponent = ({ mutationHandler = createLabelSuccessHandler, issuableType = IssuableType.Issue, + labelType = 'ProjectLabel', } = {}) => { const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]); mockApollo.clients.defaultClient.cache.writeQuery({ @@ -68,6 +69,8 @@ describe('DropdownContentsCreateView', () => { propsData: { issuableType, fullPath: '', + attrWorkspacePath: '', + labelType, }, }); }; @@ -174,7 +177,7 @@ describe('DropdownContentsCreateView', () => { }); it('calls a mutation with `groupPath` variable on the epic', () => { - createComponent({ issuableType: IssuableType.Epic }); + createComponent({ issuableType: IssuableType.Epic, labelType: 'GroupLabel' }); 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..5407e391d7a 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 @@ -43,6 +43,7 @@ describe('DropdownContentsLabelsView', () => { initialState = mockConfig, queryHandler = successfulQueryHandler, injected = {}, + searchKey = '', } = {}) => { const mockApollo = createMockApollo([[projectLabelsQuery, queryHandler]]); @@ -57,6 +58,7 @@ describe('DropdownContentsLabelsView', () => { ...initialState, localSelectedLabels, issuableType: IssuableType.Issue, + searchKey, }, 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..3b5ef4a8c90 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', @@ -39,6 +41,8 @@ describe('DropdownContent', () => { variant: 'sidebar', issuableType: 'issue', fullPath: 'test', + labelType: 'ProjectLabel', + 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..b21d4194d8e 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,7 @@ describe('LabelsSelectRoot', () => { propsData: { ...config, issuableType: IssuableType.Issue, + labelType: 'ProjectLabel', }, stubs: { SidebarEditableItem, @@ -121,11 +122,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..92f3549b398 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 = { |