import { lastValueFrom, of } from 'rxjs'; import { AuditMutationInterceptor } from './audit-mutation.interceptor'; import { AuditMutation } from './audit-mutation.decorator'; describe('AuditMutationInterceptor', () => { it('writes an audit event after a successful mutation response', async () => { const record = jest.fn().mockResolvedValue({ id: 'audit-1' }); const resolveCurrentUser = jest.fn().mockResolvedValue({ id: 'm-8', name: '超级管理员', roleId: 'role-admin' }); const interceptor = new AuditMutationInterceptor( new (jest.requireActual('@nestjs/core').Reflector)(), { record } as any, { resolveCurrentUser } as any, ); const handler = decorate(() => undefined); const result = await lastValueFrom(interceptor.intercept(contextFor(handler), { handle: () => of({ item: { id: 'task-1', productId: 'product-1', projectId: 'project-1', versionId: 'version-1' } }), } as any)); expect(result).toEqual({ item: { id: 'task-1', productId: 'product-1', projectId: 'project-1', versionId: 'version-1' } }); expect(record).toHaveBeenCalledWith({ actor: { id: 'm-8', name: '超级管理员', roleId: 'role-admin' }, action: 'dev_task.update', entityType: 'dev_task', entityId: 'task-1', productId: 'product-1', projectId: 'project-1', versionId: 'version-1', scope: { productId: 'product-1', projectId: 'project-1', versionId: 'version-1' }, after: { item: { id: 'task-1', productId: 'product-1', projectId: 'project-1', versionId: 'version-1' } }, metadata: { route: 'PATCH /versions/version-1/dev-tasks/task-1' }, }); }); }); function decorate(handler: Function) { AuditMutation({ action: 'dev_task.update', entityType: 'dev_task', entityIdParam: 'id', versionIdParam: 'versionId', })(handler as any, undefined as any, undefined as any); return handler; } function contextFor(handler: Function) { const request = { method: 'PATCH', originalUrl: '/versions/version-1/dev-tasks/task-1', params: { id: 'task-1', versionId: 'version-1' }, body: {}, headers: {}, }; return { getHandler: () => handler, getClass: () => class TestController {}, switchToHttp: () => ({ getRequest: () => request }), } as any; }