farmcontrol-ws/src/events/__tests__/eventmanager.test.js

135 lines
3.7 KiB
JavaScript

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