diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-19 15:09:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-19 15:09:51 +0300 |
commit | eef2437c0a359ec3437d31d1b1ea959e54c71458 (patch) | |
tree | 92ea24b2d26a057881171827e777604780838633 /spec/frontend/work_items | |
parent | 021a832cb8e90a0305452381ccf4ce15dc5e0ebd (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/work_items')
4 files changed, 215 insertions, 1 deletions
diff --git a/spec/frontend/work_items/components/notes/work_item_note_actions_spec.js b/spec/frontend/work_items/components/notes/work_item_note_actions_spec.js index dcce89bdf09..2e901783e07 100644 --- a/spec/frontend/work_items/components/notes/work_item_note_actions_spec.js +++ b/spec/frontend/work_items/components/notes/work_item_note_actions_spec.js @@ -25,6 +25,8 @@ describe('Work Item Note Actions', () => { const findAssignUnassignButton = () => wrapper.find('[data-testid="assign-note-action"]'); const findReportAbuseToAdminButton = () => wrapper.find('[data-testid="abuse-note-action"]'); const findAuthorBadge = () => wrapper.find('[data-testid="author-badge"]'); + const findMaxAccessLevelBadge = () => wrapper.find('[data-testid="max-access-level-badge"]'); + const findContributorBadge = () => wrapper.find('[data-testid="contributor-badge"]'); const addEmojiMutationResolver = jest.fn().mockResolvedValue({ data: { @@ -45,6 +47,9 @@ describe('Work Item Note Actions', () => { canReportAbuse = false, workItemType = 'Task', isWorkItemAuthor = false, + isAuthorContributor = false, + maxAccessLevelOfAuthor = '', + projectName = 'Project name', } = {}) => { wrapper = shallowMount(WorkItemNoteActions, { propsData: { @@ -56,6 +61,9 @@ describe('Work Item Note Actions', () => { canReportAbuse, workItemType, isWorkItemAuthor, + isAuthorContributor, + maxAccessLevelOfAuthor, + projectName, }, provide: { glFeatures: { @@ -251,5 +259,41 @@ describe('Work Item Note Actions', () => { expect(findAuthorBadge().attributes('title')).toBe('This user is the author of this task.'); }); }); + + describe('Max access level badge', () => { + it('does not show the access level badge by default', () => { + createComponent(); + + expect(findMaxAccessLevelBadge().exists()).toBe(false); + }); + + it('shows the access badge when we have a valid value', () => { + createComponent({ maxAccessLevelOfAuthor: 'Owner' }); + + expect(findMaxAccessLevelBadge().exists()).toBe(true); + expect(findMaxAccessLevelBadge().text()).toBe('Owner'); + expect(findMaxAccessLevelBadge().attributes('title')).toBe( + 'This user has the owner role in the Project name project.', + ); + }); + }); + + describe('Contributor badge', () => { + it('does not show the contributor badge by default', () => { + createComponent(); + + expect(findContributorBadge().exists()).toBe(false); + }); + + it('shows the contributor badge the note author is a contributor', () => { + createComponent({ isAuthorContributor: true }); + + expect(findContributorBadge().exists()).toBe(true); + expect(findContributorBadge().text()).toBe('Contributor'); + expect(findContributorBadge().attributes('title')).toBe( + 'This user has previously committed to the Project name project.', + ); + }); + }); }); }); diff --git a/spec/frontend/work_items/components/notes/work_item_note_spec.js b/spec/frontend/work_items/components/notes/work_item_note_spec.js index 39ce3193ee6..8dbd2818fc5 100644 --- a/spec/frontend/work_items/components/notes/work_item_note_spec.js +++ b/spec/frontend/work_items/components/notes/work_item_note_spec.js @@ -20,6 +20,8 @@ import { updateWorkItemMutationResponse, workItemByIidResponseFactory, workItemQueryResponse, + mockWorkItemCommentNoteByContributor, + mockWorkItemCommentByMaintainer, } from 'jest/work_items/mock_data'; import { i18n, TRACKING_CATEGORY_SHOW } from '~/work_items/constants'; import { mockTracking } from 'helpers/tracking_helper'; @@ -236,8 +238,9 @@ describe('Work Item Note', () => { }); describe('main comment', () => { - beforeEach(() => { + beforeEach(async () => { createComponent({ isFirstNote: true }); + await waitForPromises(); }); it('should have the note header, actions and body', () => { @@ -250,6 +253,10 @@ describe('Work Item Note', () => { it('should have the reply button props', () => { expect(findNoteActions().props('showReply')).toBe(true); }); + + it('should have the project name', () => { + expect(findNoteActions().props('projectName')).toBe('Project name'); + }); }); describe('comment threads', () => { @@ -374,6 +381,28 @@ describe('Work Item Note', () => { }, ); }); + + describe('Max access level badge', () => { + it('should pass the max access badge props', async () => { + createComponent({ note: mockWorkItemCommentByMaintainer }); + await waitForPromises(); + + expect(findNoteActions().props('maxAccessLevelOfAuthor')).toBe( + mockWorkItemCommentByMaintainer.maxAccessLevelOfAuthor, + ); + }); + }); + + describe('Contributor badge', () => { + it('should pass the contributor props', async () => { + createComponent({ note: mockWorkItemCommentNoteByContributor }); + await waitForPromises(); + + expect(findNoteActions().props('isAuthorContributor')).toBe( + mockWorkItemCommentNoteByContributor.authorIsContributor, + ); + }); + }); }); }); }); 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 daa18a5dee2..e03c6a7e28d 100644 --- a/spec/frontend/work_items/components/work_item_actions_spec.js +++ b/spec/frontend/work_items/components/work_item_actions_spec.js @@ -1,10 +1,12 @@ import { GlDropdownDivider, GlModal, GlToggle } from '@gitlab/ui'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; + import createMockApollo from 'helpers/mock_apollo_helper'; import { stubComponent } from 'helpers/stub_component'; 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'; @@ -14,6 +16,8 @@ import { TEST_ID_NOTIFICATIONS_TOGGLE_FORM, TEST_ID_DELETE_ACTION, TEST_ID_PROMOTE_ACTION, + TEST_ID_COPY_REFERENCE_ACTION, + TEST_ID_COPY_CREATE_NOTE_EMAIL_ACTION, } from '~/work_items/constants'; import updateWorkItemNotificationsMutation from '~/work_items/graphql/update_work_item_notifications.mutation.graphql'; import projectWorkItemTypesQuery from '~/work_items/graphql/project_work_item_types.query.graphql'; @@ -33,6 +37,9 @@ describe('WorkItemActions component', () => { let wrapper; let mockApollo; + const mockWorkItemReference = 'gitlab-org/gitlab-test#1'; + const mockWorkItemCreateNoteEmail = + 'gitlab-incoming+gitlab-org-gitlab-test-2-ddpzuq0zd2wefzofcpcdr3dg7-issue-1@gmail.com'; const findModal = () => wrapper.findComponent(GlModal); const findConfidentialityToggleButton = () => @@ -41,6 +48,9 @@ describe('WorkItemActions component', () => { wrapper.findByTestId(TEST_ID_NOTIFICATIONS_TOGGLE_ACTION); const findDeleteButton = () => wrapper.findByTestId(TEST_ID_DELETE_ACTION); const findPromoteButton = () => wrapper.findByTestId(TEST_ID_PROMOTE_ACTION); + const findCopyReferenceButton = () => wrapper.findByTestId(TEST_ID_COPY_REFERENCE_ACTION); + const findCopyCreateNoteEmailButton = () => + wrapper.findByTestId(TEST_ID_COPY_CREATE_NOTE_EMAIL_ACTION); const findDropdownItems = () => wrapper.findAll('[data-testid="work-item-actions-dropdown"] > *'); const findDropdownItemsActual = () => findDropdownItems().wrappers.map((x) => { @@ -78,6 +88,8 @@ describe('WorkItemActions component', () => { notificationsMock = [updateWorkItemNotificationsMutation, jest.fn()], convertWorkItemMutationHandler = convertWorkItemMutationSuccessHandler, workItemType = 'Task', + workItemReference = mockWorkItemReference, + workItemCreateNoteEmail = mockWorkItemCreateNoteEmail, } = {}) => { const handlers = [notificationsMock]; mockApollo = createMockApollo([ @@ -96,6 +108,8 @@ describe('WorkItemActions component', () => { subscribed, isParentConfidential, workItemType, + workItemReference, + workItemCreateNoteEmail, }, provide: { fullPath: 'gitlab-org/gitlab', @@ -141,6 +155,14 @@ describe('WorkItemActions component', () => { text: 'Turn on confidentiality', }, { + testId: TEST_ID_COPY_REFERENCE_ACTION, + text: 'Copy reference', + }, + { + testId: TEST_ID_COPY_CREATE_NOTE_EMAIL_ACTION, + text: 'Copy task email address', + }, + { divider: true, }, { @@ -359,4 +381,37 @@ describe('WorkItemActions component', () => { ]); }); }); + + describe('copy reference action', () => { + it('shows toast when user clicks on the action', () => { + createComponent(); + + expect(findCopyReferenceButton().exists()).toBe(true); + findCopyReferenceButton().vm.$emit('click'); + + expect(toast).toHaveBeenCalledWith('Reference copied'); + }); + }); + + describe('copy email address action', () => { + it.each(['key result', 'objective'])( + 'renders correct button name when work item is %s', + (workItemType) => { + createComponent({ workItemType }); + + expect(findCopyCreateNoteEmailButton().text()).toEqual( + `Copy ${workItemType} email address`, + ); + }, + ); + + it('shows toast when user clicks on the action', () => { + createComponent(); + + expect(findCopyCreateNoteEmailButton().exists()).toBe(true); + findCopyCreateNoteEmailButton().vm.$emit('click'); + + expect(toast).toHaveBeenCalledWith('Email address copied'); + }); + }); }); diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index a6e24d023a9..84e5e76cb4c 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -97,6 +97,7 @@ export const workItemQueryResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, workItemType: { __typename: 'WorkItemType', @@ -200,6 +201,7 @@ export const updateWorkItemMutationResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, workItemType: { __typename: 'WorkItemType', @@ -214,6 +216,9 @@ export const updateWorkItemMutationResponse = { adminParentLink: false, __typename: 'WorkItemPermissions', }, + reference: 'test-project-path#1', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-1@gmail.com', widgets: [ { type: 'HIERARCHY', @@ -304,6 +309,7 @@ export const convertWorkItemMutationResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, workItemType: { __typename: 'WorkItemType', @@ -318,6 +324,9 @@ export const convertWorkItemMutationResponse = { adminParentLink: false, __typename: 'WorkItemPermissions', }, + reference: 'gitlab-org/gitlab-test#1', + createNoteEmail: + 'gitlab-incoming+gitlab-org-gitlab-test-2-ddpzuq0zd2wefzofcpcdr3dg7-issue-1@gmail.com', widgets: [ { type: 'HIERARCHY', @@ -456,6 +465,7 @@ export const workItemResponseFactory = ({ id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, workItemType, userPermissions: { @@ -465,6 +475,9 @@ export const workItemResponseFactory = ({ adminParentLink, __typename: 'WorkItemPermissions', }, + reference: 'test-project-path#1', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-1@gmail.com', widgets: [ { __typename: 'WorkItemWidgetDescription', @@ -725,6 +738,7 @@ export const createWorkItemMutationResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, workItemType: { __typename: 'WorkItemType', @@ -739,6 +753,9 @@ export const createWorkItemMutationResponse = { adminParentLink: false, __typename: 'WorkItemPermissions', }, + reference: 'test-project-path#1', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-1@gmail.com', widgets: [], }, errors: [], @@ -956,6 +973,7 @@ export const workItemHierarchyEmptyResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, userPermissions: { deleteWorkItem: false, @@ -965,6 +983,9 @@ export const workItemHierarchyEmptyResponse = { __typename: 'WorkItemPermissions', }, confidential: false, + reference: 'test-project-path#1', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-1@gmail.com', widgets: [ { type: 'HIERARCHY', @@ -1015,6 +1036,7 @@ export const workItemHierarchyNoUpdatePermissionResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, confidential: false, widgets: [ @@ -1167,12 +1189,16 @@ export const workItemHierarchyResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, description: 'Issue description', state: 'OPEN', createdAt: '2022-08-03T12:41:54Z', updatedAt: null, closedAt: null, + reference: 'test-project-path#1', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-1@gmail.com', widgets: [ { type: 'HIERARCHY', @@ -1244,6 +1270,7 @@ export const workItemObjectiveWithChild = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, userPermissions: { deleteWorkItem: true, @@ -1327,6 +1354,7 @@ export const workItemHierarchyTreeResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, widgets: [ { @@ -1417,7 +1445,11 @@ export const changeIndirectWorkItemParentMutationResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, + reference: 'test-project-path#13', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-13@gmail.com', widgets: [ { __typename: 'WorkItemWidgetHierarchy', @@ -1480,7 +1512,11 @@ export const changeWorkItemParentMutationResponse = { id: '1', fullPath: 'test-project-path', archived: false, + name: 'Project name', }, + reference: 'test-project-path#2', + createNoteEmail: + 'gitlab-incoming+test-project-path-13fp7g6i9agekcv71s0jx9p58-issue-2@gmail.com', widgets: [ { __typename: 'WorkItemWidgetHierarchy', @@ -1953,6 +1989,8 @@ export const mockWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723561234', }, @@ -2002,6 +2040,8 @@ export const mockWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723565678', }, @@ -2050,6 +2090,8 @@ export const mockWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723560987', }, @@ -2158,6 +2200,8 @@ export const mockWorkItemNotesByIidResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: null, + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723561234', @@ -2209,6 +2253,8 @@ export const mockWorkItemNotesByIidResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: null, + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723568765', @@ -2261,6 +2307,8 @@ export const mockWorkItemNotesByIidResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: null, + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723569876', @@ -2371,6 +2419,8 @@ export const mockMoreWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da1112356a59e', @@ -2422,6 +2472,8 @@ export const mockMoreWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da1272356a59e', @@ -2471,6 +2523,8 @@ export const mockMoreWorkItemNotesResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723569876', @@ -2539,6 +2593,8 @@ export const createWorkItemNoteResponse = { lastEditedAt: null, url: 'http://127.0.0.1:3000/flightjs/Flight/-/work_items/37?iid_path=true#note_191', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/c872ba2d7d3eb780d2255138d67ca8b04f65b122', __typename: 'Discussion', @@ -2590,6 +2646,8 @@ export const mockWorkItemCommentNote = { lastEditedBy: null, system: false, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723569876', }, @@ -2613,6 +2671,16 @@ export const mockWorkItemCommentNote = { }, }; +export const mockWorkItemCommentNoteByContributor = { + ...mockWorkItemCommentNote, + authorIsContributor: true, +}; + +export const mockWorkItemCommentByMaintainer = { + ...mockWorkItemCommentNote, + maxAccessLevelOfAuthor: 'Maintainer', +}; + export const mockWorkItemNotesResponseWithComments = { data: { workspace: { @@ -2674,6 +2742,8 @@ export const mockWorkItemNotesResponseWithComments = { url: 'http://127.0.0.1:3000/flightjs/Flight/-/work_items/37?iid_path=true#note_191', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/2bb1162fd0d39297d1a68fdd7d4083d3780af0f3', @@ -2712,6 +2782,8 @@ export const mockWorkItemNotesResponseWithComments = { url: 'http://127.0.0.1:3000/flightjs/Flight/-/work_items/37?iid_path=true#note_191', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/2bb1162fd0d39297d1a68fdd7d4083d3780af0f3', @@ -2759,6 +2831,8 @@ export const mockWorkItemNotesResponseWithComments = { lastEditedBy: null, system: false, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723560987', @@ -2831,6 +2905,8 @@ export const workItemNotesCreateSubscriptionResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723560987', }, @@ -2901,6 +2977,8 @@ export const workItemNotesUpdateSubscriptionResponse = { lastEditedBy: null, system: true, internal: false, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/9c17769ca29798eddaed539d010da12723560987', }, @@ -2952,6 +3030,8 @@ export const workItemSystemNoteWithMetadata = { lastEditedAt: '2023-05-05T07:19:37Z', url: 'https://gdk.test:3443/flightjs/Flight/-/work_items/46#note_1651', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/7d4a46ea0525e2eeed451f7b718b0ebe73205374', __typename: 'Discussion', @@ -3044,6 +3124,8 @@ export const workItemNotesWithSystemNotesWithChangedDescription = { lastEditedAt: '2023-05-10T05:21:01Z', url: 'https://gdk.test:3443/gnuwget/Wget2/-/work_items/79#note_1687', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/aa72f4c2f3eef66afa6d79a805178801ce4bd89f', @@ -3104,6 +3186,8 @@ export const workItemNotesWithSystemNotesWithChangedDescription = { lastEditedAt: '2023-05-10T05:21:05Z', url: 'https://gdk.test:3443/gnuwget/Wget2/-/work_items/79#note_1688', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/a7d3cf7bd72f7a98f802845f538af65cb11a02cc', @@ -3165,6 +3249,8 @@ export const workItemNotesWithSystemNotesWithChangedDescription = { lastEditedAt: '2023-05-10T05:21:08Z', url: 'https://gdk.test:3443/gnuwget/Wget2/-/work_items/79#note_1689', lastEditedBy: null, + maxAccessLevelOfAuthor: 'Owner', + authorIsContributor: false, discussion: { id: 'gid://gitlab/Discussion/391eed1ee0a258cc966a51dde900424f3b51b95d', |