All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
216 lines
5.9 KiB
JavaScript
216 lines
5.9 KiB
JavaScript
import { jest } from '@jest/globals';
|
|
|
|
// Mock dependencies
|
|
jest.unstable_mockModule('../../config.js', () => ({
|
|
loadConfig: jest.fn(() => ({
|
|
server: { logLevel: 'info' }
|
|
}))
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../auth/auth.js', () => ({
|
|
CodeAuth: jest.fn().mockImplementation(() => ({
|
|
verifyCode: jest.fn(),
|
|
verifyOtp: jest.fn()
|
|
})),
|
|
createAuthMiddleware: jest.fn(() => (socket, next) => next())
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../database/database.js', () => ({
|
|
newObject: jest.fn(),
|
|
editObject: jest.fn(),
|
|
getObject: jest.fn(),
|
|
listObjects: jest.fn()
|
|
}));
|
|
|
|
jest.unstable_mockModule(
|
|
'../../database/schemas/management/host.schema.js',
|
|
() => ({
|
|
hostModel: { modelName: 'host' }
|
|
})
|
|
);
|
|
|
|
jest.unstable_mockModule('../../updates/updatemanager.js', () => ({
|
|
UpdateManager: jest.fn().mockImplementation(() => ({
|
|
subscribeToObjectUpdate: jest.fn(),
|
|
unsubscribeToObjectUpdate: jest.fn()
|
|
}))
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../actions/actionmanager.js', () => ({
|
|
ActionManager: jest.fn().mockImplementation(() => ({
|
|
subscribeToObjectActions: jest.fn(),
|
|
removeAllListeners: jest.fn()
|
|
}))
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../events/eventmanager.js', () => ({
|
|
EventManager: jest.fn().mockImplementation(() => ({
|
|
sendObjectEvent: jest.fn(),
|
|
subscribeToObjectEvent: jest.fn(),
|
|
removeObjectEventsListener: jest.fn(),
|
|
removeAllListeners: jest.fn()
|
|
}))
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../templates/templatemanager.js', () => ({
|
|
TemplateManager: jest.fn().mockImplementation(() => ({
|
|
renderPDF: jest.fn()
|
|
}))
|
|
}));
|
|
|
|
jest.unstable_mockModule('../../utils.js', () => ({
|
|
getModelByName: jest.fn(name => ({ modelName: name }))
|
|
}));
|
|
|
|
jest.unstable_mockModule('log4js', () => ({
|
|
default: {
|
|
getLogger: () => ({
|
|
level: 'info',
|
|
debug: jest.fn(),
|
|
error: jest.fn(),
|
|
warn: jest.fn(),
|
|
trace: jest.fn(),
|
|
info: jest.fn()
|
|
})
|
|
}
|
|
}));
|
|
|
|
const { SocketHost } = await import('../sockethost.js');
|
|
const { editObject, newObject, getObject, listObjects } = await import(
|
|
'../../database/database.js'
|
|
);
|
|
|
|
describe('SocketHost', () => {
|
|
let mockSocket;
|
|
let mockSocketManager;
|
|
let socketHost;
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
mockSocket = {
|
|
id: 'test-socket-id',
|
|
use: jest.fn(),
|
|
on: jest.fn(),
|
|
emit: jest.fn()
|
|
};
|
|
mockSocketManager = {};
|
|
socketHost = new SocketHost(mockSocket, mockSocketManager);
|
|
});
|
|
|
|
it('should initialize correctly and setup event handlers', () => {
|
|
expect(mockSocket.use).toHaveBeenCalled();
|
|
expect(mockSocket.on).toHaveBeenCalledWith(
|
|
'authenticate',
|
|
expect.any(Function)
|
|
);
|
|
expect(mockSocket.on).toHaveBeenCalledWith(
|
|
'disconnect',
|
|
expect.any(Function)
|
|
);
|
|
});
|
|
|
|
describe('handleAuthenticate', () => {
|
|
it('should authenticate with id and authCode', async () => {
|
|
const data = { id: 'host-1', authCode: 'code-123' };
|
|
const callback = jest.fn();
|
|
const mockHost = { _id: 'host-id-obj' };
|
|
|
|
socketHost.codeAuth.verifyCode.mockResolvedValue({
|
|
valid: true,
|
|
host: mockHost
|
|
});
|
|
editObject.mockResolvedValue({});
|
|
|
|
await socketHost.handleAuthenticate(data, callback);
|
|
|
|
expect(socketHost.codeAuth.verifyCode).toHaveBeenCalledWith(
|
|
'host-1',
|
|
'code-123'
|
|
);
|
|
expect(editObject).toHaveBeenCalled();
|
|
expect(callback).toHaveBeenCalledWith({ valid: true, host: mockHost });
|
|
expect(socketHost.authenticated).toBe(true);
|
|
});
|
|
|
|
it('should authenticate with otp', async () => {
|
|
const data = { otp: '123456' };
|
|
const callback = jest.fn();
|
|
const mockHost = { _id: 'host-id-obj' };
|
|
|
|
socketHost.codeAuth.verifyOtp.mockResolvedValue({
|
|
valid: true,
|
|
host: mockHost
|
|
});
|
|
editObject.mockResolvedValue({});
|
|
|
|
await socketHost.handleAuthenticate(data, callback);
|
|
|
|
expect(socketHost.codeAuth.verifyOtp).toHaveBeenCalledWith('123456');
|
|
expect(callback).toHaveBeenCalledWith({ valid: true, host: mockHost });
|
|
});
|
|
|
|
it('should return error if params are missing', async () => {
|
|
const data = {};
|
|
const callback = jest.fn();
|
|
|
|
await socketHost.handleAuthenticate(data, callback);
|
|
|
|
expect(callback).toHaveBeenCalledWith({
|
|
valid: false,
|
|
error: 'Missing params.'
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('database operations handlers', () => {
|
|
beforeEach(() => {
|
|
socketHost.host = { _id: 'host-id' };
|
|
});
|
|
|
|
it('handleNewObject should call newObject and callback', async () => {
|
|
const data = { objectType: 'printer', newData: { name: 'P1' } };
|
|
const callback = jest.fn();
|
|
newObject.mockResolvedValue({ _id: 'new-id' });
|
|
|
|
await socketHost.handleNewObject(data, callback);
|
|
|
|
expect(newObject).toHaveBeenCalled();
|
|
expect(callback).toHaveBeenCalledWith({ _id: 'new-id' });
|
|
});
|
|
|
|
it('handleEditObject should call editObject and callback', async () => {
|
|
const data = {
|
|
objectType: 'printer',
|
|
_id: 'p1',
|
|
updateData: { status: 'idle' }
|
|
};
|
|
const callback = jest.fn();
|
|
editObject.mockResolvedValue({ success: true });
|
|
|
|
await socketHost.handleEditObject(data, callback);
|
|
|
|
expect(editObject).toHaveBeenCalled();
|
|
expect(callback).toHaveBeenCalledWith({ success: true });
|
|
});
|
|
});
|
|
|
|
describe('handleDisconnect', () => {
|
|
it('should set host offline if authenticated', async () => {
|
|
socketHost.authenticated = true;
|
|
socketHost.id = 'host-id';
|
|
socketHost.host = { _id: 'host-id' };
|
|
listObjects.mockResolvedValue([]); // for setDevicesState
|
|
|
|
await socketHost.handleDisconnect();
|
|
|
|
expect(editObject).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
id: 'host-id',
|
|
updateData: expect.objectContaining({ online: false })
|
|
})
|
|
);
|
|
expect(socketHost.actionManager.removeAllListeners).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|