UNPKG

energy-manager-iot

Version:

Library for energy management in IoT devices via MQTT protocol. Documentation: https://jonhvmp.github.io/energy-manager-iot-docs/

233 lines (232 loc) 10.4 kB
"use strict"; 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 index_1 = require("../index"); const mqtt = __importStar(require("mqtt")); /** * Main tests for the EnergyManager class * * This test suite covers the core functionality of the EnergyManager, * including device management, group operations, and MQTT communication. */ // Mock MQTT client jest.mock('mqtt', () => { const mockClient = { on: jest.fn(), end: jest.fn((force, opts, cb) => cb()), publish: jest.fn((topic, message, opts, cb) => cb()), subscribe: jest.fn((topic, opts, cb) => cb()), unsubscribe: jest.fn((topic, cb) => cb()), removeAllListeners: jest.fn() }; return { connect: jest.fn().mockReturnValue(mockClient) }; }); describe('EnergyManager', () => { let energyManager; let mockMqttClient; beforeEach(() => { jest.clearAllMocks(); energyManager = new index_1.EnergyManager({ topicPrefix: 'test/devices/', statusInterval: 1000 }); mockMqttClient = mqtt.connect('mqtt://localhost:1883'); }); // Clean up resources after each test afterEach(async () => { // Stop status check if (energyManager['statusCheckInterval']) { clearInterval(energyManager['statusCheckInterval']); energyManager['statusCheckInterval'] = undefined; } // Remove all listeners to prevent memory leaks energyManager.removeAllListeners(); // Ensure MQTT client was terminated if (mockMqttClient.removeAllListeners) { mockMqttClient.removeAllListeners(); } }); // Clean up all resources after all tests afterAll(() => { jest.restoreAllMocks(); }); describe('Initialization', () => { test('should create instance with default properties', () => { expect(energyManager).toBeDefined(); expect(energyManager.isConnected()).toBe(false); }); test('should use custom topic prefix', () => { energyManager.setTopicPrefix('custom/prefix/'); // Register a device to test the prefix energyManager.registerDevice('test-device', 'Test Device', index_1.DeviceType.SENSOR); // Simulate connection Object.defineProperty(energyManager, 'mqtt', { value: { isClientConnected: () => true } }); // Verify prefix is used expect(energyManager['topicPrefix']).toBe('custom/prefix/'); }); }); describe('Device Management', () => { test('should register and retrieve devices', () => { const device = energyManager.registerDevice('sensor1', 'Temperature Sensor', index_1.DeviceType.SENSOR, { reportingInterval: 60 }); expect(device).toBeDefined(); expect(device.id).toBe('sensor1'); expect(device.name).toBe('Temperature Sensor'); expect(device.type).toBe(index_1.DeviceType.SENSOR); expect(device.config.reportingInterval).toBe(60); const retrievedDevice = energyManager.getDevice('sensor1'); expect(retrievedDevice).toEqual(device); }); test('should update devices', () => { energyManager.registerDevice('sensor1', 'Temperature Sensor', index_1.DeviceType.SENSOR); const updatedDevice = energyManager.updateDevice('sensor1', { name: 'Updated Sensor', config: { reportingInterval: 120 } }); expect(updatedDevice.name).toBe('Updated Sensor'); expect(updatedDevice.config.reportingInterval).toBe(120); }); test('should remove devices', () => { energyManager.registerDevice('sensor1', 'Temperature Sensor', index_1.DeviceType.SENSOR); const removed = energyManager.removeDevice('sensor1'); expect(removed).toBe(true); // Verify device no longer exists expect(() => energyManager.getDevice('sensor1')).toThrow(); }); }); describe('Group Management', () => { beforeEach(() => { energyManager.registerDevice('sensor1', 'Temperature Sensor', index_1.DeviceType.SENSOR); energyManager.registerDevice('sensor2', 'Humidity Sensor', index_1.DeviceType.SENSOR); }); test('should create groups', () => { const created = energyManager.createGroup('bedroom'); expect(created).toBe(true); const groups = energyManager.getAllGroups(); expect(groups).toContain('bedroom'); }); test('should add devices to groups', () => { energyManager.createGroup('bedroom'); const added = energyManager.addDeviceToGroup('sensor1', 'bedroom'); expect(added).toBe(true); const devices = energyManager.getDevicesInGroup('bedroom'); expect(devices.length).toBe(1); expect(devices[0].id).toBe('sensor1'); // Verify group is in device const device = energyManager.getDevice('sensor1'); expect(device.groups).toContain('bedroom'); }); test('should remove devices from groups', () => { energyManager.createGroup('bedroom'); energyManager.addDeviceToGroup('sensor1', 'bedroom'); const removed = energyManager.removeDeviceFromGroup('sensor1', 'bedroom'); expect(removed).toBe(true); const devices = energyManager.getDevicesInGroup('bedroom'); expect(devices.length).toBe(0); // Verify group was removed from device const device = energyManager.getDevice('sensor1'); expect(device.groups).not.toContain('bedroom'); }); test('should calculate group statistics', () => { // Add simulated status to devices const device1 = energyManager.getDevice('sensor1'); const device2 = energyManager.getDevice('sensor2'); // @ts-ignore - Accessing private method for test energyManager.registry.updateDeviceStatus('sensor1', { deviceId: 'sensor1', batteryLevel: 80, powerMode: index_1.PowerMode.NORMAL, connectionStatus: index_1.ConnectionStatus.ONLINE, lastSeen: Date.now() }); // @ts-ignore - Accessing private method for test energyManager.registry.updateDeviceStatus('sensor2', { deviceId: 'sensor2', batteryLevel: 60, powerMode: index_1.PowerMode.LOW_POWER, connectionStatus: index_1.ConnectionStatus.ONLINE, lastSeen: Date.now() }); // Create group with both sensors energyManager.createGroup('sensors'); energyManager.addDeviceToGroup('sensor1', 'sensors'); energyManager.addDeviceToGroup('sensor2', 'sensors'); // Calculate statistics const stats = energyManager.getGroupStatistics('sensors'); // Verify statistics expect(stats.totalDevices).toBe(2); expect(stats.averageBatteryLevel).toBe(70); // (80 + 60) / 2 expect(stats.onlineCount).toBe(2); expect(stats.powerModeDistribution[index_1.PowerMode.NORMAL]).toBe(1); expect(stats.powerModeDistribution[index_1.PowerMode.LOW_POWER]).toBe(1); }); }); // Basic MQTT connection simulation describe('MQTT Connection', () => { test('should connect to MQTT broker', async () => { // Set up mock events let connectCallback; mockMqttClient.on.mockImplementation((event, callback) => { if (event === 'connect') { connectCallback = callback; } return mockMqttClient; // Return client to allow chaining }); // Start connection const connectPromise = energyManager.connect('mqtt://localhost'); // Ensure callback was defined expect(connectCallback).toBeDefined(); // Simulate successful connect event if (connectCallback) { connectCallback(); } await connectPromise; expect(mqtt.connect).toHaveBeenCalledWith('mqtt://localhost', expect.any(Object)); }); // New test for disconnection test('should disconnect from MQTT broker', async () => { // Simulate connected state Object.defineProperty(energyManager['mqtt'], 'isConnected', { value: true }); // Spy on MQTT handler's disconnect method const disconnectSpy = jest.spyOn(energyManager['mqtt'], 'disconnect') .mockResolvedValue(); await energyManager.disconnect(); expect(disconnectSpy).toHaveBeenCalled(); }); }); });