/** * 监控服务测试 * * 功能描述: * - 测试MonitoringService的核心功能 * - 包含属性测试验证操作确认和日志记录 * - 包含属性测试验证系统监控和告警 * * **Feature: zulip-integration, Property 10: 操作确认和日志记录** * **Validates: Requirements 4.5, 8.5, 9.1, 9.2, 9.3** * * **Feature: zulip-integration, Property 11: 系统监控和告警** * **Validates: Requirements 9.4** * * @author angjustinl moyin * @version 1.0.0 * @since 2025-12-25 */ import { Test, TestingModule } from '@nestjs/testing'; import { ConfigService } from '@nestjs/config'; import { Logger } from '@nestjs/common'; import * as fc from 'fast-check'; import { MonitoringService, ConnectionEventType, ApiCallResult, AlertLevel, ConnectionLog, ApiCallLog, MessageForwardLog, OperationConfirmation, } from './monitoring.service'; describe('MonitoringService', () => { let service: MonitoringService; let mockConfigService: jest.Mocked; beforeEach(async () => { jest.clearAllMocks(); // Mock NestJS Logger jest.spyOn(Logger.prototype, 'log').mockImplementation(); jest.spyOn(Logger.prototype, 'error').mockImplementation(); jest.spyOn(Logger.prototype, 'warn').mockImplementation(); jest.spyOn(Logger.prototype, 'debug').mockImplementation(); mockConfigService = { get: jest.fn((key: string, defaultValue?: any) => { const config: Record = { 'MONITORING_HEALTH_CHECK_INTERVAL': 60000, 'MONITORING_ERROR_RATE_THRESHOLD': 0.1, 'MONITORING_RESPONSE_TIME_THRESHOLD': 5000, 'MONITORING_MEMORY_THRESHOLD': 0.9, }; return config[key] ?? defaultValue; }), } as any; const module: TestingModule = await Test.createTestingModule({ providers: [ MonitoringService, { provide: ConfigService, useValue: mockConfigService, }, ], }).compile(); service = module.get(MonitoringService); }); afterEach(async () => { service.onModuleDestroy(); }); it('should be defined', () => { expect(service).toBeDefined(); }); describe('基础功能测试', () => { it('应该正确初始化统计数据', () => { const stats = service.getStats(); expect(stats.connections.total).toBe(0); expect(stats.apiCalls.total).toBe(0); expect(stats.messages.upstream).toBe(0); expect(stats.alerts.total).toBe(0); }); it('应该正确重置统计数据', () => { // 添加一些数据 service.logConnection({ socketId: 'socket1', eventType: ConnectionEventType.CONNECTED, timestamp: new Date(), }); // 重置 service.resetStats(); const stats = service.getStats(); expect(stats.connections.total).toBe(0); }); }); describe('连接日志测试', () => { it('应该正确记录连接事件', () => { service.logConnection({ socketId: 'socket1', userId: 'user1', eventType: ConnectionEventType.CONNECTED, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.connections.total).toBe(1); expect(stats.connections.active).toBe(1); }); it('应该正确记录断开事件', () => { service.logConnection({ socketId: 'socket1', eventType: ConnectionEventType.CONNECTED, timestamp: new Date(), }); service.logConnection({ socketId: 'socket1', eventType: ConnectionEventType.DISCONNECTED, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.connections.active).toBe(0); }); it('应该正确记录错误事件', () => { service.logConnection({ socketId: 'socket1', eventType: ConnectionEventType.ERROR, error: 'Connection failed', timestamp: new Date(), }); const stats = service.getStats(); expect(stats.connections.errors).toBe(1); }); }); describe('API调用日志测试', () => { it('应该正确记录成功的API调用', () => { service.logApiCall({ operation: 'sendMessage', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 100, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.apiCalls.total).toBe(1); expect(stats.apiCalls.success).toBe(1); }); it('应该正确记录失败的API调用', () => { service.logApiCall({ operation: 'sendMessage', userId: 'user1', result: ApiCallResult.FAILURE, responseTime: 100, error: 'API error', timestamp: new Date(), }); const stats = service.getStats(); expect(stats.apiCalls.failures).toBe(1); }); it('应该在响应时间过长时发送告警', () => { const alertHandler = jest.fn(); service.on('alert', alertHandler); service.logApiCall({ operation: 'sendMessage', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 10000, // 超过阈值 timestamp: new Date(), }); expect(alertHandler).toHaveBeenCalled(); }); }); describe('消息转发日志测试', () => { it('应该正确记录上行消息', () => { service.logMessageForward({ fromUserId: 'user1', toUserIds: ['user2'], stream: 'test-stream', topic: 'test-topic', direction: 'upstream', success: true, latency: 50, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.messages.upstream).toBe(1); }); it('应该正确记录下行消息', () => { service.logMessageForward({ fromUserId: 'user1', toUserIds: ['user2', 'user3'], stream: 'test-stream', topic: 'test-topic', direction: 'downstream', success: true, latency: 30, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.messages.downstream).toBe(1); }); }); describe('操作确认测试', () => { it('应该正确记录操作确认', () => { const confirmHandler = jest.fn(); service.on('operation_confirmed', confirmHandler); service.confirmOperation({ operationId: 'op1', operation: 'sendMessage', userId: 'user1', success: true, timestamp: new Date(), }); expect(confirmHandler).toHaveBeenCalled(); expect(Logger.prototype.log).toHaveBeenCalled(); }); }); describe('告警测试', () => { it('应该正确发送告警', () => { const alertHandler = jest.fn(); service.on('alert', alertHandler); service.sendAlert({ id: 'alert1', level: AlertLevel.WARNING, title: 'Test Alert', message: 'This is a test alert', component: 'test', timestamp: new Date(), }); expect(alertHandler).toHaveBeenCalled(); const stats = service.getStats(); expect(stats.alerts.byLevel[AlertLevel.WARNING]).toBe(1); }); it('应该正确获取最近的告警', () => { service.sendAlert({ id: 'alert1', level: AlertLevel.INFO, title: 'Alert 1', message: 'Message 1', component: 'test', timestamp: new Date(), }); service.sendAlert({ id: 'alert2', level: AlertLevel.WARNING, title: 'Alert 2', message: 'Message 2', component: 'test', timestamp: new Date(), }); const recentAlerts = service.getRecentAlerts(10); expect(recentAlerts.length).toBe(2); }); }); describe('健康检查测试', () => { it('应该返回健康状态', async () => { const health = await service.checkSystemHealth(); expect(health).toBeDefined(); expect(health.status).toBeDefined(); expect(health.components).toBeDefined(); expect(health.timestamp).toBeInstanceOf(Date); }); }); /** * 属性测试: 操作确认和日志记录 * * **Feature: zulip-integration, Property 10: 操作确认和日志记录** * **Validates: Requirements 4.5, 8.5, 9.1, 9.2, 9.3** * * 对于任何重要的系统操作(连接管理、API调用、消息转发), * 系统应该记录相应的日志信息,并向客户端返回操作确认 */ describe('Property 10: 操作确认和日志记录', () => { beforeEach(() => { service.resetStats(); }); /** * 属性: 对于任何连接事件,系统应该正确记录并更新统计 */ it('对于任何连接事件,系统应该正确记录并更新统计', async () => { await fc.assert( fc.asyncProperty( // 生成Socket ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成用户ID(可选) fc.option(fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0)), // 生成事件类型 fc.constantFrom( ConnectionEventType.CONNECTED, ConnectionEventType.DISCONNECTED, ConnectionEventType.ERROR, ConnectionEventType.TIMEOUT ), async (socketId, userId, eventType) => { const initialStats = service.getStats(); const initialTotal = initialStats.connections.total; const initialActive = initialStats.connections.active; const initialErrors = initialStats.connections.errors; const log: ConnectionLog = { socketId, userId: userId ?? undefined, eventType, timestamp: new Date(), }; service.logConnection(log); const newStats = service.getStats(); // 验证统计更新正确 if (eventType === ConnectionEventType.CONNECTED) { expect(newStats.connections.total).toBe(initialTotal + 1); expect(newStats.connections.active).toBe(initialActive + 1); } else if (eventType === ConnectionEventType.DISCONNECTED) { expect(newStats.connections.active).toBe(Math.max(0, initialActive - 1)); } else if (eventType === ConnectionEventType.ERROR || eventType === ConnectionEventType.TIMEOUT) { expect(newStats.connections.errors).toBe(initialErrors + 1); } // 验证日志被调用 expect(Logger.prototype.log).toHaveBeenCalled(); } ), { numRuns: 100 } ); }, 30000); /** * 属性: 对于任何API调用,系统应该正确记录响应时间和结果 */ it('对于任何API调用,系统应该正确记录响应时间和结果', async () => { await fc.assert( fc.asyncProperty( // 生成操作名称 fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成用户ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成结果 fc.constantFrom( ApiCallResult.SUCCESS, ApiCallResult.FAILURE, ApiCallResult.TIMEOUT, ApiCallResult.RATE_LIMITED ), // 生成响应时间 fc.integer({ min: 1, max: 10000 }), async (operation, userId, result, responseTime) => { const initialStats = service.getStats(); const initialTotal = initialStats.apiCalls.total; const initialSuccess = initialStats.apiCalls.success; const initialFailures = initialStats.apiCalls.failures; const log: ApiCallLog = { operation, userId, result, responseTime, timestamp: new Date(), }; service.logApiCall(log); const newStats = service.getStats(); // 验证总数增加 expect(newStats.apiCalls.total).toBe(initialTotal + 1); // 验证成功/失败计数 if (result === ApiCallResult.SUCCESS) { expect(newStats.apiCalls.success).toBe(initialSuccess + 1); } else { expect(newStats.apiCalls.failures).toBe(initialFailures + 1); } // 验证日志被调用 expect(Logger.prototype.log).toHaveBeenCalled(); } ), { numRuns: 100 } ); }, 30000); /** * 属性: 对于任何消息转发,系统应该正确记录方向和延迟 */ it('对于任何消息转发,系统应该正确记录方向和延迟', async () => { await fc.assert( fc.asyncProperty( // 生成发送者ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成接收者ID列表 fc.array( fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), { minLength: 1, maxLength: 10 } ), // 生成Stream名称 fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成Topic名称 fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成方向 fc.constantFrom('upstream' as const, 'downstream' as const), // 生成延迟 fc.integer({ min: 1, max: 5000 }), async (fromUserId, toUserIds, stream, topic, direction, latency) => { const initialStats = service.getStats(); const initialUpstream = initialStats.messages.upstream; const initialDownstream = initialStats.messages.downstream; const log: MessageForwardLog = { fromUserId, toUserIds, stream, topic, direction, success: true, latency, timestamp: new Date(), }; service.logMessageForward(log); const newStats = service.getStats(); // 验证方向计数 if (direction === 'upstream') { expect(newStats.messages.upstream).toBe(initialUpstream + 1); } else { expect(newStats.messages.downstream).toBe(initialDownstream + 1); } // 验证日志被调用 expect(Logger.prototype.log).toHaveBeenCalled(); } ), { numRuns: 100 } ); }, 30000); /** * 属性: 对于任何操作确认,系统应该记录并发出事件 */ it('对于任何操作确认,系统应该记录并发出事件', async () => { await fc.assert( fc.asyncProperty( // 生成操作ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成操作名称 fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成用户ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成成功状态 fc.boolean(), async (operationId, operation, userId, success) => { const eventHandler = jest.fn(); service.on('operation_confirmed', eventHandler); const confirmation: OperationConfirmation = { operationId, operation, userId, success, timestamp: new Date(), }; service.confirmOperation(confirmation); // 验证事件被发出 expect(eventHandler).toHaveBeenCalledWith(confirmation); // 验证日志被调用 expect(Logger.prototype.log).toHaveBeenCalled(); service.removeListener('operation_confirmed', eventHandler); } ), { numRuns: 100 } ); }, 30000); }); /** * 属性测试: 系统监控和告警 * * **Feature: zulip-integration, Property 11: 系统监控和告警** * **Validates: Requirements 9.4** * * 对于任何系统资源异常或性能问题,系统应该检测异常情况并发送相应的告警通知 */ describe('Property 11: 系统监控和告警', () => { beforeEach(() => { service.resetStats(); }); /** * 属性: 对于任何告警,系统应该正确记录并更新统计 */ it('对于任何告警,系统应该正确记录并更新统计', async () => { await fc.assert( fc.asyncProperty( // 生成告警ID fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), // 生成告警级别 fc.constantFrom( AlertLevel.INFO, AlertLevel.WARNING, AlertLevel.ERROR, AlertLevel.CRITICAL ), // 生成标题 fc.string({ minLength: 1, maxLength: 100 }).filter(s => s.trim().length > 0), // 生成消息 fc.string({ minLength: 1, maxLength: 500 }).filter(s => s.trim().length > 0), // 生成组件名称 fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), async (id, level, title, message, component) => { const initialStats = service.getStats(); const initialTotal = initialStats.alerts.total; const initialByLevel = initialStats.alerts.byLevel[level]; const alertHandler = jest.fn(); service.on('alert', alertHandler); service.sendAlert({ id, level, title, message, component, timestamp: new Date(), }); const newStats = service.getStats(); // 验证总数增加 expect(newStats.alerts.total).toBe(initialTotal + 1); // 验证级别计数增加 expect(newStats.alerts.byLevel[level]).toBe(initialByLevel + 1); // 验证事件被发出 expect(alertHandler).toHaveBeenCalled(); service.removeListener('alert', alertHandler); } ), { numRuns: 100 } ); }, 30000); /** * 属性: 健康检查应该返回完整的状态信息 */ it('健康检查应该返回完整的状态信息', async () => { await fc.assert( fc.asyncProperty( // 生成一些连接事件 fc.integer({ min: 0, max: 10 }), // 生成一些API调用 fc.integer({ min: 0, max: 10 }), async (connectionCount, apiCallCount) => { // 模拟一些活动 for (let i = 0; i < connectionCount; i++) { service.logConnection({ socketId: `socket-${i}`, eventType: ConnectionEventType.CONNECTED, timestamp: new Date(), }); } for (let i = 0; i < apiCallCount; i++) { service.logApiCall({ operation: `operation-${i}`, userId: `user-${i}`, result: ApiCallResult.SUCCESS, responseTime: 100, timestamp: new Date(), }); } const health = await service.checkSystemHealth(); // 验证健康状态结构 expect(health).toBeDefined(); expect(health.status).toBeDefined(); expect(['healthy', 'degraded', 'unhealthy']).toContain(health.status); expect(health.components).toBeDefined(); expect(health.components.websocket).toBeDefined(); expect(health.components.zulipApi).toBeDefined(); expect(health.components.redis).toBeDefined(); expect(health.components.memory).toBeDefined(); expect(health.timestamp).toBeInstanceOf(Date); } ), { numRuns: 50 } ); }, 30000); /** * 属性: 最近告警列表应该正确维护 */ it('最近告警列表应该正确维护', async () => { await fc.assert( fc.asyncProperty( // 生成告警数量 fc.integer({ min: 1, max: 20 }), // 生成请求数量 fc.integer({ min: 1, max: 15 }), async (alertCount, requestLimit) => { // 重置统计以确保干净的状态 service.resetStats(); // 发送多个告警 for (let i = 0; i < alertCount; i++) { service.sendAlert({ id: `alert-${i}`, level: AlertLevel.INFO, title: `Alert ${i}`, message: `Message ${i}`, component: 'test', timestamp: new Date(), }); } const recentAlerts = service.getRecentAlerts(requestLimit); // 验证返回数量不超过请求数量 expect(recentAlerts.length).toBeLessThanOrEqual(requestLimit); // 验证返回数量不超过实际告警数量(在本次测试中发送的) expect(recentAlerts.length).toBeLessThanOrEqual(Math.min(alertCount, requestLimit)); // 验证每个告警都有必要的字段 for (const alert of recentAlerts) { expect(alert.id).toBeDefined(); expect(alert.level).toBeDefined(); expect(alert.title).toBeDefined(); expect(alert.message).toBeDefined(); expect(alert.component).toBeDefined(); expect(alert.timestamp).toBeInstanceOf(Date); } } ), { numRuns: 50 } ); }, 30000); /** * 属性: 统计数据应该保持一致性 */ it('统计数据应该保持一致性', async () => { await fc.assert( fc.asyncProperty( // 生成成功API调用数 fc.integer({ min: 0, max: 50 }), // 生成失败API调用数 fc.integer({ min: 0, max: 50 }), async (successCount, failureCount) => { // 重置统计以确保干净的状态 service.resetStats(); // 记录成功的API调用 for (let i = 0; i < successCount; i++) { service.logApiCall({ operation: 'test', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 100, timestamp: new Date(), }); } // 记录失败的API调用 for (let i = 0; i < failureCount; i++) { service.logApiCall({ operation: 'test', userId: 'user1', result: ApiCallResult.FAILURE, responseTime: 100, timestamp: new Date(), }); } const stats = service.getStats(); // 验证总数等于成功数加失败数 expect(stats.apiCalls.total).toBe(successCount + failureCount); expect(stats.apiCalls.success).toBe(successCount); expect(stats.apiCalls.failures).toBe(failureCount); } ), { numRuns: 50 } ); }, 30000); }); // ==================== 补充测试用例 ==================== describe('边界条件和错误处理测试', () => { it('应该正确处理活跃连接数不会变成负数', () => { // 先断开一个不存在的连接 service.logConnection({ socketId: 'socket1', eventType: ConnectionEventType.DISCONNECTED, timestamp: new Date(), }); const stats = service.getStats(); expect(stats.connections.active).toBe(0); // 不应该是负数 }); it('应该正确处理空的最近告警列表', () => { const alerts = service.getRecentAlerts(5); expect(alerts).toEqual([]); }); it('应该正确处理超出限制的最近告警请求', () => { // 添加一些告警 for (let i = 0; i < 5; i++) { service.sendAlert({ id: `alert-${i}`, level: AlertLevel.INFO, title: `Alert ${i}`, message: `Message ${i}`, component: 'test', timestamp: new Date(), }); } // 请求超过实际数量的告警 const alerts = service.getRecentAlerts(10); expect(alerts.length).toBe(5); }); it('应该正确处理零除法情况', () => { // 在没有任何API调用时获取统计 const stats = service.getStats(); expect(stats.apiCalls.avgResponseTime).toBe(0); // 应该是0而不是NaN }); it('应该正确处理消息延迟统计的零除法', () => { // 在没有任何消息时获取统计 const stats = service.getStats(); expect(stats.messages.avgLatency).toBe(0); // 应该是0而不是NaN }); it('应该正确处理不同级别的告警日志', () => { const logSpy = jest.spyOn(Logger.prototype, 'log'); const warnSpy = jest.spyOn(Logger.prototype, 'warn'); const errorSpy = jest.spyOn(Logger.prototype, 'error'); // INFO级别 service.sendAlert({ id: 'info-alert', level: AlertLevel.INFO, title: 'Info Alert', message: 'Info message', component: 'test', timestamp: new Date(), }); // WARNING级别 service.sendAlert({ id: 'warn-alert', level: AlertLevel.WARNING, title: 'Warning Alert', message: 'Warning message', component: 'test', timestamp: new Date(), }); // ERROR级别 service.sendAlert({ id: 'error-alert', level: AlertLevel.ERROR, title: 'Error Alert', message: 'Error message', component: 'test', timestamp: new Date(), }); // CRITICAL级别 service.sendAlert({ id: 'critical-alert', level: AlertLevel.CRITICAL, title: 'Critical Alert', message: 'Critical message', component: 'test', timestamp: new Date(), }); expect(logSpy).toHaveBeenCalled(); // INFO expect(warnSpy).toHaveBeenCalled(); // WARNING expect(errorSpy).toHaveBeenCalledTimes(2); // ERROR + CRITICAL }); it('应该正确处理健康检查中的降级状态', async () => { // 先添加一些正常连接 for (let i = 0; i < 10; i++) { service.logConnection({ socketId: `socket-normal-${i}`, eventType: ConnectionEventType.CONNECTED, timestamp: new Date(), }); } // 然后添加一些错误来触发降级状态 for (let i = 0; i < 5; i++) { service.logConnection({ socketId: `socket-error-${i}`, eventType: ConnectionEventType.ERROR, timestamp: new Date(), }); } const health = await service.checkSystemHealth(); // 错误率应该是 5/10 = 50%,超过阈值 10%,应该是不健康状态 expect(health.components.websocket.status).toMatch(/^(degraded|unhealthy)$/); }); it('应该正确处理API调用的降级状态', async () => { // 先添加一些成功的API调用 for (let i = 0; i < 10; i++) { service.logApiCall({ operation: 'test', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 100, timestamp: new Date(), }); } // 然后模拟大量失败的API调用 for (let i = 0; i < 5; i++) { service.logApiCall({ operation: 'test', userId: 'user1', result: ApiCallResult.FAILURE, responseTime: 100, timestamp: new Date(), }); } const health = await service.checkSystemHealth(); // 错误率应该是 5/15 = 33%,超过阈值 10%,应该是不健康状态 expect(health.components.zulipApi.status).toMatch(/^(degraded|unhealthy)$/); }); it('应该正确处理慢API调用的降级状态', async () => { // 模拟慢API调用 for (let i = 0; i < 10; i++) { service.logApiCall({ operation: 'test', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 15000, // 超过阈值 timestamp: new Date(), }); } const health = await service.checkSystemHealth(); // 应该检测到API组件降级 expect(health.components.zulipApi.status).toMatch(/^(degraded|unhealthy)$/); }); it('应该正确处理模块生命周期', () => { // 测试模块初始化 service.onModuleInit(); // 验证健康检查已启动(通过检查私有属性) expect((service as any).healthCheckInterval).toBeDefined(); // 测试模块销毁 service.onModuleDestroy(); // 验证健康检查已停止 expect((service as any).healthCheckInterval).toBeNull(); }); it('应该正确处理最近日志的大小限制', () => { const maxLogs = (service as any).maxRecentLogs; // 添加超过限制的API调用日志 for (let i = 0; i < maxLogs + 10; i++) { service.logApiCall({ operation: `test-${i}`, userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 100, timestamp: new Date(), }); } // 验证最近日志数量不超过限制 const recentLogs = (service as any).recentApiCalls; expect(recentLogs.length).toBeLessThanOrEqual(maxLogs); }); it('应该正确处理最近告警的大小限制', () => { const maxLogs = (service as any).maxRecentLogs; // 添加超过限制的告警 for (let i = 0; i < maxLogs + 10; i++) { service.sendAlert({ id: `alert-${i}`, level: AlertLevel.INFO, title: `Alert ${i}`, message: `Message ${i}`, component: 'test', timestamp: new Date(), }); } // 验证最近告警数量不超过限制 const recentAlerts = (service as any).recentAlerts; expect(recentAlerts.length).toBeLessThanOrEqual(maxLogs); }); it('应该正确处理消息转发错误统计', () => { service.logMessageForward({ fromUserId: 'user1', toUserIds: ['user2'], stream: 'test-stream', topic: 'test-topic', direction: 'upstream', success: false, // 失败的消息 latency: 100, error: 'Transfer failed', timestamp: new Date(), }); const stats = service.getStats(); expect(stats.messages.errors).toBe(1); }); it('应该正确处理带有元数据的连接日志', () => { const eventHandler = jest.fn(); service.on('connection_event', eventHandler); service.logConnection({ socketId: 'socket1', userId: 'user1', eventType: ConnectionEventType.CONNECTED, duration: 1000, timestamp: new Date(), metadata: { userAgent: 'test-agent', ip: '127.0.0.1' }, }); expect(eventHandler).toHaveBeenCalledWith( expect.objectContaining({ metadata: { userAgent: 'test-agent', ip: '127.0.0.1' }, }) ); service.removeListener('connection_event', eventHandler); }); it('应该正确处理带有元数据的API调用日志', () => { const eventHandler = jest.fn(); service.on('api_call', eventHandler); service.logApiCall({ operation: 'sendMessage', userId: 'user1', result: ApiCallResult.SUCCESS, responseTime: 100, statusCode: 200, timestamp: new Date(), metadata: { endpoint: '/api/messages', method: 'POST' }, }); expect(eventHandler).toHaveBeenCalledWith( expect.objectContaining({ metadata: { endpoint: '/api/messages', method: 'POST' }, }) ); service.removeListener('api_call', eventHandler); }); it('应该正确处理带有消息ID的消息转发日志', () => { const eventHandler = jest.fn(); service.on('message_forward', eventHandler); service.logMessageForward({ messageId: 12345, fromUserId: 'user1', toUserIds: ['user2', 'user3'], stream: 'test-stream', topic: 'test-topic', direction: 'downstream', success: true, latency: 50, timestamp: new Date(), }); expect(eventHandler).toHaveBeenCalledWith( expect.objectContaining({ messageId: 12345, }) ); service.removeListener('message_forward', eventHandler); }); it('应该正确处理带有详情的操作确认', () => { const eventHandler = jest.fn(); service.on('operation_confirmed', eventHandler); service.confirmOperation({ operationId: 'op123', operation: 'sendMessage', userId: 'user1', success: true, timestamp: new Date(), details: { messageId: 456, recipients: 3 }, }); expect(eventHandler).toHaveBeenCalledWith( expect.objectContaining({ details: { messageId: 456, recipients: 3 }, }) ); service.removeListener('operation_confirmed', eventHandler); }); it('应该正确处理带有元数据的告警', () => { const eventHandler = jest.fn(); service.on('alert', eventHandler); service.sendAlert({ id: 'alert123', level: AlertLevel.WARNING, title: 'Test Alert', message: 'Test message', component: 'test-component', timestamp: new Date(), metadata: { threshold: 5000, actual: 7000 }, }); expect(eventHandler).toHaveBeenCalledWith( expect.objectContaining({ metadata: { threshold: 5000, actual: 7000 }, }) ); service.removeListener('alert', eventHandler); }); }); });