diff options
Diffstat (limited to 'spec/frontend/sidebar/components/time_tracking')
-rw-r--r-- | spec/frontend/sidebar/components/time_tracking/mock_data.js | 28 | ||||
-rw-r--r-- | spec/frontend/sidebar/components/time_tracking/report_spec.js | 86 |
2 files changed, 103 insertions, 11 deletions
diff --git a/spec/frontend/sidebar/components/time_tracking/mock_data.js b/spec/frontend/sidebar/components/time_tracking/mock_data.js index ba2781118d9..f161ae677d0 100644 --- a/spec/frontend/sidebar/components/time_tracking/mock_data.js +++ b/spec/frontend/sidebar/components/time_tracking/mock_data.js @@ -1,3 +1,5 @@ +export const timelogToRemoveId = 'gid://gitlab/Timelog/18'; + export const getIssueTimelogsQueryResponse = { data: { issuable: { @@ -9,7 +11,7 @@ export const getIssueTimelogsQueryResponse = { nodes: [ { __typename: 'Timelog', - id: 'gid://gitlab/Timelog/18', + id: timelogToRemoveId, timeSpent: 14400, user: { id: 'user-1', @@ -23,6 +25,10 @@ export const getIssueTimelogsQueryResponse = { __typename: 'Note', }, summary: 'A summary', + userPermissions: { + adminTimelog: true, + __typename: 'TimelogPermissions', + }, }, { __typename: 'Timelog', @@ -36,6 +42,10 @@ export const getIssueTimelogsQueryResponse = { spentAt: '2021-05-07T13:19:01Z', note: null, summary: 'A summary', + userPermissions: { + adminTimelog: false, + __typename: 'TimelogPermissions', + }, }, { __typename: 'Timelog', @@ -53,6 +63,10 @@ export const getIssueTimelogsQueryResponse = { __typename: 'Note', }, summary: null, + userPermissions: { + adminTimelog: false, + __typename: 'TimelogPermissions', + }, }, ], __typename: 'TimelogConnection', @@ -85,6 +99,10 @@ export const getMrTimelogsQueryResponse = { __typename: 'Note', }, summary: null, + userPermissions: { + adminTimelog: true, + __typename: 'TimelogPermissions', + }, }, { __typename: 'Timelog', @@ -98,6 +116,10 @@ export const getMrTimelogsQueryResponse = { spentAt: '2021-05-07T14:44:39Z', note: null, summary: null, + userPermissions: { + adminTimelog: true, + __typename: 'TimelogPermissions', + }, }, { __typename: 'Timelog', @@ -115,6 +137,10 @@ export const getMrTimelogsQueryResponse = { __typename: 'Note', }, summary: null, + userPermissions: { + adminTimelog: true, + __typename: 'TimelogPermissions', + }, }, ], __typename: 'TimelogConnection', diff --git a/spec/frontend/sidebar/components/time_tracking/report_spec.js b/spec/frontend/sidebar/components/time_tracking/report_spec.js index 2b17e6dd6c3..5ed8810e95e 100644 --- a/spec/frontend/sidebar/components/time_tracking/report_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/report_spec.js @@ -1,15 +1,21 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { getAllByRole, getByRole } from '@testing-library/dom'; +import { getAllByRole, getByRole, getAllByTestId } from '@testing-library/dom'; import { shallowMount, mount } from '@vue/test-utils'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; import Report from '~/sidebar/components/time_tracking/report.vue'; import getIssueTimelogsQuery from '~/vue_shared/components/sidebar/queries/get_issue_timelogs.query.graphql'; import getMrTimelogsQuery from '~/vue_shared/components/sidebar/queries/get_mr_timelogs.query.graphql'; -import { getIssueTimelogsQueryResponse, getMrTimelogsQueryResponse } from './mock_data'; +import deleteTimelogMutation from '~/sidebar/components/time_tracking/graphql/mutations/delete_timelog.mutation.graphql'; +import { + getIssueTimelogsQueryResponse, + getMrTimelogsQueryResponse, + timelogToRemoveId, +} from './mock_data'; jest.mock('~/flash'); @@ -18,6 +24,7 @@ describe('Issuable Time Tracking Report', () => { let wrapper; let fakeApollo; const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); + const findDeleteButton = () => wrapper.findByTestId('deleteButton'); const successIssueQueryHandler = jest.fn().mockResolvedValue(getIssueTimelogsQueryResponse); const successMrQueryHandler = jest.fn().mockResolvedValue(getMrTimelogsQueryResponse); @@ -31,14 +38,16 @@ describe('Issuable Time Tracking Report', () => { [getIssueTimelogsQuery, queryHandler], [getMrTimelogsQuery, queryHandler], ]); - wrapper = mountFunction(Report, { - provide: { - issuableId: 1, - issuableType, - }, - propsData: { limitToHours, issuableId: '1' }, - apolloProvider: fakeApollo, - }); + wrapper = extendedWrapper( + mountFunction(Report, { + provide: { + issuableId: 1, + issuableType, + }, + propsData: { limitToHours, issuableId: '1' }, + apolloProvider: fakeApollo, + }), + ); }; afterEach(() => { @@ -75,6 +84,7 @@ describe('Issuable Time Tracking Report', () => { expect(getAllByRole(wrapper.element, 'row', { name: /Administrator/i })).toHaveLength(2); expect(getAllByRole(wrapper.element, 'row', { name: /A note/i })).toHaveLength(1); expect(getAllByRole(wrapper.element, 'row', { name: /A summary/i })).toHaveLength(2); + expect(getAllByTestId(wrapper.element, 'deleteButton')).toHaveLength(1); }); }); @@ -95,6 +105,7 @@ describe('Issuable Time Tracking Report', () => { await waitForPromises(); expect(getAllByRole(wrapper.element, 'row', { name: /Administrator/i })).toHaveLength(3); + expect(getAllByTestId(wrapper.element, 'deleteButton')).toHaveLength(3); }); }); @@ -123,4 +134,59 @@ describe('Issuable Time Tracking Report', () => { }); }); }); + + describe('when clicking on the delete timelog button', () => { + beforeEach(() => { + mountComponent({ mountFunction: mount }); + }); + + it('calls `$apollo.mutate` with deleteTimelogMutation mutation and removes the row', async () => { + const mutateSpy = jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ + data: { + timelogDelete: { + errors: [], + }, + }, + }); + + await waitForPromises(); + await findDeleteButton().trigger('click'); + await waitForPromises(); + + expect(createFlash).not.toHaveBeenCalled(); + expect(mutateSpy).toHaveBeenCalledWith({ + mutation: deleteTimelogMutation, + variables: { + input: { + id: timelogToRemoveId, + }, + }, + update: expect.anything(), + }); + }); + + it('calls `createFlash` with errorMessage and does not remove the row on promise reject', async () => { + const mutateSpy = jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue({}); + + await waitForPromises(); + await findDeleteButton().trigger('click'); + await waitForPromises(); + + expect(mutateSpy).toHaveBeenCalledWith({ + mutation: deleteTimelogMutation, + variables: { + input: { + id: timelogToRemoveId, + }, + }, + update: expect.anything(), + }); + + expect(createFlash).toHaveBeenCalledWith({ + message: 'An error occurred while removing the timelog.', + captureError: true, + error: expect.any(Object), + }); + }); + }); }); |