Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/work_items/components/work_item_links')
-rw-r--r--spec/frontend/work_items/components/work_item_links/work_item_links_form_spec.js205
-rw-r--r--spec/frontend/work_items/components/work_item_links/work_item_links_spec.js31
2 files changed, 172 insertions, 64 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 ab3ea623e3e..071d5fb715a 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,10 +1,11 @@
import Vue from 'vue';
-import { GlForm, GlFormInput, GlFormCombobox } from '@gitlab/ui';
+import { GlForm, GlFormInput, GlTokenSelector } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
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 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';
@@ -14,6 +15,7 @@ import {
projectWorkItemTypesQueryResponse,
createWorkItemMutationResponse,
updateWorkItemMutationResponse,
+ mockIterationWidgetResponse,
} from '../../mock_data';
Vue.use(VueApollo);
@@ -23,22 +25,35 @@ describe('WorkItemLinksForm', () => {
const updateMutationResolver = jest.fn().mockResolvedValue(updateWorkItemMutationResponse);
const createMutationResolver = jest.fn().mockResolvedValue(createWorkItemMutationResponse);
+ const availableWorkItemsResolver = jest.fn().mockResolvedValue(availableWorkItemsResponse);
+
+ const mockParentIteration = mockIterationWidgetResponse;
const createComponent = async ({
- listResponse = availableWorkItemsResponse,
typesResponse = projectWorkItemTypesQueryResponse,
parentConfidential = false,
hasIterationsFeature = false,
+ workItemsMvc2Enabled = false,
+ parentIteration = null,
+ formType = FORM_TYPES.create,
} = {}) => {
wrapper = shallowMountExtended(WorkItemLinksForm, {
apolloProvider: createMockApollo([
- [projectWorkItemsQuery, jest.fn().mockResolvedValue(listResponse)],
+ [projectWorkItemsQuery, availableWorkItemsResolver],
[projectWorkItemTypesQuery, jest.fn().mockResolvedValue(typesResponse)],
[updateWorkItemMutation, updateMutationResolver],
[createWorkItemMutation, createMutationResolver],
]),
- propsData: { issuableGid: 'gid://gitlab/WorkItem/1', parentConfidential },
+ propsData: {
+ issuableGid: 'gid://gitlab/WorkItem/1',
+ parentConfidential,
+ parentIteration,
+ formType,
+ },
provide: {
+ glFeatures: {
+ workItemsMvc2: workItemsMvc2Enabled,
+ },
projectPath: 'project/path',
hasIterationsFeature,
},
@@ -48,89 +63,155 @@ describe('WorkItemLinksForm', () => {
};
const findForm = () => wrapper.findComponent(GlForm);
- const findCombobox = () => wrapper.findComponent(GlFormCombobox);
+ const findTokenSelector = () => wrapper.findComponent(GlTokenSelector);
const findInput = () => wrapper.findComponent(GlFormInput);
const findAddChildButton = () => wrapper.findByTestId('add-child-button');
- beforeEach(async () => {
- await createComponent();
- });
-
afterEach(() => {
wrapper.destroy();
});
- it('renders form', () => {
- expect(findForm().exists()).toBe(true);
- });
-
- it('creates child task in non confidential parent', async () => {
- findInput().vm.$emit('input', 'Create task test');
+ describe('creating a new work item', () => {
+ beforeEach(async () => {
+ await createComponent();
+ });
- findForm().vm.$emit('submit', {
- preventDefault: jest.fn(),
+ it('renders create form', () => {
+ expect(findForm().exists()).toBe(true);
+ expect(findInput().exists()).toBe(true);
+ expect(findAddChildButton().text()).toBe('Create task');
+ expect(findTokenSelector().exists()).toBe(false);
});
- await waitForPromises();
- expect(createMutationResolver).toHaveBeenCalledWith({
- input: {
- title: 'Create task test',
- projectPath: 'project/path',
- workItemTypeId: 'gid://gitlab/WorkItems::Type/3',
- hierarchyWidget: {
- parentId: 'gid://gitlab/WorkItem/1',
+
+ it('creates child task in non confidential parent', async () => {
+ findInput().vm.$emit('input', 'Create task test');
+
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(createMutationResolver).toHaveBeenCalledWith({
+ input: {
+ title: 'Create task test',
+ projectPath: 'project/path',
+ workItemTypeId: 'gid://gitlab/WorkItems::Type/3',
+ hierarchyWidget: {
+ parentId: 'gid://gitlab/WorkItem/1',
+ },
+ confidential: false,
},
- confidential: false,
- },
+ });
});
- });
- it('creates child task in confidential parent', async () => {
- await createComponent({ parentConfidential: true });
+ it('creates child task in confidential parent', async () => {
+ await createComponent({ parentConfidential: true });
- findInput().vm.$emit('input', 'Create confidential task');
+ findInput().vm.$emit('input', 'Create confidential task');
- findForm().vm.$emit('submit', {
- preventDefault: jest.fn(),
- });
- await waitForPromises();
- expect(createMutationResolver).toHaveBeenCalledWith({
- input: {
- title: 'Create confidential task',
- projectPath: 'project/path',
- workItemTypeId: 'gid://gitlab/WorkItems::Type/3',
- hierarchyWidget: {
- parentId: 'gid://gitlab/WorkItem/1',
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(createMutationResolver).toHaveBeenCalledWith({
+ input: {
+ title: 'Create confidential task',
+ projectPath: 'project/path',
+ workItemTypeId: 'gid://gitlab/WorkItems::Type/3',
+ hierarchyWidget: {
+ parentId: 'gid://gitlab/WorkItem/1',
+ },
+ confidential: true,
},
- confidential: true,
- },
+ });
});
});
- // Follow up issue to turn this functionality back on https://gitlab.com/gitlab-org/gitlab/-/issues/368757
- // eslint-disable-next-line jest/no-disabled-tests
- it.skip('selects and add child', async () => {
- findCombobox().vm.$emit('input', availableWorkItemsResponse.data.workspace.workItems.edges[0]);
+ describe('adding an existing work item', () => {
+ beforeEach(async () => {
+ await createComponent({ formType: FORM_TYPES.add });
+ });
- findAddChildButton().vm.$emit('click');
- await waitForPromises();
- expect(updateMutationResolver).toHaveBeenCalled();
- });
+ it('renders add form', () => {
+ expect(findForm().exists()).toBe(true);
+ expect(findTokenSelector().exists()).toBe(true);
+ expect(findAddChildButton().text()).toBe('Add task');
+ expect(findInput().exists()).toBe(false);
+ });
- // eslint-disable-next-line jest/no-disabled-tests
- describe.skip('when typing in combobox', () => {
- beforeEach(async () => {
- findCombobox().vm.$emit('input', 'Task');
+ it('searches for available work items as prop when typing in input', async () => {
+ findTokenSelector().vm.$emit('focus');
+ findTokenSelector().vm.$emit('text-input', 'Task');
await waitForPromises();
- await jest.runOnlyPendingTimers();
+
+ expect(availableWorkItemsResolver).toHaveBeenCalled();
});
- it('passes available work items as prop', () => {
- expect(findCombobox().exists()).toBe(true);
- expect(findCombobox().props('tokenList').length).toBe(2);
+ 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();
+
+ expect(findAddChildButton().text()).toBe('Add tasks');
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(updateMutationResolver).toHaveBeenCalled();
});
+ });
+
+ describe('associate iteration with task', () => {
+ it('does not update iteration when mvc2 feature flag is not enabled', async () => {
+ await createComponent({
+ hasIterationsFeature: true,
+ parentIteration: mockParentIteration,
+ });
- it('passes action to create task', () => {
- expect(findCombobox().props('actionList').length).toBe(1);
+ findInput().vm.$emit('input', 'Create task test');
+
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(updateMutationResolver).not.toHaveBeenCalled();
+ });
+ it('updates when parent has an iteration associated', async () => {
+ await createComponent({
+ workItemsMvc2Enabled: true,
+ hasIterationsFeature: true,
+ parentIteration: mockParentIteration,
+ });
+ findInput().vm.$emit('input', 'Create task test');
+
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(updateMutationResolver).toHaveBeenCalledWith({
+ input: {
+ id: 'gid://gitlab/WorkItem/1',
+ iterationWidget: {
+ iterationId: mockParentIteration.id,
+ },
+ },
+ });
+ });
+ it('does not update when parent has no iteration associated', async () => {
+ await createComponent({
+ workItemsMvc2Enabled: true,
+ hasIterationsFeature: true,
+ });
+ findInput().vm.$emit('input', 'Create task test');
+
+ findForm().vm.$emit('submit', {
+ preventDefault: jest.fn(),
+ });
+ await waitForPromises();
+ expect(updateMutationResolver).not.toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js
index 6961996f912..66ce2c1becf 100644
--- a/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js
+++ b/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js
@@ -8,6 +8,7 @@ import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import issueDetailsQuery from 'ee_else_ce/work_items/graphql/get_issue_details.query.graphql';
import WorkItemLinks from '~/work_items/components/work_item_links/work_item_links.vue';
import WorkItemLinkChild from '~/work_items/components/work_item_links/work_item_link_child.vue';
+import { FORM_TYPES } from '~/work_items/constants';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import changeWorkItemParentMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import getWorkItemLinksQuery from '~/work_items/graphql/work_item_links.query.graphql';
@@ -41,6 +42,13 @@ const issueDetailsResponse = (confidential = false) => ({
},
__typename: 'Iteration',
},
+ milestone: {
+ dueDate: null,
+ expired: false,
+ id: 'gid://gitlab/Milestone/28',
+ title: 'v2.0',
+ __typename: 'Milestone',
+ },
__typename: 'Issue',
},
__typename: 'Project',
@@ -107,7 +115,9 @@ describe('WorkItemLinks', () => {
const findToggleButton = () => wrapper.findByTestId('toggle-links');
const findLinksBody = () => wrapper.findByTestId('links-body');
const findEmptyState = () => wrapper.findByTestId('links-empty');
+ const findToggleFormDropdown = () => wrapper.findByTestId('toggle-form');
const findToggleAddFormButton = () => wrapper.findByTestId('toggle-add-form');
+ const findToggleCreateFormButton = () => wrapper.findByTestId('toggle-create-form');
const findWorkItemLinkChildItems = () => wrapper.findAllComponents(WorkItemLinkChild);
const findFirstWorkItemLinkChild = () => findWorkItemLinkChildItems().at(0);
const findAddLinksForm = () => wrapper.findByTestId('add-links-form');
@@ -136,11 +146,27 @@ describe('WorkItemLinks', () => {
});
describe('add link form', () => {
- it('displays form on click add button and hides form on cancel', async () => {
+ it('displays add work item form on click add dropdown then add existing button and hides form on cancel', async () => {
+ findToggleFormDropdown().vm.$emit('click');
findToggleAddFormButton().vm.$emit('click');
await nextTick();
expect(findAddLinksForm().exists()).toBe(true);
+ expect(findAddLinksForm().props('formType')).toBe(FORM_TYPES.add);
+
+ findAddLinksForm().vm.$emit('cancel');
+ await nextTick();
+
+ expect(findAddLinksForm().exists()).toBe(false);
+ });
+
+ it('displays create work item form on click add dropdown then create button and hides form on cancel', async () => {
+ findToggleFormDropdown().vm.$emit('click');
+ findToggleCreateFormButton().vm.$emit('click');
+ await nextTick();
+
+ expect(findAddLinksForm().exists()).toBe(true);
+ expect(findAddLinksForm().props('formType')).toBe(FORM_TYPES.create);
findAddLinksForm().vm.$emit('cancel');
await nextTick();
@@ -193,7 +219,7 @@ describe('WorkItemLinks', () => {
});
it('does not display button to toggle Add form', () => {
- expect(findToggleAddFormButton().exists()).toBe(false);
+ expect(findToggleFormDropdown().exists()).toBe(false);
});
it('does not display link menu on children', () => {
@@ -283,6 +309,7 @@ describe('WorkItemLinks', () => {
await createComponent({
issueDetailsQueryHandler: jest.fn().mockResolvedValue(issueDetailsResponse(true)),
});
+ findToggleFormDropdown().vm.$emit('click');
findToggleAddFormButton().vm.$emit('click');
await nextTick();