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;
}
