UNPKG

@ahmedhegazee/nestjs-telescope

Version:

Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling

378 lines 14.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const testing_1 = require("@nestjs/testing"); const health_controller_1 = require("./health.controller"); const telescope_service_1 = require("../services/telescope.service"); const metrics_service_1 = require("../services/metrics.service"); const resilient_bridge_service_1 = require("../../devtools/bridge/resilient-bridge.service"); describe('HealthController', () => { let controller; let telescopeService; let metricsService; let resilientBridge; beforeEach(async () => { const mockTelescopeService = {}; const mockMetricsService = { getMetrics: jest.fn(), getPerformanceReport: jest.fn(), }; const mockResilientBridge = { getHealthStatus: jest.fn(), getCircuitBreakerStatus: jest.fn(), getStreamMetrics: jest.fn(), getComprehensiveStatus: jest.fn(), }; const mockConfig = { enabled: true, environment: 'test', storage: { driver: 'memory', retention: { hours: 24, maxEntries: 10000 }, batch: { enabled: true, size: 100, flushInterval: 1000 } }, devtools: { enabled: true, port: 8001, features: { dependencyGraph: true, interactivePlayground: true, performanceMetrics: true } }, dashboard: { enabled: true, path: '/telescope', strategy: 'hybrid' }, features: { realTimeUpdates: true, analytics: true, customWatchers: true }, watchers: { request: { enabled: true, priority: 1, tags: [], dependencies: [] }, query: { enabled: true, priority: 1, tags: [], dependencies: [] } } }; const module = await testing_1.Test.createTestingModule({ controllers: [health_controller_1.HealthController], providers: [ { provide: telescope_service_1.TelescopeService, useValue: mockTelescopeService, }, { provide: metrics_service_1.MetricsService, useValue: mockMetricsService, }, { provide: resilient_bridge_service_1.ResilientBridgeService, useValue: mockResilientBridge, }, { provide: 'TELESCOPE_CONFIG', useValue: mockConfig, }, ], }).compile(); controller = module.get(health_controller_1.HealthController); telescopeService = module.get(telescope_service_1.TelescopeService); metricsService = module.get(metrics_service_1.MetricsService); resilientBridge = module.get(resilient_bridge_service_1.ResilientBridgeService); }); afterEach(() => { jest.clearAllMocks(); }); describe('getHealth', () => { it('should return healthy status when all services are healthy', async () => { metricsService.getMetrics.mockReturnValue({ totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }); metricsService.getPerformanceReport.mockReturnValue({ metrics: { totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }, samples: { processingTimes: [100, 110, 90], recentBatches: 3 }, status: { isHealthy: true, alerts: [] } }); resilientBridge.getHealthStatus.mockReturnValue({ isHealthy: true, issues: [], circuitBreakers: {}, streamMetrics: {}, lastHealthCheckAt: new Date() }); resilientBridge.getCircuitBreakerStatus.mockReturnValue({ storage: { state: 'closed', failures: 0 }, devtools: { state: 'closed', failures: 0 } }); resilientBridge.getStreamMetrics.mockReturnValue({ entriesInQueue: 0, errorCount: 0, averageProcessingTime: 100, throughput: 10, isProcessing: true, subscriptions: 2 }); const result = await controller.getHealth(); expect(result.status).toBe('healthy'); expect(result.services.telescope.status).toBe('healthy'); expect(result.services.metrics.status).toBe('healthy'); expect(result.services.bridge.status).toBe('healthy'); expect(result.services.storage.status).toBe('healthy'); expect(result.metrics.totalEntries).toBe(100); expect(result.metrics.errorRate).toBe(0); }); it('should return degraded status when some services have issues', async () => { metricsService.getMetrics.mockReturnValue({ totalEntries: 100, totalBatches: 10, successfulBatches: 8, failedBatches: 2, averageProcessingTime: 100, throughput: 10, errorRate: 20, uptime: 60000 }); metricsService.getPerformanceReport.mockReturnValue({ metrics: { totalEntries: 100, totalBatches: 10, successfulBatches: 8, failedBatches: 2, averageProcessingTime: 100, throughput: 10, errorRate: 20, uptime: 60000 }, samples: { processingTimes: [100, 110, 90], recentBatches: 3 }, status: { isHealthy: false, alerts: ['High error rate: 20.00%'] } }); resilientBridge.getHealthStatus.mockReturnValue({ isHealthy: false, issues: ['High error count: 50'], circuitBreakers: {}, streamMetrics: {}, lastHealthCheckAt: new Date() }); resilientBridge.getCircuitBreakerStatus.mockReturnValue({ storage: { state: 'closed', failures: 0 }, devtools: { state: 'half-open', failures: 2 } }); const result = await controller.getHealth(); expect(result.status).toBe('degraded'); expect(result.services.metrics.status).toBe('degraded'); expect(result.services.bridge.status).toBe('degraded'); }); it('should return unhealthy status when critical services fail', async () => { metricsService.getMetrics.mockImplementation(() => { throw new Error('Metrics service unavailable'); }); const result = await controller.getHealth(); expect(result.status).toBe('unhealthy'); expect(result.services.telescope.status).toBe('unhealthy'); expect(result.services.metrics.status).toBe('unhealthy'); expect(result.services.bridge.status).toBe('unhealthy'); expect(result.services.storage.status).toBe('unhealthy'); expect(result.metrics.errorRate).toBe(100); }); }); describe('getDetailedHealth', () => { it('should return detailed health information', async () => { metricsService.getMetrics.mockReturnValue({ totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }); metricsService.getPerformanceReport.mockReturnValue({ metrics: { totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }, samples: { processingTimes: [100, 110, 90], recentBatches: 3 }, status: { isHealthy: true, alerts: [] } }); resilientBridge.getHealthStatus.mockReturnValue({ isHealthy: true, issues: [], circuitBreakers: {}, streamMetrics: {}, lastHealthCheckAt: new Date() }); resilientBridge.getCircuitBreakerStatus.mockReturnValue({ storage: { state: 'closed', failures: 0 } }); resilientBridge.getStreamMetrics.mockReturnValue({ entriesInQueue: 0, errorCount: 0, averageProcessingTime: 100, throughput: 10, isProcessing: true, subscriptions: 2 }); resilientBridge.getComprehensiveStatus.mockReturnValue({ bridge: { isHealthy: true, issues: [], circuitBreakers: {}, streamMetrics: {}, lastHealthCheckAt: new Date() }, circuitBreakers: {}, streamMetrics: {}, configuration: { resilience: { circuitBreakerEnabled: true, fallbackEnabled: true, maxRetries: 3, retryDelayMs: 1000, healthCheckIntervalMs: 30000 }, stream: {} } }); const result = await controller.getDetailedHealth(); expect(result.status).toBe('healthy'); expect(result.diagnostics).toBeDefined(); expect(result.diagnostics.bridge).toBeDefined(); expect(result.diagnostics.circuitBreakers).toBeDefined(); expect(result.diagnostics.streamMetrics).toBeDefined(); expect(result.diagnostics.configuration).toBeDefined(); expect(result.diagnostics.performanceReport).toBeDefined(); }); }); describe('getMetrics', () => { it('should return performance metrics', async () => { metricsService.getMetrics.mockReturnValue({ totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }); metricsService.getPerformanceReport.mockReturnValue({ metrics: { totalEntries: 100, totalBatches: 10, successfulBatches: 10, failedBatches: 0, averageProcessingTime: 100, throughput: 10, errorRate: 0, uptime: 60000 }, samples: { processingTimes: [100, 110, 90], recentBatches: 3 }, status: { isHealthy: true, alerts: [] } }); resilientBridge.getStreamMetrics.mockReturnValue({ entriesInQueue: 0, errorCount: 0, averageProcessingTime: 100, throughput: 10, isProcessing: true, subscriptions: 2 }); const result = await controller.getMetrics(); expect(result.timestamp).toBeDefined(); expect(result.uptime).toBeDefined(); expect(result.metrics).toBeDefined(); expect(result.streamMetrics).toBeDefined(); expect(result.performanceReport).toBeDefined(); }); }); describe('getCircuitBreakers', () => { it('should return circuit breaker status', async () => { resilientBridge.getCircuitBreakerStatus.mockReturnValue({ storage: { state: 'closed', failures: 0 }, devtools: { state: 'open', failures: 5 } }); resilientBridge.getHealthStatus.mockReturnValue({ isHealthy: false, issues: ['DevTools circuit breaker open'], circuitBreakers: { storage: { state: 'closed', failures: 0 }, devtools: { state: 'open', failures: 5 } }, streamMetrics: {}, lastHealthCheckAt: new Date() }); const result = await controller.getCircuitBreakers(); expect(result.timestamp).toBeDefined(); expect(result.circuitBreakers).toBeDefined(); expect(result.circuitBreakers.storage.state).toBe('closed'); expect(result.circuitBreakers.devtools.state).toBe('open'); expect(result.bridgeHealth).toBeDefined(); expect(result.bridgeHealth.isHealthy).toBe(false); }); }); }); //# sourceMappingURL=health.controller.spec.js.map