farmcontrol-ws/src/socket/__tests__/socketmanager.test.js

137 lines
3.5 KiB
JavaScript

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' });
});
});
});