energy-manager-iot
Version:
Library for energy management in IoT devices via MQTT protocol. Documentation: https://jonhvmp.github.io/energy-manager-iot-docs/
164 lines (163 loc) • 7.13 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");
// Use global mock, without redefining
jest.mock('mqtt');
/**
* Advanced tests for the MqttHandler class
*
* These tests focus on edge cases and error handling in the MQTT handler,
* particularly around publishing, subscribing, and connection failures.
*/
describe('MqttHandler - Advanced Tests', () => {
let mqttHandler;
let mockClient;
let callbacks = {};
beforeEach(() => {
jest.clearAllMocks();
callbacks = {};
// Get the existing mock client from global mock
const mockImplementation = mqtt.connect.getMockImplementation();
mockClient = mockImplementation ? mockImplementation() : {};
// Override mockClient.on implementation for this test
mockClient.on.mockImplementation((event, callback) => {
callbacks[event] = callback;
return mockClient;
});
mqttHandler = new mqtt_handler_1.MqttHandler({
clientId: 'test-client',
username: 'user',
password: 'pass',
clean: true
});
});
afterEach(() => {
if (mqttHandler) {
mqttHandler.removeAllListeners();
}
});
describe('Publication Errors', () => {
test('should reject when publication fails', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
callbacks['connect'] && callbacks['connect'](); // Simulate connect event
await connectPromise;
// Mock publication error
mockClient.publish.mockImplementationOnce((_topic, _message, _opts, cb) => {
if (cb)
cb(new Error('Publish failed'));
});
// Try to publish
await expect(mqttHandler.publish('test/topic', 'message')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
test('should reject when subscription fails', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
callbacks['connect'] && callbacks['connect']();
await connectPromise;
// Mock subscription error
mockClient.subscribe.mockImplementationOnce((_topic, _opts, cb) => {
if (cb)
cb(new Error('Subscribe failed'));
});
// Try to subscribe
await expect(mqttHandler.subscribe('test/topic')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
test('should reject when unsubscription fails', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
callbacks['connect'] && callbacks['connect']();
await connectPromise;
// Mock unsubscription error
mockClient.unsubscribe.mockImplementationOnce((_topic, cb) => {
if (cb)
cb(new Error('Unsubscribe failed'));
});
// Try to unsubscribe
await expect(mqttHandler.unsubscribe('test/topic')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
});
describe('Initialization Exceptions', () => {
test('should handle exceptions when creating MQTT client', async () => {
// Simulate exception error during connection
jest.spyOn(mqtt, 'connect').mockImplementationOnce(() => {
throw new Error('Connection setup failed');
});
// Try to connect
await expect(mqttHandler.connect('mqtt://localhost:1883')).rejects.toThrow(error_handler_1.EnergyManagerError);
});
test('should handle disconnection when client is already disconnected', async () => {
// Client not initialized
const result = await mqttHandler.disconnect();
expect(result).toBeUndefined();
});
test('should reject when disconnection fails', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
callbacks['connect'] && callbacks['connect']();
await connectPromise;
// Mock disconnection error
mockClient.end.mockImplementationOnce((force, opts, cb) => {
cb(new Error('Disconnect failed'));
});
// Try to disconnect
await expect(mqttHandler.disconnect()).rejects.toThrow(error_handler_1.EnergyManagerError);
});
});
describe('Message Handling', () => {
test('should handle errors in topic callbacks', async () => {
// Connect first
const connectPromise = mqttHandler.connect('mqtt://localhost:1883');
callbacks['connect'] && callbacks['connect']();
await connectPromise;
// Register callback with error
const errorCallback = jest.fn(() => {
throw new Error('Callback error');
});
await mqttHandler.subscribe('test/error', errorCallback);
// Should not throw error even with callback failure
const message = Buffer.from('test');
// Simulate message reception
expect(() => {
callbacks['message'] && callbacks['message']('test/error', message);
}).not.toThrow();
// Callback should have been called
expect(errorCallback).toHaveBeenCalled();
});
});
});