import { jest } from '@jest/globals'; jest.unstable_mockModule('../../database/nats.js', () => ({ natsServer: { publish: jest.fn().mockResolvedValue({ success: true }), subscribe: jest.fn().mockResolvedValue({ success: true }), removeSubscription: jest.fn().mockResolvedValue({ success: true }) } })); jest.unstable_mockModule('log4js', () => ({ default: { getLogger: () => ({ level: 'info', debug: jest.fn(), error: jest.fn(), warn: jest.fn(), trace: jest.fn(), info: jest.fn() }) } })); jest.unstable_mockModule('../../config.js', () => ({ loadConfig: jest.fn(() => ({ server: { logLevel: 'info' } })) })); const { EventManager } = await import('../eventmanager.js'); const { natsServer } = await import('../../database/nats.js'); describe('EventManager', () => { let mockSocketClient; let eventManager; beforeEach(() => { jest.clearAllMocks(); mockSocketClient = { socketId: 'test-socket-id', socket: { emit: jest.fn() } }; eventManager = new EventManager(mockSocketClient); }); describe('subscribeToObjectEvent', () => { it('should subscribe to object events and emit when received', async () => { const id = 'obj-123'; const objectType = 'printer'; const eventType = 'status'; await eventManager.subscribeToObjectEvent(id, objectType, eventType); expect(natsServer.subscribe).toHaveBeenCalledWith( 'printers.obj-123.events.status', 'test-socket-id', expect.any(Function) ); // Simulate NATS message const natsCallback = natsServer.subscribe.mock.calls[0][2]; const eventData = { status: 'online' }; natsCallback('printers.obj-123.events.status', eventData); expect(mockSocketClient.socket.emit).toHaveBeenCalledWith('objectEvent', { _id: id, objectType: objectType, event: eventData }); }); }); describe('removeObjectEventsListener', () => { it('should remove specific subscription', async () => { const id = 'obj-123'; const objectType = 'printer'; const eventType = 'status'; await eventManager.subscribeToObjectEvent(id, objectType, eventType); await eventManager.removeObjectEventsListener(id, objectType, eventType); expect(natsServer.removeSubscription).toHaveBeenCalledWith( 'printers.obj-123.events.status', 'test-socket-id' ); expect(eventManager.subscriptions.size).toBe(0); }); }); describe('sendObjectEvent', () => { it('should publish event to NATS', async () => { const id = 'obj-123'; const objectType = 'printer'; const event = { type: 'alert', message: 'low filament' }; const result = await eventManager.sendObjectEvent(id, objectType, event); expect(result).toEqual({ success: true }); expect(natsServer.publish).toHaveBeenCalledWith( 'printers.obj-123.events.alert', event ); }); it('should handle errors when publishing fails', async () => { natsServer.publish.mockRejectedValueOnce(new Error('NATS error')); const result = await eventManager.sendObjectEvent('id', 'type', { type: 't' }); expect(result).toHaveProperty('error', 'NATS error'); }); }); describe('removeAllListeners', () => { it('should remove all subscriptions', async () => { await eventManager.subscribeToObjectEvent('1', 'printer', 'e1'); await eventManager.subscribeToObjectEvent('2', 'printer', 'e2'); await eventManager.removeAllListeners(); expect(natsServer.removeSubscription).toHaveBeenCalledTimes(2); expect(eventManager.subscriptions.size).toBe(0); }); }); });