diff options
Diffstat (limited to 'spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js')
-rw-r--r-- | spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js | 93 |
1 files changed, 84 insertions, 9 deletions
diff --git a/spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js index bbe460a55ba..5e1c46826cc 100644 --- a/spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js +++ b/spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js @@ -1,11 +1,18 @@ import Vue from 'vue'; -import { GlForm, GlFormInput, GlTokenSelector } from '@gitlab/ui'; +import { GlForm, GlFormInput, GlFormCheckbox, GlTooltip, GlTokenSelector } from '@gitlab/ui'; import VueApollo from 'vue-apollo'; +import { sprintf, s__ } from '~/locale'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import WorkItemLinksForm from '~/work_items/components/work_item_links/work_item_links_form.vue'; -import { FORM_TYPES } from '~/work_items/constants'; +import { + FORM_TYPES, + WORK_ITEM_TYPE_ENUM_TASK, + WORK_ITEM_TYPE_VALUE_ISSUE, + I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL, + I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP, +} from '~/work_items/constants'; import projectWorkItemsQuery from '~/work_items/graphql/project_work_items.query.graphql'; import projectWorkItemTypesQuery from '~/work_items/graphql/project_work_item_types.query.graphql'; import createWorkItemMutation from '~/work_items/graphql/create_work_item.mutation.graphql'; @@ -36,6 +43,8 @@ describe('WorkItemLinksForm', () => { workItemsMvcEnabled = false, parentIteration = null, formType = FORM_TYPES.create, + parentWorkItemType = WORK_ITEM_TYPE_VALUE_ISSUE, + childrenType = WORK_ITEM_TYPE_ENUM_TASK, } = {}) => { wrapper = shallowMountExtended(WorkItemLinksForm, { apolloProvider: createMockApollo([ @@ -48,6 +57,8 @@ describe('WorkItemLinksForm', () => { issuableGid: 'gid://gitlab/WorkItem/1', parentConfidential, parentIteration, + parentWorkItemType, + childrenType, formType, }, provide: { @@ -65,6 +76,7 @@ describe('WorkItemLinksForm', () => { const findForm = () => wrapper.findComponent(GlForm); const findTokenSelector = () => wrapper.findComponent(GlTokenSelector); const findInput = () => wrapper.findComponent(GlFormInput); + const findConfidentialCheckbox = () => wrapper.findComponent(GlFormCheckbox); const findAddChildButton = () => wrapper.findByTestId('add-child-button'); afterEach(() => { @@ -90,6 +102,7 @@ describe('WorkItemLinksForm', () => { preventDefault: jest.fn(), }); await waitForPromises(); + expect(wrapper.vm.childWorkItemType).toEqual('gid://gitlab/WorkItems::Type/3'); expect(createMutationResolver).toHaveBeenCalledWith({ input: { title: 'Create task test', @@ -112,6 +125,7 @@ describe('WorkItemLinksForm', () => { preventDefault: jest.fn(), }); await waitForPromises(); + expect(wrapper.vm.childWorkItemType).toEqual('gid://gitlab/WorkItems::Type/3'); expect(createMutationResolver).toHaveBeenCalledWith({ input: { title: 'Create confidential task', @@ -124,9 +138,50 @@ describe('WorkItemLinksForm', () => { }, }); }); + + describe('confidentiality checkbox', () => { + it('renders confidentiality checkbox', () => { + const confidentialCheckbox = findConfidentialCheckbox(); + + expect(confidentialCheckbox.exists()).toBe(true); + expect(wrapper.findComponent(GlTooltip).exists()).toBe(false); + expect(confidentialCheckbox.text()).toBe( + sprintf(I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL, { + workItemType: WORK_ITEM_TYPE_ENUM_TASK.toLocaleLowerCase(), + }), + ); + }); + + it('renders confidentiality tooltip with checkbox checked and disabled when parent is confidential', () => { + createComponent({ parentConfidential: true }); + + const confidentialCheckbox = findConfidentialCheckbox(); + const confidentialTooltip = wrapper.findComponent(GlTooltip); + + expect(confidentialCheckbox.attributes('disabled')).toBe('true'); + expect(confidentialCheckbox.attributes('checked')).toBe('true'); + expect(confidentialTooltip.exists()).toBe(true); + expect(confidentialTooltip.text()).toBe( + sprintf(I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP, { + workItemType: WORK_ITEM_TYPE_ENUM_TASK.toLocaleLowerCase(), + parentWorkItemType: WORK_ITEM_TYPE_VALUE_ISSUE.toLocaleLowerCase(), + }), + ); + }); + }); }); describe('adding an existing work item', () => { + const selectAvailableWorkItemTokens = async () => { + findTokenSelector().vm.$emit( + 'input', + availableWorkItemsResponse.data.workspace.workItems.nodes, + ); + findTokenSelector().vm.$emit('blur', new FocusEvent({ relatedTarget: null })); + + await waitForPromises(); + }; + beforeEach(async () => { await createComponent({ formType: FORM_TYPES.add }); }); @@ -136,6 +191,7 @@ describe('WorkItemLinksForm', () => { expect(findTokenSelector().exists()).toBe(true); expect(findAddChildButton().text()).toBe('Add task'); expect(findInput().exists()).toBe(false); + expect(findConfidentialCheckbox().exists()).toBe(false); }); it('searches for available work items as prop when typing in input', async () => { @@ -147,13 +203,7 @@ describe('WorkItemLinksForm', () => { }); it('selects and adds children', async () => { - findTokenSelector().vm.$emit( - 'input', - availableWorkItemsResponse.data.workspace.workItems.nodes, - ); - findTokenSelector().vm.$emit('blur', new FocusEvent({ relatedTarget: null })); - - await waitForPromises(); + await selectAvailableWorkItemTokens(); expect(findAddChildButton().text()).toBe('Add tasks'); findForm().vm.$emit('submit', { @@ -162,6 +212,31 @@ describe('WorkItemLinksForm', () => { await waitForPromises(); expect(updateMutationResolver).toHaveBeenCalled(); }); + + it('shows validation error when non-confidential child items are being added to confidential parent', async () => { + await createComponent({ formType: FORM_TYPES.add, parentConfidential: true }); + + await selectAvailableWorkItemTokens(); + + const validationEl = wrapper.findByTestId('work-items-invalid'); + expect(validationEl.exists()).toBe(true); + expect(validationEl.text().trim()).toBe( + sprintf( + s__( + 'WorkItem|%{invalidWorkItemsList} cannot be added: Cannot assign a non-confidential %{childWorkItemType} to a confidential parent %{parentWorkItemType}. Make the selected %{childWorkItemType} confidential and try again.', + ), + { + // Only non-confidential work items are shown in the error message + invalidWorkItemsList: availableWorkItemsResponse.data.workspace.workItems.nodes + .filter((wi) => !wi.confidential) + .map((wi) => wi.title) + .join(', '), + childWorkItemType: 'Task', + parentWorkItemType: 'Issue', + }, + ), + ); + }); }); describe('associate iteration with task', () => { |