integration tests
This commit is contained in:
175
adapters/events/InMemoryHealthEventPublisher.ts
Normal file
175
adapters/events/InMemoryHealthEventPublisher.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* In-Memory Health Event Publisher
|
||||
*
|
||||
* Tracks health-related events for testing purposes.
|
||||
* This publisher allows verification of event emission patterns
|
||||
* without requiring external event bus infrastructure.
|
||||
*/
|
||||
|
||||
import {
|
||||
HealthEventPublisher,
|
||||
HealthCheckCompletedEvent,
|
||||
HealthCheckFailedEvent,
|
||||
HealthCheckTimeoutEvent,
|
||||
ConnectedEvent,
|
||||
DisconnectedEvent,
|
||||
DegradedEvent,
|
||||
CheckingEvent,
|
||||
} from '../../../core/health/ports/HealthEventPublisher';
|
||||
|
||||
export interface HealthCheckCompletedEventWithType {
|
||||
type: 'HealthCheckCompleted';
|
||||
healthy: boolean;
|
||||
responseTime: number;
|
||||
timestamp: Date;
|
||||
endpoint?: string;
|
||||
}
|
||||
|
||||
export interface HealthCheckFailedEventWithType {
|
||||
type: 'HealthCheckFailed';
|
||||
error: string;
|
||||
timestamp: Date;
|
||||
endpoint?: string;
|
||||
}
|
||||
|
||||
export interface HealthCheckTimeoutEventWithType {
|
||||
type: 'HealthCheckTimeout';
|
||||
timestamp: Date;
|
||||
endpoint?: string;
|
||||
}
|
||||
|
||||
export interface ConnectedEventWithType {
|
||||
type: 'Connected';
|
||||
timestamp: Date;
|
||||
responseTime: number;
|
||||
}
|
||||
|
||||
export interface DisconnectedEventWithType {
|
||||
type: 'Disconnected';
|
||||
timestamp: Date;
|
||||
consecutiveFailures: number;
|
||||
}
|
||||
|
||||
export interface DegradedEventWithType {
|
||||
type: 'Degraded';
|
||||
timestamp: Date;
|
||||
reliability: number;
|
||||
}
|
||||
|
||||
export interface CheckingEventWithType {
|
||||
type: 'Checking';
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
export type HealthEvent =
|
||||
| HealthCheckCompletedEventWithType
|
||||
| HealthCheckFailedEventWithType
|
||||
| HealthCheckTimeoutEventWithType
|
||||
| ConnectedEventWithType
|
||||
| DisconnectedEventWithType
|
||||
| DegradedEventWithType
|
||||
| CheckingEventWithType;
|
||||
|
||||
export class InMemoryHealthEventPublisher implements HealthEventPublisher {
|
||||
private events: HealthEvent[] = [];
|
||||
private shouldFail: boolean = false;
|
||||
|
||||
/**
|
||||
* Publish a health check completed event
|
||||
*/
|
||||
async publishHealthCheckCompleted(event: HealthCheckCompletedEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'HealthCheckCompleted', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a health check failed event
|
||||
*/
|
||||
async publishHealthCheckFailed(event: HealthCheckFailedEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'HealthCheckFailed', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a health check timeout event
|
||||
*/
|
||||
async publishHealthCheckTimeout(event: HealthCheckTimeoutEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'HealthCheckTimeout', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a connected event
|
||||
*/
|
||||
async publishConnected(event: ConnectedEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'Connected', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a disconnected event
|
||||
*/
|
||||
async publishDisconnected(event: DisconnectedEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'Disconnected', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a degraded event
|
||||
*/
|
||||
async publishDegraded(event: DegradedEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'Degraded', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a checking event
|
||||
*/
|
||||
async publishChecking(event: CheckingEvent): Promise<void> {
|
||||
if (this.shouldFail) throw new Error('Event publisher failed');
|
||||
this.events.push({ type: 'Checking', ...event });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all published events
|
||||
*/
|
||||
getEvents(): HealthEvent[] {
|
||||
return [...this.events];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get events by type
|
||||
*/
|
||||
getEventsByType<T extends HealthEvent['type']>(type: T): Extract<HealthEvent, { type: T }>[] {
|
||||
return this.events.filter((event): event is Extract<HealthEvent, { type: T }> => event.type === type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of events
|
||||
*/
|
||||
getEventCount(): number {
|
||||
return this.events.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of events by type
|
||||
*/
|
||||
getEventCountByType(type: HealthEvent['type']): number {
|
||||
return this.events.filter(event => event.type === type).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all published events
|
||||
*/
|
||||
clear(): void {
|
||||
this.events = [];
|
||||
this.shouldFail = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the publisher to fail on publish
|
||||
*/
|
||||
setShouldFail(shouldFail: boolean): void {
|
||||
this.shouldFail = shouldFail;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user