diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-14 21:08:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-14 21:08:53 +0300 |
commit | 5b62f8e3ee531f63ce3c49cae03e2a618ba51615 (patch) | |
tree | 2d2553232fe0663957ee4d1054211cc71cb07679 /spec/frontend/work_items | |
parent | cdb41961fd2bc233d36c5b30f89d087c2efa9818 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/work_items')
-rw-r--r-- | spec/frontend/work_items/components/work_item_actions_spec.js | 116 | ||||
-rw-r--r-- | spec/frontend/work_items/components/work_item_detail_spec.js | 1 | ||||
-rw-r--r-- | spec/frontend/work_items/mock_data.js | 9 |
3 files changed, 120 insertions, 6 deletions
diff --git a/spec/frontend/work_items/components/work_item_actions_spec.js b/spec/frontend/work_items/components/work_item_actions_spec.js index a0db8172bf6..5ae0635850d 100644 --- a/spec/frontend/work_items/components/work_item_actions_spec.js +++ b/spec/frontend/work_items/components/work_item_actions_spec.js @@ -1,17 +1,35 @@ -import { GlDropdownDivider, GlModal } from '@gitlab/ui'; +import { GlDropdownDivider, GlModal, GlToggle } from '@gitlab/ui'; +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { isLoggedIn } from '~/lib/utils/common_utils'; +import toast from '~/vue_shared/plugins/global_toast'; import WorkItemActions from '~/work_items/components/work_item_actions.vue'; - -const TEST_ID_CONFIDENTIALITY_TOGGLE_ACTION = 'confidentiality-toggle-action'; -const TEST_ID_DELETE_ACTION = 'delete-action'; +import { + TEST_ID_CONFIDENTIALITY_TOGGLE_ACTION, + TEST_ID_NOTIFICATIONS_TOGGLE_ACTION, + TEST_ID_NOTIFICATIONS_TOGGLE_FORM, + TEST_ID_DELETE_ACTION, +} from '~/work_items/constants'; +import updateWorkItemNotificationsMutation from '~/work_items/graphql/update_work_item_notifications.mutation.graphql'; +import { workItemResponseFactory } from '../mock_data'; + +jest.mock('~/lib/utils/common_utils'); +jest.mock('~/vue_shared/plugins/global_toast'); describe('WorkItemActions component', () => { + Vue.use(VueApollo); + let wrapper; let glModalDirective; const findModal = () => wrapper.findComponent(GlModal); const findConfidentialityToggleButton = () => wrapper.findByTestId(TEST_ID_CONFIDENTIALITY_TOGGLE_ACTION); + const findNotificationsToggleButton = () => + wrapper.findByTestId(TEST_ID_NOTIFICATIONS_TOGGLE_ACTION); const findDeleteButton = () => wrapper.findByTestId(TEST_ID_DELETE_ACTION); const findDropdownItems = () => wrapper.findAll('[data-testid="work-item-actions-dropdown"] > *'); const findDropdownItemsActual = () => @@ -25,20 +43,27 @@ describe('WorkItemActions component', () => { text: x.text(), }; }); + const findNotificationsToggle = () => wrapper.findComponent(GlToggle); const createComponent = ({ canUpdate = true, canDelete = true, isConfidential = false, + subscribed = false, isParentConfidential = false, + notificationsMock = [updateWorkItemNotificationsMutation, jest.fn()], } = {}) => { + const handlers = [notificationsMock]; glModalDirective = jest.fn(); wrapper = shallowMountExtended(WorkItemActions, { + apolloProvider: createMockApollo(handlers), + isLoggedIn: isLoggedIn(), propsData: { - workItemId: '123', + workItemId: 'gid://gitlab/WorkItem/1', canUpdate, canDelete, isConfidential, + subscribed, isParentConfidential, workItemType: 'Task', }, @@ -52,6 +77,10 @@ describe('WorkItemActions component', () => { }); }; + beforeEach(() => { + isLoggedIn.mockReturnValue(true); + }); + it('renders modal', () => { createComponent(); @@ -64,6 +93,13 @@ describe('WorkItemActions component', () => { expect(findDropdownItemsActual()).toEqual([ { + testId: TEST_ID_NOTIFICATIONS_TOGGLE_FORM, + text: '', + }, + { + divider: true, + }, + { testId: TEST_ID_CONFIDENTIALITY_TOGGLE_ACTION, text: 'Turn on confidentiality', }, @@ -133,7 +169,75 @@ describe('WorkItemActions component', () => { }); expect(findDeleteButton().exists()).toBe(false); - expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false); + }); + }); + + describe('notifications action', () => { + const workItemQueryResponse = workItemResponseFactory({ canUpdate: true, canDelete: true }); + const inputVariables = { + id: workItemQueryResponse.data.workItem.id, + notificationsWidget: { + subscribed: false, + }, + }; + + const notificationExpectedResponse = workItemResponseFactory({ + subscribed: false, + }); + + const toggleNotificationsHandler = jest.fn().mockResolvedValue({ + data: { + workItemUpdate: { + workItem: notificationExpectedResponse.data.workItem, + errors: [], + }, + }, + }); + + const errorMessage = 'Failed to subscribe'; + const toggleNotificationsFailureHandler = jest.fn().mockRejectedValue(new Error(errorMessage)); + + const notificationsMock = [updateWorkItemNotificationsMutation, toggleNotificationsHandler]; + + const notificationsFailureMock = [ + updateWorkItemNotificationsMutation, + toggleNotificationsFailureHandler, + ]; + + beforeEach(() => { + createComponent(); + isLoggedIn.mockReturnValue(true); + }); + + it('renders toggle button', () => { + expect(findNotificationsToggleButton().exists()).toBe(true); + }); + + it('calls notification mutation and displays a toast when the notification widget is toggled', async () => { + createComponent({ notificationsMock }); + + await waitForPromises(); + + findNotificationsToggle().vm.$emit('change', false); + + await waitForPromises(); + + expect(notificationsMock[1]).toHaveBeenCalledWith({ + input: inputVariables, + }); + expect(toast).toHaveBeenCalledWith('Notifications turned off.'); + }); + + it('emits error when the update notification mutation fails', async () => { + createComponent({ notificationsMock: notificationsFailureMock }); + + await waitForPromises(); + + findNotificationsToggle().vm.$emit('change', false); + + await waitForPromises(); + + expect(wrapper.emitted('error')).toEqual([[errorMessage]]); }); }); }); diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js index 9d0a2344356..8e5b607cee7 100644 --- a/spec/frontend/work_items/components/work_item_detail_spec.js +++ b/spec/frontend/work_items/components/work_item_detail_spec.js @@ -35,6 +35,7 @@ import workItemAssigneesSubscription from '~/work_items/graphql/work_item_assign import workItemMilestoneSubscription from '~/work_items/graphql/work_item_milestone.subscription.graphql'; import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql'; import updateWorkItemTaskMutation from '~/work_items/graphql/update_work_item_task.mutation.graphql'; + import { mockParent, workItemDatesSubscriptionResponse, diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index 50d7aff3365..c3376556d6e 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -288,6 +288,8 @@ export const objectiveType = { export const workItemResponseFactory = ({ canUpdate = false, canDelete = false, + notificationsWidgetPresent = true, + subscribed = true, allowsMultipleAssignees = true, assigneesWidgetPresent = true, datesWidgetPresent = true, @@ -472,6 +474,13 @@ export const workItemResponseFactory = ({ type: 'NOTES', } : { type: 'MOCK TYPE' }, + notificationsWidgetPresent + ? { + __typename: 'WorkItemWidgetNotifications', + type: 'NOTIFICATIONS', + subscribed, + } + : { type: 'MOCK TYPE' }, ], }, }, |