Skip to content

Commit be68965

Browse files
guskovauebenakansara
authored andcommitted
[ResponseOps][Cases] Fill working alert status with updated at time (elastic#204282)
Fixes: elastic#192252 ### How to test: I've created a rule in Security Solution which triggers alerts. After attached couple alerts to the case. Then I've closed case, so status alerts will be closed as well so I can filter out them from other alerts. After I checked if they have filled `kibana.alert.workflow_status_updated_at` column. ![Screenshot 2024-12-16 at 09 57 16](https://github.com/user-attachments/assets/b090e5f6-4aca-4c7f-8367-9cc2ba4412e8) ### Checklist Check the PR satisfies following conditions. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
1 parent 11f551a commit be68965

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

x-pack/plugins/cases/server/services/alerts/index.test.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ describe('updateAlertsStatus', () => {
1616
const alertsClient = alertsClientMock.create();
1717
let alertService: AlertService;
1818

19-
beforeEach(async () => {
19+
beforeEach(() => {
20+
jest.useFakeTimers();
21+
jest.setSystemTime(new Date('2022-02-21T17:35:00Z'));
22+
2023
alertService = new AlertService(esClient, logger, alertsClient);
2124
jest.clearAllMocks();
2225
});
2326

27+
afterEach(() => {
28+
jest.runOnlyPendingTimers();
29+
jest.useRealTimers();
30+
});
31+
2432
describe('happy path', () => {
2533
it('updates the status of the alert correctly', async () => {
2634
const args = [{ id: 'alert-id-1', index: '.siem-signals', status: CaseStatuses.closed }];
@@ -41,7 +49,8 @@ describe('updateAlertsStatus', () => {
4149
"script": Object {
4250
"lang": "painless",
4351
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
44-
ctx._source['kibana.alert.workflow_status'] = 'closed'
52+
ctx._source['kibana.alert.workflow_status'] = 'closed';
53+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
4554
}
4655
if (ctx._source.signal != null && ctx._source.signal.status != null) {
4756
ctx._source.signal.status = 'closed'
@@ -80,7 +89,8 @@ describe('updateAlertsStatus', () => {
8089
"script": Object {
8190
"lang": "painless",
8291
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
83-
ctx._source['kibana.alert.workflow_status'] = 'closed'
92+
ctx._source['kibana.alert.workflow_status'] = 'closed';
93+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
8494
}
8595
if (ctx._source.signal != null && ctx._source.signal.status != null) {
8696
ctx._source.signal.status = 'closed'
@@ -115,7 +125,8 @@ describe('updateAlertsStatus', () => {
115125
"script": Object {
116126
"lang": "painless",
117127
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
118-
ctx._source['kibana.alert.workflow_status'] = 'acknowledged'
128+
ctx._source['kibana.alert.workflow_status'] = 'acknowledged';
129+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
119130
}
120131
if (ctx._source.signal != null && ctx._source.signal.status != null) {
121132
ctx._source.signal.status = 'acknowledged'
@@ -154,7 +165,8 @@ describe('updateAlertsStatus', () => {
154165
"script": Object {
155166
"lang": "painless",
156167
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
157-
ctx._source['kibana.alert.workflow_status'] = 'closed'
168+
ctx._source['kibana.alert.workflow_status'] = 'closed';
169+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
158170
}
159171
if (ctx._source.signal != null && ctx._source.signal.status != null) {
160172
ctx._source.signal.status = 'closed'
@@ -183,7 +195,8 @@ describe('updateAlertsStatus', () => {
183195
"script": Object {
184196
"lang": "painless",
185197
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
186-
ctx._source['kibana.alert.workflow_status'] = 'open'
198+
ctx._source['kibana.alert.workflow_status'] = 'open';
199+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
187200
}
188201
if (ctx._source.signal != null && ctx._source.signal.status != null) {
189202
ctx._source.signal.status = 'open'
@@ -222,7 +235,8 @@ describe('updateAlertsStatus', () => {
222235
"script": Object {
223236
"lang": "painless",
224237
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
225-
ctx._source['kibana.alert.workflow_status'] = 'closed'
238+
ctx._source['kibana.alert.workflow_status'] = 'closed';
239+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
226240
}
227241
if (ctx._source.signal != null && ctx._source.signal.status != null) {
228242
ctx._source.signal.status = 'closed'
@@ -251,7 +265,8 @@ describe('updateAlertsStatus', () => {
251265
"script": Object {
252266
"lang": "painless",
253267
"source": "if (ctx._source['kibana.alert.workflow_status'] != null) {
254-
ctx._source['kibana.alert.workflow_status'] = 'open'
268+
ctx._source['kibana.alert.workflow_status'] = 'open';
269+
ctx._source['kibana.alert.workflow_status_updated_at'] = '2022-02-21T17:35:00.000Z';
255270
}
256271
if (ctx._source.signal != null && ctx._source.signal.status != null) {
257272
ctx._source.signal.status = 'open'

x-pack/plugins/cases/server/services/alerts/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import { isEmpty } from 'lodash';
1010

1111
import type { ElasticsearchClient, Logger } from '@kbn/core/server';
1212
import type { STATUS_VALUES } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names';
13-
import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names';
13+
import {
14+
ALERT_WORKFLOW_STATUS,
15+
ALERT_WORKFLOW_STATUS_UPDATED_AT,
16+
} from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names';
1417
import type { MgetResponse } from '@elastic/elasticsearch/lib/api/types';
1518
import type { AlertsClient } from '@kbn/rule-registry-plugin/server';
1619
import type { PublicMethodsOf } from '@kbn/utility-types';
@@ -169,7 +172,8 @@ export class AlertService {
169172
body: {
170173
script: {
171174
source: `if (ctx._source['${ALERT_WORKFLOW_STATUS}'] != null) {
172-
ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}'
175+
ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}';
176+
ctx._source['${ALERT_WORKFLOW_STATUS_UPDATED_AT}'] = '${new Date().toISOString()}';
173177
}
174178
if (ctx._source.signal != null && ctx._source.signal.status != null) {
175179
ctx._source.signal.status = '${status}'

0 commit comments

Comments
 (0)