From c805855447595082678ef784c1950f83ec34da95 Mon Sep 17 00:00:00 2001 From: Antonio Date: Fri, 4 Aug 2023 13:17:40 +0200 Subject: [PATCH] [Cases] Validate max user actions on update comment. (#163150) ## Summary Updating a comment in a case creates a user action. We want to validate that updating a comment will not make the total user actions of a case exceed 10000. ## Release Notes Updating a case comment is now included in the 10000 user actions restriction. --- .../server/client/attachments/update.test.ts | 47 ++++++++++--------- .../cases/server/client/attachments/update.ts | 8 +++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/cases/server/client/attachments/update.test.ts b/x-pack/plugins/cases/server/client/attachments/update.test.ts index c3ebb40d396d5a2..84653e7491c69b5 100644 --- a/x-pack/plugins/cases/server/client/attachments/update.test.ts +++ b/x-pack/plugins/cases/server/client/attachments/update.test.ts @@ -7,11 +7,17 @@ import { comment, actionComment } from '../../mocks'; import { createCasesClientMockArgs } from '../mocks'; -import { MAX_COMMENT_LENGTH } from '../../../common/constants'; +import { MAX_COMMENT_LENGTH, MAX_USER_ACTIONS_PER_CASE } from '../../../common/constants'; import { update } from './update'; +import { createUserActionServiceMock } from '../../services/mocks'; describe('update', () => { + const caseID = 'test-case'; + const clientArgs = createCasesClientMockArgs(); + const userActionService = createUserActionServiceMock(); + + clientArgs.services.userActionService = userActionService; beforeEach(() => { jest.clearAllMocks(); @@ -25,10 +31,7 @@ describe('update', () => { .toString(); await expect( - update( - { updateRequest: { ...updateComment, comment: longComment }, caseID: 'test-case' }, - clientArgs - ) + update({ updateRequest: { ...updateComment, comment: longComment }, caseID }, clientArgs) ).rejects.toThrow( `Failed to patch comment case id: test-case: Error: The length of the comment is too long. The maximum length is ${MAX_COMMENT_LENGTH}.` ); @@ -36,10 +39,7 @@ describe('update', () => { it('should throw an error if the comment is an empty string', async () => { await expect( - update( - { updateRequest: { ...updateComment, comment: '' }, caseID: 'test-case' }, - clientArgs - ) + update({ updateRequest: { ...updateComment, comment: '' }, caseID }, clientArgs) ).rejects.toThrow( 'Failed to patch comment case id: test-case: Error: The comment field cannot be an empty string.' ); @@ -47,14 +47,23 @@ describe('update', () => { it('should throw an error if the description is a string with empty characters', async () => { await expect( - update( - { updateRequest: { ...updateComment, comment: ' ' }, caseID: 'test-case' }, - clientArgs - ) + update({ updateRequest: { ...updateComment, comment: ' ' }, caseID }, clientArgs) ).rejects.toThrow( 'Failed to patch comment case id: test-case: Error: The comment field cannot be an empty string.' ); }); + + it(`throws error when the case user actions become > ${MAX_USER_ACTIONS_PER_CASE}`, async () => { + userActionService.getMultipleCasesUserActionsTotal.mockResolvedValue({ + [caseID]: MAX_USER_ACTIONS_PER_CASE, + }); + + await expect( + update({ updateRequest: { ...updateComment }, caseID }, clientArgs) + ).rejects.toThrow( + `The case with id ${caseID} has reached the limit of ${MAX_USER_ACTIONS_PER_CASE} user actions.` + ); + }); }); describe('actions', () => { @@ -67,7 +76,7 @@ describe('update', () => { await expect( update( - { updateRequest: { ...updateActionComment, comment: longComment }, caseID: 'test-case' }, + { updateRequest: { ...updateActionComment, comment: longComment }, caseID }, clientArgs ) ).rejects.toThrow( @@ -77,10 +86,7 @@ describe('update', () => { it('should throw an error if the comment is an empty string', async () => { await expect( - update( - { updateRequest: { ...updateActionComment, comment: '' }, caseID: 'test-case' }, - clientArgs - ) + update({ updateRequest: { ...updateActionComment, comment: '' }, caseID }, clientArgs) ).rejects.toThrow( 'Failed to patch comment case id: test-case: Error: The comment field cannot be an empty string.' ); @@ -88,10 +94,7 @@ describe('update', () => { it('should throw an error if the description is a string with empty characters', async () => { await expect( - update( - { updateRequest: { ...updateActionComment, comment: ' ' }, caseID: 'test-case' }, - clientArgs - ) + update({ updateRequest: { ...updateActionComment, comment: ' ' }, caseID }, clientArgs) ).rejects.toThrow( 'Failed to patch comment case id: test-case: Error: The comment field cannot be an empty string.' ); diff --git a/x-pack/plugins/cases/server/client/attachments/update.ts b/x-pack/plugins/cases/server/client/attachments/update.ts index 15d0fc41cfc1361..5c1243b69a1df0a 100644 --- a/x-pack/plugins/cases/server/client/attachments/update.ts +++ b/x-pack/plugins/cases/server/client/attachments/update.ts @@ -7,6 +7,7 @@ import Boom from '@hapi/boom'; +import { validateMaxUserActions } from '../../../common/utils/validators'; import { AttachmentPatchRequestRt } from '../../../common/types/api'; import { CaseCommentModel } from '../../common/models'; import { createCaseError } from '../../common/error'; @@ -29,7 +30,7 @@ export async function update( clientArgs: CasesClientArgs ): Promise { const { - services: { attachmentService }, + services: { attachmentService, userActionService }, logger, authorization, externalReferenceAttachmentTypeRegistry, @@ -41,6 +42,11 @@ export async function update( version: queryCommentVersion, ...queryRestAttributes } = decodeWithExcessOrThrow(AttachmentPatchRequestRt)(queryParams); + await validateMaxUserActions({ + caseId: caseID, + userActionService, + userActionsToAdd: 1, + }); decodeCommentRequest(queryRestAttributes, externalReferenceAttachmentTypeRegistry);