/** * View Data Layer Tests - Health Functionality * * This test file covers the view data layer for health functionality. * * The view data layer is responsible for: * - DTO → UI model mapping * - Formatting, sorting, and grouping * - Derived fields and defaults * - UI-specific semantics * * This layer isolates the UI from API churn by providing a stable interface * between the API layer and the presentation layer. * * Test coverage includes: * - Health status data transformation and aggregation * - System metrics and performance view models * - Health check data formatting and validation * - Derived health fields (status indicators, alerts, etc.) * - Default values and fallbacks for health views * - Health-specific formatting (uptime, response times, error rates, etc.) * - Data grouping and categorization for health components * - Real-time health monitoring data updates * - Health alert and notification view models */ import { HealthViewDataBuilder, HealthDTO } from '@/lib/builders/view-data/HealthViewDataBuilder'; import { HealthStatusDisplay } from '@/lib/display-objects/HealthStatusDisplay'; import { HealthMetricDisplay } from '@/lib/display-objects/HealthMetricDisplay'; import { HealthComponentDisplay } from '@/lib/display-objects/HealthComponentDisplay'; import { HealthAlertDisplay } from '@/lib/display-objects/HealthAlertDisplay'; describe('HealthViewDataBuilder', () => { describe('happy paths', () => { it('should transform HealthDTO to HealthViewData correctly', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.95, responseTime: 150, errorRate: 0.05, lastCheck: new Date().toISOString(), checksPassed: 995, checksFailed: 5, components: [ { name: 'Database', status: 'ok', lastCheck: new Date().toISOString(), responseTime: 50, errorRate: 0.01, }, { name: 'API', status: 'ok', lastCheck: new Date().toISOString(), responseTime: 100, errorRate: 0.02, }, ], alerts: [ { id: 'alert-1', type: 'info', title: 'System Update', message: 'System updated successfully', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe('ok'); expect(result.overallStatus.statusLabel).toBe('Healthy'); expect(result.overallStatus.statusColor).toBe('#10b981'); expect(result.overallStatus.statusIcon).toBe('✓'); expect(result.metrics.uptime).toBe('99.95%'); expect(result.metrics.responseTime).toBe('150ms'); expect(result.metrics.errorRate).toBe('0.05%'); expect(result.metrics.checksPassed).toBe(995); expect(result.metrics.checksFailed).toBe(5); expect(result.metrics.totalChecks).toBe(1000); expect(result.metrics.successRate).toBe('99.5%'); expect(result.components).toHaveLength(2); expect(result.components[0].name).toBe('Database'); expect(result.components[0].status).toBe('ok'); expect(result.components[0].statusLabel).toBe('Healthy'); expect(result.alerts).toHaveLength(1); expect(result.alerts[0].id).toBe('alert-1'); expect(result.alerts[0].type).toBe('info'); expect(result.hasAlerts).toBe(true); expect(result.hasDegradedComponents).toBe(false); expect(result.hasErrorComponents).toBe(false); }); it('should handle missing optional fields gracefully', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe('ok'); expect(result.metrics.uptime).toBe('N/A'); expect(result.metrics.responseTime).toBe('N/A'); expect(result.metrics.errorRate).toBe('N/A'); expect(result.metrics.checksPassed).toBe(0); expect(result.metrics.checksFailed).toBe(0); expect(result.metrics.totalChecks).toBe(0); expect(result.metrics.successRate).toBe('N/A'); expect(result.components).toEqual([]); expect(result.alerts).toEqual([]); expect(result.hasAlerts).toBe(false); expect(result.hasDegradedComponents).toBe(false); expect(result.hasErrorComponents).toBe(false); }); it('should handle degraded status correctly', () => { const healthDTO: HealthDTO = { status: 'degraded', timestamp: new Date().toISOString(), uptime: 95.5, responseTime: 500, errorRate: 4.5, components: [ { name: 'Database', status: 'degraded', lastCheck: new Date().toISOString(), responseTime: 200, errorRate: 2.0, }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe('degraded'); expect(result.overallStatus.statusLabel).toBe('Degraded'); expect(result.overallStatus.statusColor).toBe('#f59e0b'); expect(result.overallStatus.statusIcon).toBe('⚠'); expect(result.metrics.uptime).toBe('95.50%'); expect(result.metrics.responseTime).toBe('500ms'); expect(result.metrics.errorRate).toBe('4.50%'); expect(result.hasDegradedComponents).toBe(true); }); it('should handle error status correctly', () => { const healthDTO: HealthDTO = { status: 'error', timestamp: new Date().toISOString(), uptime: 85.2, responseTime: 2000, errorRate: 14.8, components: [ { name: 'Database', status: 'error', lastCheck: new Date().toISOString(), responseTime: 1500, errorRate: 10.0, }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe('error'); expect(result.overallStatus.statusLabel).toBe('Error'); expect(result.overallStatus.statusColor).toBe('#ef4444'); expect(result.overallStatus.statusIcon).toBe('✕'); expect(result.metrics.uptime).toBe('85.20%'); expect(result.metrics.responseTime).toBe('2.00s'); expect(result.metrics.errorRate).toBe('14.80%'); expect(result.hasErrorComponents).toBe(true); }); it('should handle multiple components with mixed statuses', () => { const healthDTO: HealthDTO = { status: 'degraded', timestamp: new Date().toISOString(), components: [ { name: 'Database', status: 'ok', lastCheck: new Date().toISOString(), }, { name: 'API', status: 'degraded', lastCheck: new Date().toISOString(), }, { name: 'Cache', status: 'error', lastCheck: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.components).toHaveLength(3); expect(result.hasDegradedComponents).toBe(true); expect(result.hasErrorComponents).toBe(true); expect(result.components[0].statusLabel).toBe('Healthy'); expect(result.components[1].statusLabel).toBe('Degraded'); expect(result.components[2].statusLabel).toBe('Error'); }); it('should handle multiple alerts with different severities', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), alerts: [ { id: 'alert-1', type: 'critical', title: 'Critical Alert', message: 'Critical issue detected', timestamp: new Date().toISOString(), }, { id: 'alert-2', type: 'warning', title: 'Warning Alert', message: 'Warning message', timestamp: new Date().toISOString(), }, { id: 'alert-3', type: 'info', title: 'Info Alert', message: 'Informational message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.alerts).toHaveLength(3); expect(result.hasAlerts).toBe(true); expect(result.alerts[0].severity).toBe('Critical'); expect(result.alerts[0].severityColor).toBe('#ef4444'); expect(result.alerts[1].severity).toBe('Warning'); expect(result.alerts[1].severityColor).toBe('#f59e0b'); expect(result.alerts[2].severity).toBe('Info'); expect(result.alerts[2].severityColor).toBe('#3b82f6'); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const now = new Date(); const healthDTO: HealthDTO = { status: 'ok', timestamp: now.toISOString(), uptime: 99.99, responseTime: 100, errorRate: 0.01, lastCheck: now.toISOString(), checksPassed: 9999, checksFailed: 1, components: [ { name: 'Test Component', status: 'ok', lastCheck: now.toISOString(), responseTime: 50, errorRate: 0.005, }, ], alerts: [ { id: 'test-alert', type: 'info', title: 'Test Alert', message: 'Test message', timestamp: now.toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe(healthDTO.status); expect(result.overallStatus.timestamp).toBe(healthDTO.timestamp); expect(result.metrics.uptime).toBe('99.99%'); expect(result.metrics.responseTime).toBe('100ms'); expect(result.metrics.errorRate).toBe('0.01%'); expect(result.metrics.lastCheck).toBe(healthDTO.lastCheck); expect(result.metrics.checksPassed).toBe(healthDTO.checksPassed); expect(result.metrics.checksFailed).toBe(healthDTO.checksFailed); expect(result.components[0].name).toBe(healthDTO.components![0].name); expect(result.components[0].status).toBe(healthDTO.components![0].status); expect(result.alerts[0].id).toBe(healthDTO.alerts![0].id); expect(result.alerts[0].type).toBe(healthDTO.alerts![0].type); }); it('should not modify the input DTO', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.95, responseTime: 150, errorRate: 0.05, components: [ { name: 'Database', status: 'ok', lastCheck: new Date().toISOString(), }, ], }; const originalDTO = JSON.parse(JSON.stringify(healthDTO)); HealthViewDataBuilder.build(healthDTO); expect(healthDTO).toEqual(originalDTO); }); it('should transform all numeric fields to formatted strings', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.95, responseTime: 150, errorRate: 0.05, checksPassed: 995, checksFailed: 5, }; const result = HealthViewDataBuilder.build(healthDTO); expect(typeof result.metrics.uptime).toBe('string'); expect(typeof result.metrics.responseTime).toBe('string'); expect(typeof result.metrics.errorRate).toBe('string'); expect(typeof result.metrics.successRate).toBe('string'); }); it('should handle large numbers correctly', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.999, responseTime: 5000, errorRate: 0.001, checksPassed: 999999, checksFailed: 1, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.uptime).toBe('99.999%'); expect(result.metrics.responseTime).toBe('5.00s'); expect(result.metrics.errorRate).toBe('0.001%'); expect(result.metrics.successRate).toBe('100.0%'); }); }); describe('edge cases', () => { it('should handle null/undefined numeric fields', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: null as any, responseTime: undefined, errorRate: null as any, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.uptime).toBe('N/A'); expect(result.metrics.responseTime).toBe('N/A'); expect(result.metrics.errorRate).toBe('N/A'); }); it('should handle negative numeric values', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: -1, responseTime: -100, errorRate: -0.5, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.uptime).toBe('N/A'); expect(result.metrics.responseTime).toBe('N/A'); expect(result.metrics.errorRate).toBe('N/A'); }); it('should handle empty components and alerts arrays', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), components: [], alerts: [], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.components).toEqual([]); expect(result.alerts).toEqual([]); expect(result.hasAlerts).toBe(false); expect(result.hasDegradedComponents).toBe(false); expect(result.hasErrorComponents).toBe(false); }); it('should handle component with missing optional fields', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), components: [ { name: 'Test Component', status: 'ok', }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.components[0].lastCheck).toBeDefined(); expect(result.components[0].formattedLastCheck).toBeDefined(); expect(result.components[0].responseTime).toBe('N/A'); expect(result.components[0].errorRate).toBe('N/A'); }); it('should handle alert with missing optional fields', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), alerts: [ { id: 'alert-1', type: 'info', title: 'Test Alert', message: 'Test message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.alerts[0].id).toBe('alert-1'); expect(result.alerts[0].type).toBe('info'); expect(result.alerts[0].title).toBe('Test Alert'); expect(result.alerts[0].message).toBe('Test message'); expect(result.alerts[0].timestamp).toBeDefined(); expect(result.alerts[0].formattedTimestamp).toBeDefined(); expect(result.alerts[0].relativeTime).toBeDefined(); }); it('should handle unknown status', () => { const healthDTO: HealthDTO = { status: 'unknown', timestamp: new Date().toISOString(), }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.overallStatus.status).toBe('unknown'); expect(result.overallStatus.statusLabel).toBe('Unknown'); expect(result.overallStatus.statusColor).toBe('#6b7280'); expect(result.overallStatus.statusIcon).toBe('?'); }); }); describe('derived fields', () => { it('should correctly calculate hasAlerts', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), alerts: [ { id: 'alert-1', type: 'info', title: 'Test', message: 'Test message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.hasAlerts).toBe(true); }); it('should correctly calculate hasDegradedComponents', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), components: [ { name: 'Component 1', status: 'ok', lastCheck: new Date().toISOString(), }, { name: 'Component 2', status: 'degraded', lastCheck: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.hasDegradedComponents).toBe(true); }); it('should correctly calculate hasErrorComponents', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), components: [ { name: 'Component 1', status: 'ok', lastCheck: new Date().toISOString(), }, { name: 'Component 2', status: 'error', lastCheck: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.hasErrorComponents).toBe(true); }); it('should correctly calculate totalChecks', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), checksPassed: 100, checksFailed: 20, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.totalChecks).toBe(120); }); it('should correctly calculate successRate', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), checksPassed: 90, checksFailed: 10, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.successRate).toBe('90.0%'); }); it('should handle zero checks correctly', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), checksPassed: 0, checksFailed: 0, }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.metrics.totalChecks).toBe(0); expect(result.metrics.successRate).toBe('N/A'); }); }); }); describe('HealthStatusDisplay', () => { describe('happy paths', () => { it('should format status labels correctly', () => { expect(HealthStatusDisplay.formatStatusLabel('ok')).toBe('Healthy'); expect(HealthStatusDisplay.formatStatusLabel('degraded')).toBe('Degraded'); expect(HealthStatusDisplay.formatStatusLabel('error')).toBe('Error'); expect(HealthStatusDisplay.formatStatusLabel('unknown')).toBe('Unknown'); }); it('should format status colors correctly', () => { expect(HealthStatusDisplay.formatStatusColor('ok')).toBe('#10b981'); expect(HealthStatusDisplay.formatStatusColor('degraded')).toBe('#f59e0b'); expect(HealthStatusDisplay.formatStatusColor('error')).toBe('#ef4444'); expect(HealthStatusDisplay.formatStatusColor('unknown')).toBe('#6b7280'); }); it('should format status icons correctly', () => { expect(HealthStatusDisplay.formatStatusIcon('ok')).toBe('✓'); expect(HealthStatusDisplay.formatStatusIcon('degraded')).toBe('⚠'); expect(HealthStatusDisplay.formatStatusIcon('error')).toBe('✕'); expect(HealthStatusDisplay.formatStatusIcon('unknown')).toBe('?'); }); it('should format timestamp correctly', () => { const timestamp = '2024-01-15T10:30:45.123Z'; const result = HealthStatusDisplay.formatTimestamp(timestamp); expect(result).toMatch(/Jan 15, 2024, 10:30:45/); }); it('should format relative time correctly', () => { const now = new Date(); const oneMinuteAgo = new Date(now.getTime() - 60 * 1000); const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000); const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000); expect(HealthStatusDisplay.formatRelativeTime(oneMinuteAgo.toISOString())).toBe('1m ago'); expect(HealthStatusDisplay.formatRelativeTime(oneHourAgo.toISOString())).toBe('1h ago'); expect(HealthStatusDisplay.formatRelativeTime(oneDayAgo.toISOString())).toBe('1d ago'); }); }); describe('edge cases', () => { it('should handle unknown status', () => { expect(HealthStatusDisplay.formatStatusLabel('unknown' as any)).toBe('Unknown'); expect(HealthStatusDisplay.formatStatusColor('unknown' as any)).toBe('#6b7280'); expect(HealthStatusDisplay.formatStatusIcon('unknown' as any)).toBe('?'); }); it('should handle just now relative time', () => { const now = new Date(); const justNow = new Date(now.getTime() - 30 * 1000); expect(HealthStatusDisplay.formatRelativeTime(justNow.toISOString())).toBe('Just now'); }); it('should handle weeks ago relative time', () => { const now = new Date(); const twoWeeksAgo = new Date(now.getTime() - 14 * 24 * 60 * 60 * 1000); expect(HealthStatusDisplay.formatRelativeTime(twoWeeksAgo.toISOString())).toBe('2w ago'); }); }); }); describe('HealthMetricDisplay', () => { describe('happy paths', () => { it('should format uptime correctly', () => { expect(HealthMetricDisplay.formatUptime(99.95)).toBe('99.95%'); expect(HealthMetricDisplay.formatUptime(100)).toBe('100.00%'); expect(HealthMetricDisplay.formatUptime(0)).toBe('0.00%'); }); it('should format response time correctly', () => { expect(HealthMetricDisplay.formatResponseTime(150)).toBe('150ms'); expect(HealthMetricDisplay.formatResponseTime(1500)).toBe('1.50s'); expect(HealthMetricDisplay.formatResponseTime(90000)).toBe('1.50m'); }); it('should format error rate correctly', () => { expect(HealthMetricDisplay.formatErrorRate(0.05)).toBe('0.05%'); expect(HealthMetricDisplay.formatErrorRate(5.5)).toBe('5.50%'); expect(HealthMetricDisplay.formatErrorRate(100)).toBe('100.00%'); }); it('should format timestamp correctly', () => { const timestamp = '2024-01-15T10:30:45.123Z'; const result = HealthMetricDisplay.formatTimestamp(timestamp); expect(result).toMatch(/Jan 15, 2024, 10:30:45/); }); it('should format success rate correctly', () => { expect(HealthMetricDisplay.formatSuccessRate(90, 10)).toBe('90.0%'); expect(HealthMetricDisplay.formatSuccessRate(100, 0)).toBe('100.0%'); expect(HealthMetricDisplay.formatSuccessRate(0, 100)).toBe('0.0%'); }); }); describe('edge cases', () => { it('should handle null/undefined values', () => { expect(HealthMetricDisplay.formatUptime(null as any)).toBe('N/A'); expect(HealthMetricDisplay.formatUptime(undefined)).toBe('N/A'); expect(HealthMetricDisplay.formatResponseTime(null as any)).toBe('N/A'); expect(HealthMetricDisplay.formatResponseTime(undefined)).toBe('N/A'); expect(HealthMetricDisplay.formatErrorRate(null as any)).toBe('N/A'); expect(HealthMetricDisplay.formatErrorRate(undefined)).toBe('N/A'); }); it('should handle negative values', () => { expect(HealthMetricDisplay.formatUptime(-1)).toBe('N/A'); expect(HealthMetricDisplay.formatResponseTime(-100)).toBe('N/A'); expect(HealthMetricDisplay.formatErrorRate(-0.5)).toBe('N/A'); }); it('should handle zero checks', () => { expect(HealthMetricDisplay.formatSuccessRate(0, 0)).toBe('N/A'); }); it('should handle decimal response times', () => { expect(HealthMetricDisplay.formatResponseTime(1234.56)).toBe('1.23s'); }); }); }); describe('HealthComponentDisplay', () => { describe('happy paths', () => { it('should format component status labels correctly', () => { expect(HealthComponentDisplay.formatStatusLabel('ok')).toBe('Healthy'); expect(HealthComponentDisplay.formatStatusLabel('degraded')).toBe('Degraded'); expect(HealthComponentDisplay.formatStatusLabel('error')).toBe('Error'); expect(HealthComponentDisplay.formatStatusLabel('unknown')).toBe('Unknown'); }); it('should format component status colors correctly', () => { expect(HealthComponentDisplay.formatStatusColor('ok')).toBe('#10b981'); expect(HealthComponentDisplay.formatStatusColor('degraded')).toBe('#f59e0b'); expect(HealthComponentDisplay.formatStatusColor('error')).toBe('#ef4444'); expect(HealthComponentDisplay.formatStatusColor('unknown')).toBe('#6b7280'); }); it('should format component status icons correctly', () => { expect(HealthComponentDisplay.formatStatusIcon('ok')).toBe('✓'); expect(HealthComponentDisplay.formatStatusIcon('degraded')).toBe('⚠'); expect(HealthComponentDisplay.formatStatusIcon('error')).toBe('✕'); expect(HealthComponentDisplay.formatStatusIcon('unknown')).toBe('?'); }); it('should format timestamp correctly', () => { const timestamp = '2024-01-15T10:30:45.123Z'; const result = HealthComponentDisplay.formatTimestamp(timestamp); expect(result).toMatch(/Jan 15, 2024, 10:30:45/); }); }); describe('edge cases', () => { it('should handle unknown status', () => { expect(HealthComponentDisplay.formatStatusLabel('unknown' as any)).toBe('Unknown'); expect(HealthComponentDisplay.formatStatusColor('unknown' as any)).toBe('#6b7280'); expect(HealthComponentDisplay.formatStatusIcon('unknown' as any)).toBe('?'); }); }); }); describe('HealthAlertDisplay', () => { describe('happy paths', () => { it('should format alert severities correctly', () => { expect(HealthAlertDisplay.formatSeverity('critical')).toBe('Critical'); expect(HealthAlertDisplay.formatSeverity('warning')).toBe('Warning'); expect(HealthAlertDisplay.formatSeverity('info')).toBe('Info'); }); it('should format alert severity colors correctly', () => { expect(HealthAlertDisplay.formatSeverityColor('critical')).toBe('#ef4444'); expect(HealthAlertDisplay.formatSeverityColor('warning')).toBe('#f59e0b'); expect(HealthAlertDisplay.formatSeverityColor('info')).toBe('#3b82f6'); }); it('should format timestamp correctly', () => { const timestamp = '2024-01-15T10:30:45.123Z'; const result = HealthAlertDisplay.formatTimestamp(timestamp); expect(result).toMatch(/Jan 15, 2024, 10:30:45/); }); it('should format relative time correctly', () => { const now = new Date(); const oneMinuteAgo = new Date(now.getTime() - 60 * 1000); const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000); const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000); expect(HealthAlertDisplay.formatRelativeTime(oneMinuteAgo.toISOString())).toBe('1m ago'); expect(HealthAlertDisplay.formatRelativeTime(oneHourAgo.toISOString())).toBe('1h ago'); expect(HealthAlertDisplay.formatRelativeTime(oneDayAgo.toISOString())).toBe('1d ago'); }); }); describe('edge cases', () => { it('should handle unknown type', () => { expect(HealthAlertDisplay.formatSeverity('unknown' as any)).toBe('Info'); expect(HealthAlertDisplay.formatSeverityColor('unknown' as any)).toBe('#3b82f6'); }); it('should handle just now relative time', () => { const now = new Date(); const justNow = new Date(now.getTime() - 30 * 1000); expect(HealthAlertDisplay.formatRelativeTime(justNow.toISOString())).toBe('Just now'); }); it('should handle weeks ago relative time', () => { const now = new Date(); const twoWeeksAgo = new Date(now.getTime() - 14 * 24 * 60 * 60 * 1000); expect(HealthAlertDisplay.formatRelativeTime(twoWeeksAgo.toISOString())).toBe('2w ago'); }); }); }); describe('Health View Data - Cross-Component Consistency', () => { describe('common patterns', () => { it('should all use consistent formatting for numeric values', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.95, responseTime: 150, errorRate: 0.05, checksPassed: 995, checksFailed: 5, components: [ { name: 'Database', status: 'ok', lastCheck: new Date().toISOString(), responseTime: 50, errorRate: 0.01, }, ], alerts: [ { id: 'alert-1', type: 'info', title: 'Test', message: 'Test message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); // All numeric values should be formatted as strings expect(typeof result.metrics.uptime).toBe('string'); expect(typeof result.metrics.responseTime).toBe('string'); expect(typeof result.metrics.errorRate).toBe('string'); expect(typeof result.metrics.successRate).toBe('string'); expect(typeof result.components[0].responseTime).toBe('string'); expect(typeof result.components[0].errorRate).toBe('string'); }); it('should all handle missing data gracefully', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), }; const result = HealthViewDataBuilder.build(healthDTO); // All fields should have safe defaults expect(result.overallStatus.status).toBe('ok'); expect(result.metrics.uptime).toBe('N/A'); expect(result.metrics.responseTime).toBe('N/A'); expect(result.metrics.errorRate).toBe('N/A'); expect(result.metrics.successRate).toBe('N/A'); expect(result.components).toEqual([]); expect(result.alerts).toEqual([]); expect(result.hasAlerts).toBe(false); expect(result.hasDegradedComponents).toBe(false); expect(result.hasErrorComponents).toBe(false); }); it('should all preserve ISO timestamps for serialization', () => { const now = new Date(); const timestamp = now.toISOString(); const healthDTO: HealthDTO = { status: 'ok', timestamp: timestamp, lastCheck: timestamp, components: [ { name: 'Database', status: 'ok', lastCheck: timestamp, }, ], alerts: [ { id: 'alert-1', type: 'info', title: 'Test', message: 'Test message', timestamp: timestamp, }, ], }; const result = HealthViewDataBuilder.build(healthDTO); // All timestamps should be preserved as ISO strings expect(result.overallStatus.timestamp).toBe(timestamp); expect(result.metrics.lastCheck).toBe(timestamp); expect(result.components[0].lastCheck).toBe(timestamp); expect(result.alerts[0].timestamp).toBe(timestamp); }); it('should all handle boolean flags correctly', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), components: [ { name: 'Component 1', status: 'ok', lastCheck: new Date().toISOString(), }, { name: 'Component 2', status: 'degraded', lastCheck: new Date().toISOString(), }, { name: 'Component 3', status: 'error', lastCheck: new Date().toISOString(), }, ], alerts: [ { id: 'alert-1', type: 'info', title: 'Test', message: 'Test message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); expect(result.hasAlerts).toBe(true); expect(result.hasDegradedComponents).toBe(true); expect(result.hasErrorComponents).toBe(true); }); }); describe('data integrity', () => { it('should maintain data consistency across transformations', () => { const healthDTO: HealthDTO = { status: 'ok', timestamp: new Date().toISOString(), uptime: 99.95, responseTime: 150, errorRate: 0.05, checksPassed: 995, checksFailed: 5, components: [ { name: 'Database', status: 'ok', lastCheck: new Date().toISOString(), }, { name: 'API', status: 'degraded', lastCheck: new Date().toISOString(), }, ], alerts: [ { id: 'alert-1', type: 'info', title: 'Test', message: 'Test message', timestamp: new Date().toISOString(), }, ], }; const result = HealthViewDataBuilder.build(healthDTO); // Verify derived fields match their source data expect(result.hasAlerts).toBe(healthDTO.alerts!.length > 0); expect(result.hasDegradedComponents).toBe( healthDTO.components!.some((c) => c.status === 'degraded') ); expect(result.hasErrorComponents).toBe( healthDTO.components!.some((c) => c.status === 'error') ); expect(result.metrics.totalChecks).toBe( (healthDTO.checksPassed || 0) + (healthDTO.checksFailed || 0) ); }); it('should handle complex real-world scenarios', () => { const now = new Date(); const timestamp = now.toISOString(); const healthDTO: HealthDTO = { status: 'degraded', timestamp: timestamp, uptime: 98.5, responseTime: 350, errorRate: 1.5, lastCheck: timestamp, checksPassed: 985, checksFailed: 15, components: [ { name: 'Database', status: 'ok', lastCheck: timestamp, responseTime: 50, errorRate: 0.01, }, { name: 'API', status: 'degraded', lastCheck: timestamp, responseTime: 200, errorRate: 2.0, }, { name: 'Cache', status: 'error', lastCheck: timestamp, responseTime: 1000, errorRate: 10.0, }, ], alerts: [ { id: 'alert-1', type: 'critical', title: 'Cache Failure', message: 'Cache service is down', timestamp: timestamp, }, { id: 'alert-2', type: 'warning', title: 'High Response Time', message: 'API response time is elevated', timestamp: timestamp, }, ], }; const result = HealthViewDataBuilder.build(healthDTO); // Verify all transformations expect(result.overallStatus.status).toBe('degraded'); expect(result.overallStatus.statusLabel).toBe('Degraded'); expect(result.metrics.uptime).toBe('98.50%'); expect(result.metrics.responseTime).toBe('350ms'); expect(result.metrics.errorRate).toBe('1.50%'); expect(result.metrics.checksPassed).toBe(985); expect(result.metrics.checksFailed).toBe(15); expect(result.metrics.totalChecks).toBe(1000); expect(result.metrics.successRate).toBe('98.5%'); expect(result.components).toHaveLength(3); expect(result.components[0].statusLabel).toBe('Healthy'); expect(result.components[1].statusLabel).toBe('Degraded'); expect(result.components[2].statusLabel).toBe('Error'); expect(result.alerts).toHaveLength(2); expect(result.alerts[0].severity).toBe('Critical'); expect(result.alerts[0].severityColor).toBe('#ef4444'); expect(result.alerts[1].severity).toBe('Warning'); expect(result.alerts[1].severityColor).toBe('#f59e0b'); expect(result.hasAlerts).toBe(true); expect(result.hasDegradedComponents).toBe(true); expect(result.hasErrorComponents).toBe(true); }); }); });