feat(audit): 收口领域写接口权限审计
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user