diff --git a/x-pack/legacy/plugins/alerting/mappings.json b/x-pack/legacy/plugins/alerting/mappings.json index bc4a7118666ed..31733f44e7ce6 100644 --- a/x-pack/legacy/plugins/alerting/mappings.json +++ b/x-pack/legacy/plugins/alerting/mappings.json @@ -54,6 +54,9 @@ "updatedBy": { "type": "keyword" }, + "createdAt": { + "type": "date" + }, "apiKey": { "type": "binary" }, diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts b/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts index 316f4cf802ab6..705f70ee96a91 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts +++ b/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts @@ -100,6 +100,7 @@ describe('create()', () => { params: { bar: true, }, + createdAt: '2019-02-12T21:01:22.479Z', actions: [ { group: 'default', @@ -160,6 +161,7 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", "params": Object { "bar": true, @@ -168,6 +170,7 @@ describe('create()', () => { "interval": "10s", }, "scheduledTaskId": "task-123", + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); @@ -189,6 +192,7 @@ describe('create()', () => { "apiKey": null, "apiKeyOwner": null, "consumer": "bar", + "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", "enabled": true, "muteAll": false, @@ -311,6 +315,7 @@ describe('create()', () => { params: { bar: true, }, + createdAt: new Date().toISOString(), actions: [ { group: 'default', @@ -407,6 +412,7 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", "params": Object { "bar": true, @@ -415,6 +421,7 @@ describe('create()', () => { "interval": "10s", }, "scheduledTaskId": "task-123", + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.bulkGet).toHaveBeenCalledWith([ @@ -460,6 +467,7 @@ describe('create()', () => { params: { bar: true, }, + createdAt: new Date().toISOString(), actions: [ { group: 'default', @@ -493,6 +501,7 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, "id": "1", "params": Object { @@ -501,6 +510,7 @@ describe('create()', () => { "schedule": Object { "interval": 10000, }, + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); @@ -806,6 +816,7 @@ describe('create()', () => { apiKey: Buffer.from('123:abc').toString('base64'), apiKeyOwner: 'elastic', createdBy: 'elastic', + createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', enabled: true, schedule: { interval: '10s' }, @@ -1248,6 +1259,7 @@ describe('get()', () => { }, ], "alertTypeId": "123", + "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", "params": Object { "bar": true, @@ -1255,6 +1267,7 @@ describe('get()', () => { "schedule": Object { "interval": "10s", }, + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.get).toHaveBeenCalledTimes(1); @@ -1347,6 +1360,7 @@ describe('find()', () => { }, ], "alertTypeId": "123", + "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", "params": Object { "bar": true, @@ -1354,6 +1368,7 @@ describe('find()', () => { "schedule": Object { "interval": "10s", }, + "updatedAt": 2019-02-12T21:01:22.479Z, }, ], "page": 1, @@ -1476,7 +1491,9 @@ describe('update()', () => { }, ], scheduledTaskId: 'task-123', + createdAt: new Date().toISOString(), }, + updated_at: new Date().toISOString(), references: [ { name: 'action_0', @@ -1517,6 +1534,7 @@ describe('update()', () => { }, }, ], + "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "id": "1", "params": Object { @@ -1526,6 +1544,7 @@ describe('update()', () => { "interval": "10s", }, "scheduledTaskId": "task-123", + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); @@ -1624,6 +1643,7 @@ describe('update()', () => { params: { bar: true, }, + createdAt: new Date().toISOString(), actions: [ { group: 'default', @@ -1652,6 +1672,7 @@ describe('update()', () => { ], scheduledTaskId: 'task-123', }, + updated_at: new Date().toISOString(), references: [ { name: 'action_0', @@ -1732,6 +1753,7 @@ describe('update()', () => { }, }, ], + "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "id": "1", "params": Object { @@ -1741,6 +1763,7 @@ describe('update()', () => { "interval": "10s", }, "scheduledTaskId": "task-123", + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.bulkGet).toHaveBeenCalledWith([ @@ -1799,6 +1822,7 @@ describe('update()', () => { params: { bar: true, }, + createdAt: new Date().toISOString(), actions: [ { group: 'default', @@ -1812,6 +1836,7 @@ describe('update()', () => { apiKey: Buffer.from('123:abc').toString('base64'), scheduledTaskId: 'task-123', }, + updated_at: new Date().toISOString(), references: [ { name: 'action_0', @@ -1853,6 +1878,7 @@ describe('update()', () => { }, ], "apiKey": "MTIzOmFiYw==", + "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "id": "1", "params": Object { @@ -1862,6 +1888,7 @@ describe('update()', () => { "interval": "10s", }, "scheduledTaskId": "task-123", + "updatedAt": 2019-02-12T21:01:22.479Z, } `); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.ts b/x-pack/legacy/plugins/alerting/server/alerts_client.ts index 70d2ff8ca3033..26e532d928c61 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client.ts +++ b/x-pack/legacy/plugins/alerting/server/alerts_client.ts @@ -77,6 +77,8 @@ interface CreateOptions { keyof Alert, | 'createdBy' | 'updatedBy' + | 'createdAt' + | 'updatedAt' | 'apiKey' | 'apiKeyOwner' | 'muteAll' @@ -142,6 +144,7 @@ export class AlertsClient { actions, createdBy: username, updatedBy: username, + createdAt: new Date().toISOString(), params: validatedAlertTypeParams, muteAll: false, mutedInstanceIds: [], @@ -171,12 +174,17 @@ export class AlertsClient { }); createdAlert.attributes.scheduledTaskId = scheduledTask.id; } - return this.getAlertFromRaw(createdAlert.id, createdAlert.attributes, references); + return this.getAlertFromRaw( + createdAlert.id, + createdAlert.attributes, + createdAlert.updated_at, + references + ); } public async get({ id }: { id: string }) { const result = await this.savedObjectsClient.get('alert', id); - return this.getAlertFromRaw(result.id, result.attributes, result.references); + return this.getAlertFromRaw(result.id, result.attributes, result.updated_at, result.references); } public async find({ options = {} }: FindOptions = {}): Promise { @@ -186,7 +194,7 @@ export class AlertsClient { }); const data = results.saved_objects.map(result => - this.getAlertFromRaw(result.id, result.attributes, result.references) + this.getAlertFromRaw(result.id, result.attributes, result.updated_at, result.references) ); return { @@ -214,7 +222,7 @@ export class AlertsClient { updateResult.scheduledTaskId && !isEqual(alert.attributes.schedule, updateResult.schedule) ) { - this.taskManager.runNow(updateResult.scheduledTaskId).catch(err => { + this.taskManager.runNow(updateResult.scheduledTaskId).catch((err: Error) => { this.logger.error( `Alert update failed to run its underlying task. TaskManager runNow failed with Error: ${err.message}` ); @@ -254,7 +262,12 @@ export class AlertsClient { references, } ); - return this.getAlertFromRaw(id, updatedObject.attributes, updatedObject.references); + return this.getAlertFromRaw( + id, + updatedObject.attributes, + updatedObject.updated_at, + updatedObject.references + ); } private apiKeyAsAlertAttributes( @@ -301,6 +314,7 @@ export class AlertsClient { enabled: true, ...this.apiKeyAsAlertAttributes(await this.createAPIKey(), username), updatedBy: username, + scheduledTaskId: scheduledTask.id, }, { version } @@ -382,6 +396,7 @@ export class AlertsClient { alertId, { updatedBy: await this.getUserName(), + mutedInstanceIds: mutedInstanceIds.filter((id: string) => id !== alertInstanceId), }, { version } @@ -424,6 +439,7 @@ export class AlertsClient { private getAlertFromRaw( id: string, rawAlert: Partial, + updatedAt: SavedObject['updated_at'], references: SavedObjectReference[] | undefined ) { if (!rawAlert.actions) { @@ -436,6 +452,8 @@ export class AlertsClient { return { id, ...rawAlert, + updatedAt: updatedAt ? new Date(updatedAt) : new Date(rawAlert.createdAt!), + createdAt: new Date(rawAlert.createdAt!), actions, }; } diff --git a/x-pack/legacy/plugins/alerting/server/routes/create.test.ts b/x-pack/legacy/plugins/alerting/server/routes/create.test.ts index c41e0d068aff2..03b33b0bd40b0 100644 --- a/x-pack/legacy/plugins/alerting/server/routes/create.test.ts +++ b/x-pack/legacy/plugins/alerting/server/routes/create.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { omit } from 'lodash'; import { createMockServer } from './_mock_server'; import { createAlertRoute } from './create'; @@ -39,8 +40,12 @@ test('creates an alert with proper parameters', async () => { payload: mockedAlert, }; + const createdAt = new Date(); + const updatedAt = new Date(); alertsClient.create.mockResolvedValueOnce({ ...mockedAlert, + createdAt, + updatedAt, id: '123', actions: [ { @@ -52,7 +57,8 @@ test('creates an alert with proper parameters', async () => { const { payload, statusCode } = await server.inject(request); expect(statusCode).toBe(200); const response = JSON.parse(payload); - expect(response).toMatchInlineSnapshot(` + expect(new Date(response.createdAt)).toEqual(createdAt); + expect(omit(response, 'createdAt', 'updatedAt')).toMatchInlineSnapshot(` Object { "actions": Array [ Object { diff --git a/x-pack/legacy/plugins/alerting/server/routes/get.test.ts b/x-pack/legacy/plugins/alerting/server/routes/get.test.ts index b97762d10c960..5b1bdc7f69708 100644 --- a/x-pack/legacy/plugins/alerting/server/routes/get.test.ts +++ b/x-pack/legacy/plugins/alerting/server/routes/get.test.ts @@ -17,6 +17,8 @@ const mockedAlert = { params: { bar: true, }, + createdAt: new Date(), + updatedAt: new Date(), actions: [ { group: 'default', @@ -40,8 +42,10 @@ test('calls get with proper parameters', async () => { alertsClient.get.mockResolvedValueOnce(mockedAlert); const { payload, statusCode } = await server.inject(request); expect(statusCode).toBe(200); - const response = JSON.parse(payload); - expect(response).toEqual(mockedAlert); + const { createdAt, updatedAt, ...response } = JSON.parse(payload); + expect({ createdAt: new Date(createdAt), updatedAt: new Date(updatedAt), ...response }).toEqual( + mockedAlert + ); expect(alertsClient.get).toHaveBeenCalledTimes(1); expect(alertsClient.get.mock.calls[0]).toMatchInlineSnapshot(` Array [ diff --git a/x-pack/legacy/plugins/alerting/server/routes/update.test.ts b/x-pack/legacy/plugins/alerting/server/routes/update.test.ts index 8ce9d94140e6d..83b70b505234f 100644 --- a/x-pack/legacy/plugins/alerting/server/routes/update.test.ts +++ b/x-pack/legacy/plugins/alerting/server/routes/update.test.ts @@ -20,6 +20,8 @@ const mockedResponse = { params: { otherField: false, }, + createdAt: new Date(), + updatedAt: new Date(), actions: [ { group: 'default', @@ -59,8 +61,10 @@ test('calls the update function with proper parameters', async () => { alertsClient.update.mockResolvedValueOnce(mockedResponse); const { payload, statusCode } = await server.inject(request); expect(statusCode).toBe(200); - const response = JSON.parse(payload); - expect(response).toEqual(mockedResponse); + const { createdAt, updatedAt, ...response } = JSON.parse(payload); + expect({ createdAt: new Date(createdAt), updatedAt: new Date(updatedAt), ...response }).toEqual( + mockedResponse + ); expect(alertsClient.update).toHaveBeenCalledTimes(1); expect(alertsClient.update.mock.calls[0]).toMatchInlineSnapshot(` Array [ diff --git a/x-pack/legacy/plugins/alerting/server/types.ts b/x-pack/legacy/plugins/alerting/server/types.ts index 7c2f3dcc918dc..a2390bf93d005 100644 --- a/x-pack/legacy/plugins/alerting/server/types.ts +++ b/x-pack/legacy/plugins/alerting/server/types.ts @@ -76,6 +76,8 @@ export interface Alert { scheduledTaskId?: string; createdBy: string | null; updatedBy: string | null; + createdAt: Date; + updatedAt: Date; apiKey: string | null; apiKeyOwner: string | null; throttle: string | null; @@ -95,6 +97,7 @@ export interface RawAlert extends SavedObjectAttributes { scheduledTaskId?: string; createdBy: string | null; updatedBy: string | null; + createdAt: string; apiKey: string | null; apiKeyOwner: string | null; throttle: string | null; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts index a78879924acd0..66e1d29b80852 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -308,6 +308,8 @@ export const getResult = (): RuleAlertType => ({ references: ['http://www.example.com', 'https://ww.example.com'], version: 1, }, + createdAt: new Date('2019-12-13T16:40:33.400Z'), + updatedAt: new Date('2019-12-13T16:40:33.400Z'), schedule: { interval: '5m' }, enabled: true, actions: [], diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts index 772f85c4dac8c..003bb10c0adae 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts @@ -92,6 +92,8 @@ export default function createAlertTests({ getService }: FtrProviderContext) { createdBy: user.username, schedule: { interval: '1m' }, scheduledTaskId: response.body.scheduledTaskId, + createdAt: response.body.createdAt, + updatedAt: response.body.updatedAt, throttle: '1m', updatedBy: user.username, apiKeyOwner: user.username, @@ -99,6 +101,9 @@ export default function createAlertTests({ getService }: FtrProviderContext) { mutedInstanceIds: [], }); expect(typeof response.body.scheduledTaskId).to.be('string'); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + const { _source: taskRecord } = await getScheduledTask(response.body.scheduledTaskId); expect(taskRecord.type).to.eql('task'); expect(taskRecord.task.taskType).to.eql('alerting:test.noop'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts index 92d8447e8f7d5..d99ab794cd28f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts @@ -66,12 +66,16 @@ export default function createFindTests({ getService }: FtrProviderContext) { params: {}, createdBy: 'elastic', scheduledTaskId: match.scheduledTaskId, + createdAt: match.createdAt, + updatedAt: match.updatedAt, throttle: '1m', updatedBy: 'elastic', apiKeyOwner: 'elastic', muteAll: false, mutedInstanceIds: [], }); + expect(Date.parse(match.createdAt)).to.be.greaterThan(0); + expect(Date.parse(match.updatedAt)).to.be.greaterThan(0); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); @@ -157,7 +161,11 @@ export default function createFindTests({ getService }: FtrProviderContext) { apiKeyOwner: 'elastic', muteAll: false, mutedInstanceIds: [], + createdAt: match.createdAt, + updatedAt: match.updatedAt, }); + expect(Date.parse(match.createdAt)).to.be.greaterThan(0); + expect(Date.parse(match.updatedAt)).to.be.greaterThan(0); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/get.ts index eaa361155b61f..20eed4013d7dd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/get.ts @@ -60,12 +60,16 @@ export default function createGetTests({ getService }: FtrProviderContext) { params: {}, createdBy: 'elastic', scheduledTaskId: response.body.scheduledTaskId, + updatedAt: response.body.updatedAt, + createdAt: response.body.createdAt, throttle: '1m', updatedBy: 'elastic', apiKeyOwner: 'elastic', muteAll: false, mutedInstanceIds: [], }); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts index ec162a75ee0a5..e89b54b1caa55 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts @@ -81,7 +81,14 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { muteAll: false, mutedInstanceIds: [], scheduledTaskId: createdAlert.scheduledTaskId, + createdAt: response.body.createdAt, + updatedAt: response.body.updatedAt, }); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan( + Date.parse(response.body.createdAt) + ); // Ensure AAD isn't broken await checkAAD({ supertest, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts index d64065b596498..50e01c65b6a86 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts @@ -79,7 +79,12 @@ export default function createAlertTests({ getService }: FtrProviderContext) { throttle: '1m', muteAll: false, mutedInstanceIds: [], + createdAt: response.body.createdAt, + updatedAt: response.body.updatedAt, }); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + expect(typeof response.body.scheduledTaskId).to.be('string'); const { _source: taskRecord } = await getScheduledTask(response.body.scheduledTaskId); expect(taskRecord.type).to.eql('task'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts index 1ee814aace797..70935a462d03e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts @@ -54,7 +54,11 @@ export default function createFindTests({ getService }: FtrProviderContext) { throttle: '1m', muteAll: false, mutedInstanceIds: [], + createdAt: match.createdAt, + updatedAt: match.updatedAt, }); + expect(Date.parse(match.createdAt)).to.be.greaterThan(0); + expect(Date.parse(match.updatedAt)).to.be.greaterThan(0); }); it(`shouldn't find alert from another space`, async () => { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts index 328b0a01d5cbd..30b5e43aee585 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts @@ -48,7 +48,11 @@ export default function createGetTests({ getService }: FtrProviderContext) { throttle: '1m', muteAll: false, mutedInstanceIds: [], + createdAt: response.body.createdAt, + updatedAt: response.body.updatedAt, }); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); }); it(`shouldn't find alert from another space`, async () => { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/update.ts index ecc614ad3807b..5a35d4bf83865 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/update.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import expect from '@kbn/expect/expect.js'; import { Spaces } from '../../scenarios'; import { checkAAD, getUrlPrefix, getTestAlertData, ObjectRemover } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -35,24 +36,33 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { actions: [], throttle: '1m', }; - await supertest + const response = await supertest .put(`${getUrlPrefix(Spaces.space1.id)}/api/alert/${createdAlert.id}`) .set('kbn-xsrf', 'foo') .send(updatedData) - .expect(200, { - ...updatedData, - id: createdAlert.id, - tags: ['bar'], - alertTypeId: 'test.noop', - consumer: 'bar', - createdBy: null, - enabled: true, - updatedBy: null, - apiKeyOwner: null, - muteAll: false, - mutedInstanceIds: [], - scheduledTaskId: createdAlert.scheduledTaskId, - }); + .expect(200); + + expect(response.body).to.eql({ + ...updatedData, + id: createdAlert.id, + tags: ['bar'], + alertTypeId: 'test.noop', + consumer: 'bar', + createdBy: null, + enabled: true, + updatedBy: null, + apiKeyOwner: null, + muteAll: false, + mutedInstanceIds: [], + scheduledTaskId: createdAlert.scheduledTaskId, + createdAt: response.body.createdAt, + updatedAt: response.body.updatedAt, + }); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan( + Date.parse(response.body.createdAt) + ); // Ensure AAD isn't broken await checkAAD({