summaryrefslogtreecommitdiff
path: root/spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js
diff options
context:
space:
mode:
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.js93
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', () => {