146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
/**
|
|
* CheckApiHealthUseCase Test
|
|
*
|
|
* Tests for the health check use case that orchestrates health checks and emits events.
|
|
*/
|
|
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { CheckApiHealthUseCase } from './CheckApiHealthUseCase';
|
|
import { HealthCheckQuery, HealthCheckResult } from '../ports/HealthCheckQuery';
|
|
import { HealthEventPublisher } from '../ports/HealthEventPublisher';
|
|
|
|
describe('CheckApiHealthUseCase', () => {
|
|
let mockHealthCheckAdapter: HealthCheckQuery;
|
|
let mockEventPublisher: HealthEventPublisher;
|
|
let useCase: CheckApiHealthUseCase;
|
|
|
|
beforeEach(() => {
|
|
mockHealthCheckAdapter = {
|
|
performHealthCheck: vi.fn(),
|
|
getStatus: vi.fn(),
|
|
getHealth: vi.fn(),
|
|
getReliability: vi.fn(),
|
|
isAvailable: vi.fn(),
|
|
};
|
|
|
|
mockEventPublisher = {
|
|
publishHealthCheckCompleted: vi.fn(),
|
|
publishHealthCheckFailed: vi.fn(),
|
|
publishHealthCheckTimeout: vi.fn(),
|
|
publishConnected: vi.fn(),
|
|
publishDisconnected: vi.fn(),
|
|
publishDegraded: vi.fn(),
|
|
publishChecking: vi.fn(),
|
|
};
|
|
|
|
useCase = new CheckApiHealthUseCase({
|
|
healthCheckAdapter: mockHealthCheckAdapter,
|
|
eventPublisher: mockEventPublisher,
|
|
});
|
|
});
|
|
|
|
describe('execute', () => {
|
|
it('should perform health check and publish completed event when healthy', async () => {
|
|
const mockResult: HealthCheckResult = {
|
|
healthy: true,
|
|
responseTime: 100,
|
|
timestamp: new Date('2024-01-01T00:00:00Z'),
|
|
};
|
|
|
|
mockHealthCheckAdapter.performHealthCheck.mockResolvedValue(mockResult);
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockHealthCheckAdapter.performHealthCheck).toHaveBeenCalledTimes(1);
|
|
expect(mockEventPublisher.publishHealthCheckCompleted).toHaveBeenCalledWith({
|
|
healthy: true,
|
|
responseTime: 100,
|
|
timestamp: mockResult.timestamp,
|
|
});
|
|
expect(mockEventPublisher.publishHealthCheckFailed).not.toHaveBeenCalled();
|
|
expect(result).toEqual(mockResult);
|
|
});
|
|
|
|
it('should perform health check and publish failed event when unhealthy', async () => {
|
|
const mockResult: HealthCheckResult = {
|
|
healthy: false,
|
|
responseTime: 200,
|
|
error: 'Connection timeout',
|
|
timestamp: new Date('2024-01-01T00:00:00Z'),
|
|
};
|
|
|
|
mockHealthCheckAdapter.performHealthCheck.mockResolvedValue(mockResult);
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockHealthCheckAdapter.performHealthCheck).toHaveBeenCalledTimes(1);
|
|
expect(mockEventPublisher.publishHealthCheckFailed).toHaveBeenCalledWith({
|
|
error: 'Connection timeout',
|
|
timestamp: mockResult.timestamp,
|
|
});
|
|
expect(mockEventPublisher.publishHealthCheckCompleted).not.toHaveBeenCalled();
|
|
expect(result).toEqual(mockResult);
|
|
});
|
|
|
|
it('should handle errors during health check and publish failed event', async () => {
|
|
const errorMessage = 'Network error';
|
|
mockHealthCheckAdapter.performHealthCheck.mockRejectedValue(new Error(errorMessage));
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockHealthCheckAdapter.performHealthCheck).toHaveBeenCalledTimes(1);
|
|
expect(mockEventPublisher.publishHealthCheckFailed).toHaveBeenCalledWith({
|
|
error: errorMessage,
|
|
timestamp: expect.any(Date),
|
|
});
|
|
expect(mockEventPublisher.publishHealthCheckCompleted).not.toHaveBeenCalled();
|
|
expect(result.healthy).toBe(false);
|
|
expect(result.responseTime).toBe(0);
|
|
expect(result.error).toBe(errorMessage);
|
|
expect(result.timestamp).toBeInstanceOf(Date);
|
|
});
|
|
|
|
it('should handle non-Error objects during health check', async () => {
|
|
mockHealthCheckAdapter.performHealthCheck.mockRejectedValue('String error');
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockEventPublisher.publishHealthCheckFailed).toHaveBeenCalledWith({
|
|
error: 'String error',
|
|
timestamp: expect.any(Date),
|
|
});
|
|
expect(result.error).toBe('String error');
|
|
});
|
|
|
|
it('should handle unknown errors during health check', async () => {
|
|
mockHealthCheckAdapter.performHealthCheck.mockRejectedValue(null);
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockEventPublisher.publishHealthCheckFailed).toHaveBeenCalledWith({
|
|
error: 'Unknown error',
|
|
timestamp: expect.any(Date),
|
|
});
|
|
expect(result.error).toBe('Unknown error');
|
|
});
|
|
|
|
it('should use default error message when result has no error', async () => {
|
|
const mockResult: HealthCheckResult = {
|
|
healthy: false,
|
|
responseTime: 150,
|
|
timestamp: new Date('2024-01-01T00:00:00Z'),
|
|
};
|
|
|
|
mockHealthCheckAdapter.performHealthCheck.mockResolvedValue(mockResult);
|
|
|
|
const result = await useCase.execute();
|
|
|
|
expect(mockEventPublisher.publishHealthCheckFailed).toHaveBeenCalledWith({
|
|
error: 'Unknown error',
|
|
timestamp: mockResult.timestamp,
|
|
});
|
|
expect(result.error).toBe('Unknown error');
|
|
});
|
|
});
|
|
});
|