import { AuditService } from './audit.service';

describe('AuditService', () => {
  const create = jest.fn();
  const findMany = jest.fn();
  const prisma = { auditEvent: { create, findMany } } as any;
  const service = new AuditService(prisma);

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('writes append-only audit events with sensitive fields redacted', async () => {
    create.mockResolvedValue({ id: 'audit-1' });

    await service.record({
      actor: { id: 'm-8', name: '超级管理员', roleId: 'role-admin' },
      action: 'product.update',
      entityType: 'product',
      entityId: 'product-1',
      productId: 'product-1',
      before: { name: 'Old', password: '123456' },
      after: { name: 'New', nested: { apiKey: 'sk-test', keep: 'visible' } },
      metadata: { authorization: 'Bearer token', reason: 'manual edit' },
    });

    expect(create).toHaveBeenCalledWith({
      data: expect.objectContaining({
        actorId: 'm-8',
        actorName: '超级管理员',
        action: 'product.update',
        entityType: 'product',
        entityId: 'product-1',
        productId: 'product-1',
        before: { name: 'Old', password: '[REDACTED]' },
        after: { name: 'New', nested: { apiKey: '[REDACTED]', keep: 'visible' } },
        metadata: { authorization: '[REDACTED]', reason: 'manual edit' },
      }),
    });
  });

  it('queries by actor, entity, scope, and date range with bounded page size', async () => {
    findMany.mockResolvedValue([]);

    await service.query({
      actorId: 'm-8',
      entityType: 'bug',
      entityId: 'bug-1',
      productId: 'product-1',
      projectId: 'project-1',
      versionId: 'version-1',
      dateFrom: '2026-07-01T00:00:00.000Z',
      dateTo: '2026-07-08T23:59:59.000Z',
      take: '500',
    });

    expect(findMany).toHaveBeenCalledWith({
      where: {
        actorId: 'm-8',
        entityType: 'bug',
        entityId: 'bug-1',
        productId: 'product-1',
        projectId: 'project-1',
        versionId: 'version-1',
        createdAt: {
          gte: new Date('2026-07-01T00:00:00.000Z'),
          lte: new Date('2026-07-08T23:59:59.000Z'),
        },
      },
      orderBy: { createdAt: 'desc' },
      take: 100,
    });
  });
});
