diff --git a/server/routes/index.test.ts b/server/routes/index.test.ts index 16d9fd0..1910f65 100644 --- a/server/routes/index.test.ts +++ b/server/routes/index.test.ts @@ -16,7 +16,13 @@ describe('index.test.ts', () => { sendAuditMessage: sendAuditMessageMock, })) + jest.mock('uuid', () => ({ + v1: jest.fn(() => 'mocked-uuid'), + })) + beforeEach(() => { + jest.clearAllMocks() + jest.resetAllMocks() app = appWithAllRoutes({}) jest.spyOn(auditService, 'sendAuditMessage').mockResolvedValue({} as never) }) @@ -34,14 +40,6 @@ describe('index.test.ts', () => { }) it('GET /triggered-event', () => { - const mockPublishedEvent = { - action: 'TEST_EVENT', - who: 'user1', - subjectId: 'some user ID', - subjectType: 'USER_ID', - details: JSON.stringify({ testField: 'some value' }), - } - return request(app) .get('/triggered-event') .expect('Content-Type', /html/) @@ -60,12 +58,22 @@ describe('index.test.ts', () => { 'Subject Type: The type of subject ID we are using. This is most commonly a user ID.', ) expect(res.text).toContain('Service: Which service performed this action?') + expect(res.text).toContain('Correlation ID: An optional ID used to link multiple correlated events.') expect(res.text).toContain( 'Details: Any additional details specific to this action that may be relevant can go here.', ) }) .expect(() => { - expect(auditService.sendAuditMessage).toBeCalledWith(mockPublishedEvent) + expect(auditService.sendAuditMessage).toBeCalledWith( + expect.objectContaining({ + action: 'TEST_EVENT', + who: 'user1', + subjectId: 'some user ID', + subjectType: 'USER_ID', + correlationId: expect.stringMatching('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'), + details: JSON.stringify({ testField: 'some value' }), + }), + ) }) }) }) diff --git a/server/routes/index.ts b/server/routes/index.ts index c8ab2ea..23f4493 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -1,5 +1,6 @@ import { type RequestHandler, Router } from 'express' +import { v1 as uuidv1 } from 'uuid' import asyncMiddleware from '../middleware/asyncMiddleware' import type { Services } from '../services' import auditService from '../services/auditService' @@ -20,6 +21,7 @@ export default function routes(service: Services): Router { who: username, subjectId: 'some user ID', subjectType: 'USER_ID', + correlationId: uuidv1(), details: JSON.stringify({ testField: 'some value' }), }) res.render('pages/triggeredEvent', { diff --git a/server/services/auditService.ts b/server/services/auditService.ts index 7397784..2a5fb33 100644 --- a/server/services/auditService.ts +++ b/server/services/auditService.ts @@ -16,12 +16,14 @@ class AuditService { who, subjectId, subjectType, + correlationId, details, }: { action: string who: string subjectId?: string subjectType?: string + correlationId?: string details?: string }) { try { @@ -31,6 +33,7 @@ class AuditService { who, subjectId, subjectType, + correlationId, service: config.apis.audit.serviceName, details, }) diff --git a/server/views/pages/triggeredEvent.njk b/server/views/pages/triggeredEvent.njk index f60b453..5fbf1d0 100644 --- a/server/views/pages/triggeredEvent.njk +++ b/server/views/pages/triggeredEvent.njk @@ -23,6 +23,7 @@ Subject ID: The subject against which the action was performed. For example, if the action being audited was a change of John's email address, then the subject ID is John's user ID.
Subject Type: The type of subject ID we are using. This is most commonly a user ID.
+ Correlation ID: An optional ID used to link multiple correlated events.
Service: Which service performed this action?
Details: Any additional details specific to this action that may be relevant can go here. This can be anything but must be in the format of a stringifed JSON.