import { jest } from '@jest/globals'; jest.unstable_mockModule('socket.io', () => ({ Server: jest.fn(() => ({ on: jest.fn(), emit: jest.fn(), })), })); jest.unstable_mockModule('../socketuser.js', () => ({ SocketUser: jest.fn((socket, manager) => ({ id: socket.id, socket, })), })); jest.unstable_mockModule('../sockethost.js', () => ({ SocketHost: jest.fn((socket, manager) => ({ id: socket.id, socket, })), })); 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('../../database/redis.js', () => ({ redisServer: { setKey: jest.fn().mockResolvedValue(undefined), getKey: jest.fn().mockResolvedValue(null), deleteKey: jest.fn().mockResolvedValue(undefined), getKeysByPattern: jest.fn().mockResolvedValue([]), connect: jest.fn().mockResolvedValue(undefined), disconnect: jest.fn().mockResolvedValue(undefined), }, })); jest.unstable_mockModule('../../lock/lockmanager.js', () => ({ LockManager: jest.fn(), })); jest.unstable_mockModule('../../templates/templatemanager.js', () => ({ TemplateManager: jest.fn(), })); jest.unstable_mockModule('../../config.js', () => ({ loadConfig: jest.fn(() => ({ server: { logLevel: 'info', corsOrigins: '*', }, })), })); jest.unstable_mockModule('log4js', () => ({ default: { getLogger: () => ({ level: 'info', debug: jest.fn(), error: jest.fn(), warn: jest.fn(), trace: jest.fn(), info: jest.fn(), }), }, })); const { SocketManager } = await import('../socketmanager.js'); const { Server } = await import('socket.io'); describe('SocketManager', () => { let mockServer; let socketManager; beforeEach(() => { jest.clearAllMocks(); mockServer = {}; socketManager = new SocketManager(mockServer); }); it('should initialize correctly', () => { expect(Server).toHaveBeenCalledWith(mockServer, expect.any(Object)); expect(socketManager.io.on).toHaveBeenCalledWith('connection', expect.any(Function)); }); describe('connection handling', () => { it('should add a user when auth type is user', async () => { const mockSocket = { id: 'user-socket', handshake: { auth: { type: 'user' } }, on: jest.fn(), }; const connectionHandler = socketManager.io.on.mock.calls[0][1]; await connectionHandler(mockSocket); expect(socketManager.socketUsers.has('user-socket')).toBe(true); }); it('should add a host when auth type is host', async () => { const mockSocket = { id: 'host-socket', handshake: { auth: { type: 'host' } }, on: jest.fn(), }; const connectionHandler = socketManager.io.on.mock.calls[0][1]; await connectionHandler(mockSocket); expect(socketManager.socketHosts.has('host-socket')).toBe(true); }); }); describe('sendToUser', () => { it('should emit event to all matching user connections', () => { const mockUserSocket = { id: 's1', emit: jest.fn(), }; socketManager.socketUsers.set('s1', { user: { _id: 'u1' }, socket: mockUserSocket, }); socketManager.sendToUser('u1', 'testEvent', { data: 'ok' }); expect(mockUserSocket.emit).toHaveBeenCalledWith('testEvent', { data: 'ok' }); }); }); });