energy-manager-iot
Version:
Library for energy management in IoT devices via MQTT protocol. Documentation: https://jonhvmp.github.io/energy-manager-iot-docs/
169 lines (168 loc) • 6.95 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const mqtt_handler_1 = require("../lib/mqtt-handler");
const mqtt = __importStar(require("mqtt"));
const error_handler_1 = require("../utils/error-handler");
/**
* Main tests for the MqttHandler class
*
* This test suite covers the core functionality of the MQTT handler,
* including connection management, message publication and subscription.
*/
// Use global MQTT mock, without trying to redefine
jest.mock('mqtt');
describe('MqttHandler', () => {
let mqttHandler;
let mockClient;
let mockHandlers;
beforeEach(() => {
jest.clearAllMocks();
// Create handlers for events
mockHandlers = {
connect: jest.fn(),
message: jest.fn(),
error: jest.fn(),
reconnect: jest.fn(),
offline: jest.fn()
};
// Create a mock client
mockClient = {
on: jest.fn(),
publish: jest.fn(),
subscribe: jest.fn(),
end: jest.fn()
};
// Add implementation for subscribe to invoke callback immediately
mockClient.subscribe.mockImplementation((topic, opts, cb) => {
cb(null);
return mockClient;
});
mqtt.connect.mockReturnValue(mockClient);
// Configure client to use our handlers
mockClient.on.mockImplementation((event, callback) => {
mockHandlers[event] = callback;
return mockClient;
});
mqttHandler = new mqtt_handler_1.MqttHandler({
clientId: 'test-client',
// Settings to avoid timeouts
connectTimeout: 1,
reconnectPeriod: 0
});
});
afterEach(() => {
if (mqttHandler) {
mqttHandler.removeAllListeners();
}
jest.clearAllMocks();
});
describe('Connection', () => {
test('should throw error with invalid URL', async () => {
await expect(mqttHandler.connect('invalid-url')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
test('should connect successfully and emit event', async () => {
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
// Simulate connection event
const connectListener = jest.fn();
mqttHandler.on('connect', connectListener);
// Trigger connect callback
mockHandlers.connect();
await connectPromise;
expect(connectListener).toHaveBeenCalled();
expect(mqttHandler.isClientConnected()).toBe(true);
});
test('should emit error event on connection error', async () => {
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
const errorListener = jest.fn();
mqttHandler.on('error', errorListener);
// Simulate error
const error = new Error('Connection refused');
mockHandlers.error(error);
await expect(connectPromise).rejects.toThrow(error_handler_1.EnergyManagerError);
expect(errorListener).toHaveBeenCalledWith(error);
});
});
describe('Publication and Subscription', () => {
test('should fail to publish when disconnected', async () => {
await expect(mqttHandler.publish('test/topic', 'message')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
test('should process received messages', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
mockHandlers.connect();
await connectPromise;
// Set up listener for messages
const messageListener = jest.fn();
mqttHandler.on('message', messageListener);
// Subscribe to topic with callback
const topicCallback = jest.fn();
await mqttHandler.subscribe('test/topic', topicCallback);
// Simulate message reception
const message = Buffer.from('test message');
mockHandlers.message('test/topic', message);
// Verify both callbacks were called
expect(messageListener).toHaveBeenCalledWith('test/topic', message);
expect(topicCallback).toHaveBeenCalledWith('test/topic', message);
});
});
describe('Disconnection and Reconnection', () => {
test('should handle disconnection', async () => {
// Connect
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
mockHandlers.connect();
await connectPromise;
// Set up listener for offline
const offlineListener = jest.fn();
mqttHandler.on('offline', offlineListener);
// Simulate offline
mockHandlers.offline();
expect(offlineListener).toHaveBeenCalled();
expect(mqttHandler.isClientConnected()).toBe(false);
});
test('should emit event on reconnection', async () => {
// Connect
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
mockHandlers.connect();
await connectPromise;
// Set up listener for reconnection
const reconnectListener = jest.fn();
mqttHandler.on('reconnect', reconnectListener);
// Simulate reconnection
mockHandlers.reconnect();
expect(reconnectListener).toHaveBeenCalled();
});
});
});