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/sidebar/components')
-rw-r--r--spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js24
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js2
-rw-r--r--spec/frontend/sidebar/components/attention_requested_toggle_spec.js12
-rw-r--r--spec/frontend/sidebar/components/confidential/sidebar_confidentiality_content_spec.js4
-rw-r--r--spec/frontend/sidebar/components/confidential/sidebar_confidentiality_form_spec.js2
-rw-r--r--spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js7
-rw-r--r--spec/frontend/sidebar/components/time_tracking/mock_data.js28
-rw-r--r--spec/frontend/sidebar/components/time_tracking/report_spec.js86
8 files changed, 143 insertions, 22 deletions
diff --git a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js
index 69f6a6e6e04..a286eeef14f 100644
--- a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js
+++ b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js
@@ -1,5 +1,8 @@
import { shallowMount } from '@vue/test-utils';
+import { GlLink } from '@gitlab/ui';
import { TEST_HOST } from 'helpers/test_constants';
+import { TYPE_USER } from '~/graphql_shared/constants';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
import AssigneeAvatar from '~/sidebar/components/assignees/assignee_avatar.vue';
import AssigneeAvatarLink from '~/sidebar/components/assignees/assignee_avatar_link.vue';
import userDataMock from '../../user_data_mock';
@@ -32,6 +35,7 @@ describe('AssigneeAvatarLink component', () => {
});
const findTooltipText = () => wrapper.attributes('title');
+ const findUserLink = () => wrapper.findComponent(GlLink);
it('has the root url present in the assigneeUrl method', () => {
createComponent();
@@ -112,4 +116,24 @@ describe('AssigneeAvatarLink component', () => {
});
},
);
+
+ it('passes the correct user id for REST API', () => {
+ createComponent({
+ tooltipHasName: true,
+ user: userDataMock(),
+ });
+
+ expect(findUserLink().attributes('data-user-id')).toBe(String(userDataMock().id));
+ });
+
+ it('passes the correct user id for GraphQL API', () => {
+ const userId = userDataMock().id;
+
+ createComponent({
+ tooltipHasName: true,
+ user: { ...userDataMock(), id: convertToGraphQLId(TYPE_USER, userId) },
+ });
+
+ expect(findUserLink().attributes('data-user-id')).toBe(String(userId));
+ });
});
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
index c870bbecd76..724fba62479 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
@@ -72,7 +72,7 @@ describe('boards sidebar remove issue', () => {
createComponent({ canUpdate: true, slots });
findEditButton().vm.$emit('click');
- await nextTick;
+ await nextTick();
expect(findCollapsed().isVisible()).toBe(false);
expect(findExpanded().isVisible()).toBe(true);
diff --git a/spec/frontend/sidebar/components/attention_requested_toggle_spec.js b/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
index 959fa799eb7..58fa878a189 100644
--- a/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
+++ b/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
@@ -41,18 +41,18 @@ describe('Attention require toggle', () => {
);
it.each`
- attentionRequested | variant
- ${true} | ${'warning'}
- ${false} | ${'default'}
+ attentionRequested | selected
+ ${true} | ${true}
+ ${false} | ${false}
`(
- 'renders button with variant $variant when attention_requested is $attentionRequested',
- ({ attentionRequested, variant }) => {
+ 'renders button with as selected when $selected when attention_requested is $attentionRequested',
+ ({ attentionRequested, selected }) => {
factory({
type: 'reviewer',
user: { attention_requested: attentionRequested, can_update_merge_request: true },
});
- expect(findToggle().props('variant')).toBe(variant);
+ expect(findToggle().props('selected')).toBe(selected);
},
);
diff --git a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_content_spec.js b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_content_spec.js
index ab45fdf03bc..81354d64a90 100644
--- a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_content_spec.js
+++ b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_content_spec.js
@@ -69,14 +69,14 @@ describe('Sidebar Confidentiality Content', () => {
variant: 'warning',
});
expect(alertEl.text()).toBe(
- 'Only project members with at least Reporter role can view or be notified about this issue.',
+ 'Only project members with at least the Reporter role, the author, and assignees can view or be notified about this issue.',
);
});
it('displays a correct confidential text for epic', () => {
createComponent({ confidential: true, issuableType: 'epic' });
expect(findText().findComponent(GlAlert).text()).toBe(
- 'Only group members with at least Reporter role can view or be notified about this epic.',
+ 'Only group members with at least the Reporter role can view or be notified about this epic.',
);
});
});
diff --git a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_form_spec.js b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_form_spec.js
index 85d6bc7b782..1ea035c7184 100644
--- a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_form_spec.js
+++ b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_form_spec.js
@@ -89,7 +89,7 @@ describe('Sidebar Confidentiality Form', () => {
it('renders a message about making an issue confidential', () => {
expect(findWarningMessage().text()).toBe(
- 'You are going to turn on confidentiality. Only project members with at least Reporter role can view or be notified about this issue.',
+ 'You are going to turn on confidentiality. Only project members with at least the Reporter role, the author, and assignees can view or be notified about this issue.',
);
});
diff --git a/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js b/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js
index a8dc610672c..88a4913a27f 100644
--- a/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js
+++ b/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js
@@ -1,6 +1,12 @@
import { createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+import {
+ fetchData,
+ fetchError,
+ mutationData,
+ mutationError,
+} from 'ee_else_ce_jest/sidebar/components/incidents/mock_data';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
@@ -12,7 +18,6 @@ import EscalationStatus from 'ee_else_ce/sidebar/components/incidents/escalation
import { STATUS_ACKNOWLEDGED } from '~/sidebar/components/incidents/constants';
import { createAlert } from '~/flash';
import { logError } from '~/lib/logger';
-import { fetchData, fetchError, mutationData, mutationError } from './mock_data';
jest.mock('~/lib/logger');
jest.mock('~/flash');
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),
+ });
+ });
+ });
});