/** * @ai-summary Integration tests for audit log wiring across features * @ai-context Verifies audit logging is properly integrated into auth, vehicle, admin, and backup features */ import { Pool } from 'pg'; import { appConfig } from '../../../core/config/config-loader'; import { AuditLogService } from '../domain/audit-log.service'; import { AuditLogRepository } from '../data/audit-log.repository'; describe('AuditLog Feature Integration', () => { let pool: Pool; let repository: AuditLogRepository; let service: AuditLogService; const createdIds: string[] = []; beforeAll(async () => { pool = new Pool({ connectionString: appConfig.getDatabaseUrl(), }); repository = new AuditLogRepository(pool); service = new AuditLogService(repository); }); afterAll(async () => { // Cleanup test data if (createdIds.length > 0) { await pool.query(`DELETE FROM audit_logs WHERE id = ANY($1::uuid[])`, [createdIds]); } await pool.end(); }); describe('Vehicle logging integration', () => { it('should create audit log with vehicle category and correct resource', async () => { const userId = '550e8400-e29b-41d4-a716-446655440000'; const vehicleId = 'vehicle-uuid-123'; const entry = await service.info( 'vehicle', userId, 'Vehicle created: 2024 Toyota Camry', 'vehicle', vehicleId, { vin: '1HGBH41JXMN109186', make: 'Toyota', model: 'Camry', year: 2024 } ); createdIds.push(entry.id); expect(entry.category).toBe('vehicle'); expect(entry.severity).toBe('info'); expect(entry.userId).toBe(userId); expect(entry.action).toContain('Vehicle created'); expect(entry.resourceType).toBe('vehicle'); expect(entry.resourceId).toBe(vehicleId); expect(entry.details).toHaveProperty('vin'); expect(entry.details).toHaveProperty('make', 'Toyota'); }); it('should log vehicle update with correct fields', async () => { const userId = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; const vehicleId = 'vehicle-uuid-456'; const entry = await service.info( 'vehicle', userId, 'Vehicle updated: 2024 Toyota Camry', 'vehicle', vehicleId, { updatedFields: ['color', 'licensePlate'] } ); createdIds.push(entry.id); expect(entry.category).toBe('vehicle'); expect(entry.action).toContain('Vehicle updated'); expect(entry.details).toHaveProperty('updatedFields'); }); it('should log vehicle deletion with vehicle info', async () => { const userId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const vehicleId = 'vehicle-uuid-789'; const entry = await service.info( 'vehicle', userId, 'Vehicle deleted: 2024 Toyota Camry', 'vehicle', vehicleId, { vin: '1HGBH41JXMN109186', make: 'Toyota', model: 'Camry', year: 2024 } ); createdIds.push(entry.id); expect(entry.category).toBe('vehicle'); expect(entry.action).toContain('Vehicle deleted'); expect(entry.resourceId).toBe(vehicleId); }); }); describe('Auth logging integration', () => { it('should create audit log with auth category for signup', async () => { const userId = '550e8400-e29b-41d4-a716-446655440000'; const entry = await service.info( 'auth', userId, 'User signup: test@example.com', 'user', userId, { email: 'test@example.com', ipAddress: '192.168.1.1' } ); createdIds.push(entry.id); expect(entry.category).toBe('auth'); expect(entry.severity).toBe('info'); expect(entry.userId).toBe(userId); expect(entry.action).toContain('signup'); expect(entry.resourceType).toBe('user'); }); it('should create audit log for password reset request', async () => { const userId = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; const entry = await service.info( 'auth', userId, 'Password reset requested', 'user', userId ); createdIds.push(entry.id); expect(entry.category).toBe('auth'); expect(entry.action).toBe('Password reset requested'); }); }); describe('Admin logging integration', () => { it('should create audit log for admin user creation', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const targetAdminId = '8f14e45f-ceea-367f-a27f-c9a6d0c67e0e'; const entry = await service.info( 'admin', adminId, 'Admin user created: newadmin@example.com', 'admin_user', targetAdminId, { email: 'newadmin@example.com', role: 'admin' } ); createdIds.push(entry.id); expect(entry.category).toBe('admin'); expect(entry.severity).toBe('info'); expect(entry.userId).toBe(adminId); expect(entry.action).toContain('Admin user created'); expect(entry.resourceType).toBe('admin_user'); expect(entry.details).toHaveProperty('role', 'admin'); }); it('should create audit log for admin revocation', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const targetAdminId = 'a1b2c3d4-e5f6-7890-1234-567890abcdef'; const entry = await service.info( 'admin', adminId, 'Admin user revoked: revoked@example.com', 'admin_user', targetAdminId, { email: 'revoked@example.com' } ); createdIds.push(entry.id); expect(entry.category).toBe('admin'); expect(entry.action).toContain('Admin user revoked'); }); it('should create audit log for admin reinstatement', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const targetAdminId = 'b2c3d4e5-f6a7-8901-2345-678901bcdef0'; const entry = await service.info( 'admin', adminId, 'Admin user reinstated: reinstated@example.com', 'admin_user', targetAdminId, { email: 'reinstated@example.com' } ); createdIds.push(entry.id); expect(entry.category).toBe('admin'); expect(entry.action).toContain('Admin user reinstated'); }); }); describe('Backup/System logging integration', () => { it('should create audit log for backup creation', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const backupId = 'backup-uuid-123'; const entry = await service.info( 'system', adminId, 'Backup created: Manual backup', 'backup', backupId, { name: 'Manual backup', includeDocuments: true } ); createdIds.push(entry.id); expect(entry.category).toBe('system'); expect(entry.severity).toBe('info'); expect(entry.action).toContain('Backup created'); expect(entry.resourceType).toBe('backup'); expect(entry.resourceId).toBe(backupId); }); it('should create audit log for backup restore', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const backupId = 'backup-uuid-456'; const entry = await service.info( 'system', adminId, 'Backup restored: backup-uuid-456', 'backup', backupId, { safetyBackupId: 'safety-backup-uuid' } ); createdIds.push(entry.id); expect(entry.category).toBe('system'); expect(entry.action).toContain('Backup restored'); }); it('should create error-level audit log for backup failure', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const backupId = 'backup-uuid-789'; const entry = await service.error( 'system', adminId, 'Backup failed: Daily backup', 'backup', backupId, { error: 'Disk full' } ); createdIds.push(entry.id); expect(entry.category).toBe('system'); expect(entry.severity).toBe('error'); expect(entry.action).toContain('Backup failed'); expect(entry.details).toHaveProperty('error', 'Disk full'); }); it('should create error-level audit log for restore failure', async () => { const adminId = '7c9e6679-7425-40de-944b-e07fc1f90ae7'; const backupId = 'backup-uuid-restore-fail'; const entry = await service.error( 'system', adminId, 'Backup restore failed: backup-uuid-restore-fail', 'backup', backupId, { error: 'Corrupted archive', safetyBackupId: 'safety-uuid' } ); createdIds.push(entry.id); expect(entry.category).toBe('system'); expect(entry.severity).toBe('error'); expect(entry.action).toContain('restore failed'); }); }); describe('Cross-feature audit log queries', () => { it('should be able to filter logs by category', async () => { // Search for vehicle logs const vehicleResult = await service.search( { category: 'vehicle' }, { limit: 100, offset: 0 } ); expect(vehicleResult.logs.length).toBeGreaterThan(0); expect(vehicleResult.logs.every((log) => log.category === 'vehicle')).toBe(true); }); it('should be able to search across all categories', async () => { const result = await service.search( { search: 'created' }, { limit: 100, offset: 0 } ); expect(result.logs.length).toBeGreaterThan(0); // Should find logs from vehicle and admin categories const categories = new Set(result.logs.map((log) => log.category)); expect(categories.size).toBeGreaterThanOrEqual(1); }); it('should be able to filter by severity across categories', async () => { const errorResult = await service.search( { severity: 'error' }, { limit: 100, offset: 0 } ); expect(errorResult.logs.every((log) => log.severity === 'error')).toBe(true); }); }); });