From 67b3e6ebe576bc41338ef8cce84e5730322573a5 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Tue, 13 Jul 2021 02:11:06 +0300 Subject: [PATCH] [Cases] Fix pushing alerts count on every push to external service (#105030) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../cases/server/client/cases/utils.test.ts | 47 ++++++++------ .../cases/server/client/cases/utils.ts | 63 ++++++++++++++----- 2 files changed, 76 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index dc8af8785056d0..d7c45d3e1e9ae6 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -608,8 +608,7 @@ describe('utils', () => { }, ], }, - // Remove second push - userActions: userActions.filter((item, index) => index !== 4), + userActions, connector, mappings: [ ...mappings, @@ -636,7 +635,7 @@ describe('utils', () => { ]); }); - it('it removes alerts correctly', async () => { + it('it filters out the alerts from the comments correctly', async () => { const res = await createIncident({ actionsClient: actionsMock, theCase: { @@ -667,6 +666,32 @@ describe('utils', () => { ]); }); + it('does not add the alerts count comment if all alerts have been pushed', async () => { + const res = await createIncident({ + actionsClient: actionsMock, + theCase: { + ...theCase, + comments: [ + { ...commentObj, id: 'comment-user-1', pushed_at: '2019-11-25T21:55:00.177Z' }, + { ...commentGeneratedAlert, pushed_at: '2019-11-25T21:55:00.177Z' }, + ], + }, + userActions, + connector, + mappings, + alerts: [], + casesConnectors, + }); + + expect(res.comments).toEqual([ + { + comment: + 'Wow, good luck catching that bad meanie! (added at 2019-11-25T21:55:00.177Z by elastic)', + commentId: 'comment-user-1', + }, + ]); + }); + it('updates an existing incident', async () => { const existingIncidentData = { priority: null, @@ -729,22 +754,6 @@ describe('utils', () => { }); }); - it('throws error if connector is not supported', async () => { - expect.assertions(2); - createIncident({ - actionsClient: actionsMock, - theCase, - userActions, - connector: { ...connector, actionTypeId: 'not-supported' }, - mappings, - alerts: [], - casesConnectors, - }).catch((e) => { - expect(e).not.toBeNull(); - expect(e).toEqual(new Error('Invalid external service')); - }); - }); - describe('getLatestPushInfo', () => { it('it returns the latest push information correctly', async () => { const res = getLatestPushInfo('456', userActions); diff --git a/x-pack/plugins/cases/server/client/cases/utils.ts b/x-pack/plugins/cases/server/client/cases/utils.ts index f44adbea2c8b22..617191462c5566 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.ts @@ -93,13 +93,53 @@ const getCommentContent = (comment: CommentResponse): string => { return ''; }; -const countAlerts = (comments: CaseResponse['comments']): number => - comments?.reduce((total, comment) => { - if (comment.type === CommentType.alert || comment.type === CommentType.generatedAlert) { - return total + (Array.isArray(comment.alertId) ? comment.alertId.length : 1); - } - return total; - }, 0) ?? 0; +interface CountAlertsInfo { + totalComments: number; + pushed: number; + totalAlerts: number; +} + +const getAlertsInfo = ( + comments: CaseResponse['comments'] +): { totalAlerts: number; hasUnpushedAlertComments: boolean } => { + const countingInfo = { totalComments: 0, pushed: 0, totalAlerts: 0 }; + + const res = + comments?.reduce(({ totalComments, pushed, totalAlerts }, comment) => { + if (comment.type === CommentType.alert || comment.type === CommentType.generatedAlert) { + return { + totalComments: totalComments + 1, + pushed: comment.pushed_at != null ? pushed + 1 : pushed, + totalAlerts: totalAlerts + (Array.isArray(comment.alertId) ? comment.alertId.length : 1), + }; + } + return { totalComments, pushed, totalAlerts }; + }, countingInfo) ?? countingInfo; + + return { + totalAlerts: res.totalAlerts, + hasUnpushedAlertComments: res.totalComments > res.pushed, + }; +}; + +const addAlertMessage = ( + caseId: string, + caseComments: CaseResponse['comments'], + comments: ExternalServiceComment[] +): ExternalServiceComment[] => { + const { totalAlerts, hasUnpushedAlertComments } = getAlertsInfo(caseComments); + + const newComments = [...comments]; + + if (hasUnpushedAlertComments) { + newComments.push({ + comment: `Elastic Alerts attached to the case: ${totalAlerts}`, + commentId: `${caseId}-total-alerts`, + }); + } + + return newComments; +}; export const createIncident = async ({ actionsClient, @@ -177,8 +217,6 @@ export const createIncident = async ({ commentsIdsToBeUpdated.has(comment.id) ); - const totalAlerts = countAlerts(caseComments); - let comments: ExternalServiceComment[] = []; if (commentsToBeUpdated && Array.isArray(commentsToBeUpdated) && commentsToBeUpdated.length > 0) { @@ -188,12 +226,7 @@ export const createIncident = async ({ } } - if (totalAlerts > 0) { - comments.push({ - comment: `Elastic Alerts attached to the case: ${totalAlerts}`, - commentId: `${theCase.id}-total-alerts`, - }); - } + comments = addAlertMessage(theCase.id, caseComments, comments); return { incident, comments }; };