import { Test, TestingModule } from '@nestjs/testing'; import { AuditLogRepository } from '../../src/infrastructure/persistence/repositories/audit-log.repository'; import { PrismaService } from '../../src/infrastructure/persistence/prisma/prisma.service'; import { MockPrismaService } from '../utils/mock-prisma.service'; describe('AuditLogRepository Integration', () => { let repository: AuditLogRepository; let mockPrisma: MockPrismaService; beforeEach(async () => { mockPrisma = new MockPrismaService(); const module: TestingModule = await Test.createTestingModule({ providers: [ AuditLogRepository, { provide: PrismaService, useValue: mockPrisma }, ], }).compile(); repository = module.get(AuditLogRepository); }); afterEach(() => { mockPrisma.reset(); }); describe('log', () => { it('should create an audit log entry for STORE action', async () => { await repository.log({ shareId: BigInt(1), userId: BigInt(12345), action: 'STORE', sourceService: 'identity-service', sourceIp: '192.168.1.1', success: true, }); expect(mockPrisma.shareAccessLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ shareId: BigInt(1), userId: BigInt(12345), action: 'STORE', sourceService: 'identity-service', sourceIp: '192.168.1.1', success: true, }), }); }); it('should create an audit log entry for RETRIEVE action', async () => { await repository.log({ shareId: BigInt(2), userId: BigInt(67890), action: 'RETRIEVE', sourceService: 'recovery-service', sourceIp: '10.0.0.1', success: true, }); expect(mockPrisma.shareAccessLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ action: 'RETRIEVE', sourceService: 'recovery-service', }), }); }); it('should create an audit log entry for REVOKE action', async () => { await repository.log({ shareId: BigInt(3), userId: BigInt(11111), action: 'REVOKE', sourceService: 'identity-service', sourceIp: '172.16.0.1', success: true, }); expect(mockPrisma.shareAccessLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ action: 'REVOKE', }), }); }); it('should log failed operations with error message', async () => { await repository.log({ shareId: BigInt(0), userId: BigInt(22222), action: 'RETRIEVE', sourceService: 'identity-service', sourceIp: '192.168.1.100', success: false, errorMessage: 'Share not found', }); expect(mockPrisma.shareAccessLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ success: false, errorMessage: 'Share not found', }), }); }); it('should not throw when database error occurs', async () => { mockPrisma.shareAccessLog.create.mockRejectedValueOnce(new Error('DB Error')); await expect( repository.log({ shareId: BigInt(1), userId: BigInt(12345), action: 'STORE', sourceService: 'identity-service', sourceIp: '127.0.0.1', success: true, }), ).resolves.not.toThrow(); }); }); describe('findByShareId', () => { it('should find logs by share ID', async () => { const shareId = BigInt(100); // Create some logs await repository.log({ shareId, userId: BigInt(12345), action: 'STORE', sourceService: 'identity-service', sourceIp: '127.0.0.1', success: true, }); await repository.log({ shareId, userId: BigInt(12345), action: 'RETRIEVE', sourceService: 'identity-service', sourceIp: '127.0.0.1', success: true, }); await repository.findByShareId(shareId); expect(mockPrisma.shareAccessLog.findMany).toHaveBeenCalledWith({ where: { shareId }, orderBy: { createdAt: 'desc' }, take: 100, }); }); it('should respect limit parameter', async () => { await repository.findByShareId(BigInt(1), 50); expect(mockPrisma.shareAccessLog.findMany).toHaveBeenCalledWith( expect.objectContaining({ take: 50, }), ); }); }); describe('findByUserId', () => { it('should find logs by user ID', async () => { const userId = BigInt(55555); await repository.findByUserId(userId); expect(mockPrisma.shareAccessLog.findMany).toHaveBeenCalledWith({ where: { userId }, orderBy: { createdAt: 'desc' }, take: 100, }); }); }); describe('countRetrievesByUserToday', () => { it('should count today\'s retrieves for a user', async () => { const userId = BigInt(33333); await repository.countRetrievesByUserToday(userId); expect(mockPrisma.shareAccessLog.count).toHaveBeenCalledWith({ where: { userId, action: 'RETRIEVE', createdAt: expect.objectContaining({ gte: expect.any(Date), }), }, }); }); it('should return correct count', async () => { const userId = BigInt(44444); // Simulate 2 retrieves today mockPrisma.shareAccessLog.count.mockResolvedValueOnce(2); const count = await repository.countRetrievesByUserToday(userId); expect(count).toBe(2); }); }); });