xpeditis2.0/apps/backend/src/application/services/audit.service.spec.ts
David-Henri ARNAUD c03370e802 fix: resolve all test failures and TypeScript errors (100% test success)
 Fixed WebhookService Tests (2 tests failing → 100% passing)
- Increased timeout to 20s for retry test (handles 3 retries × 5s delays)
- Fixed signature verification test with correct 64-char hex signature
- All 7 webhook tests now passing

 Fixed Frontend TypeScript Errors
- Updated tsconfig.json with complete path aliases (@/types/*, @/hooks/*, @/utils/*, @/pages/*)
- Added explicit type annotations in useBookings.ts (prev: Set<string>)
- Fixed BookingFilters.tsx with proper type casts (s: BookingStatus)
- Fixed CarrierMonitoring.tsx with error callback types
- Zero TypeScript compilation errors

📊 Test Results
- Test Suites: 8 passed, 8 total (100%)
- Tests: 92 passed, 92 total (100%)
- Coverage: ~82% for Phase 3 services, 100% for domain entities

📝 Documentation Updated
- TEST_COVERAGE_REPORT.md: Updated to reflect 100% success rate
- IMPLEMENTATION_SUMMARY.md: Marked all issues as resolved

🎯 Phase 3 Status: COMPLETE
- All 13/13 features implemented
- All tests passing
- Production ready

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 14:48:50 +02:00

160 lines
4.4 KiB
TypeScript

/**
* Audit Service Tests
*/
import { Test, TestingModule } from '@nestjs/testing';
import { AuditService } from './audit.service';
import { AUDIT_LOG_REPOSITORY, AuditLogRepository } from '../../domain/ports/out/audit-log.repository';
import { AuditAction, AuditStatus, AuditLog } from '../../domain/entities/audit-log.entity';
describe('AuditService', () => {
let service: AuditService;
let repository: jest.Mocked<AuditLogRepository>;
beforeEach(async () => {
const mockRepository: jest.Mocked<AuditLogRepository> = {
save: jest.fn(),
findById: jest.fn(),
findByFilters: jest.fn(),
count: jest.fn(),
findByResource: jest.fn(),
findRecentByOrganization: jest.fn(),
findByUser: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({
providers: [
AuditService,
{
provide: AUDIT_LOG_REPOSITORY,
useValue: mockRepository,
},
],
}).compile();
service = module.get<AuditService>(AuditService);
repository = module.get(AUDIT_LOG_REPOSITORY);
});
describe('log', () => {
it('should create and save an audit log', async () => {
const input = {
action: AuditAction.BOOKING_CREATED,
status: AuditStatus.SUCCESS,
userId: 'user-123',
userEmail: 'user@example.com',
organizationId: 'org-123',
};
await service.log(input);
expect(repository.save).toHaveBeenCalledWith(
expect.objectContaining({
action: AuditAction.BOOKING_CREATED,
status: AuditStatus.SUCCESS,
userId: 'user-123',
})
);
});
it('should not throw error if save fails', async () => {
repository.save.mockRejectedValue(new Error('Database error'));
const input = {
action: AuditAction.BOOKING_CREATED,
status: AuditStatus.SUCCESS,
userId: 'user-123',
userEmail: 'user@example.com',
organizationId: 'org-123',
};
await expect(service.log(input)).resolves.not.toThrow();
});
});
describe('logSuccess', () => {
it('should log a successful action', async () => {
await service.logSuccess(
AuditAction.BOOKING_CREATED,
'user-123',
'user@example.com',
'org-123',
{ resourceType: 'booking', resourceId: 'booking-123' }
);
expect(repository.save).toHaveBeenCalledWith(
expect.objectContaining({
status: AuditStatus.SUCCESS,
})
);
});
});
describe('logFailure', () => {
it('should log a failed action with error message', async () => {
await service.logFailure(
AuditAction.BOOKING_CREATED,
'user-123',
'user@example.com',
'org-123',
'Validation failed',
{ resourceType: 'booking' }
);
expect(repository.save).toHaveBeenCalledWith(
expect.objectContaining({
status: AuditStatus.FAILURE,
errorMessage: 'Validation failed',
})
);
});
});
describe('getAuditLogs', () => {
it('should return audit logs with filters', async () => {
const mockLogs = [
AuditLog.create({
id: '1',
action: AuditAction.BOOKING_CREATED,
status: AuditStatus.SUCCESS,
userId: 'user-123',
userEmail: 'user@example.com',
organizationId: 'org-123',
}),
];
repository.findByFilters.mockResolvedValue(mockLogs);
repository.count.mockResolvedValue(1);
const result = await service.getAuditLogs({ organizationId: 'org-123' });
expect(result.logs).toEqual(mockLogs);
expect(result.total).toBe(1);
});
});
describe('getResourceAuditTrail', () => {
it('should return audit trail for a resource', async () => {
const mockLogs = [
AuditLog.create({
id: '1',
action: AuditAction.BOOKING_CREATED,
status: AuditStatus.SUCCESS,
userId: 'user-123',
userEmail: 'user@example.com',
organizationId: 'org-123',
resourceType: 'booking',
resourceId: 'booking-123',
}),
];
repository.findByResource.mockResolvedValue(mockLogs);
const result = await service.getResourceAuditTrail('booking', 'booking-123');
expect(result).toEqual(mockLogs);
expect(repository.findByResource).toHaveBeenCalledWith('booking', 'booking-123');
});
});
});