UNPKG

homebridge-tsvesync

Version:

Homebridge plugin for VeSync devices including Levoit air purifiers, humidifiers, and Etekcity smart outlets

427 lines 14.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMockBulb = exports.createMockFan = exports.createMockLight = exports.createMockSwitch = exports.createMockVeSync = exports.createMockOutlet = exports.simulateNetworkDelay = exports.runAsyncTest = exports.flushPromises = exports.createMockDevice = exports.createMockInfoService = exports.createMockService = exports.createMockRetryManager = exports.createMockPluginLogger = exports.createMockLogger = void 0; const logger_1 = require("../../utils/logger"); const retry_1 = require("../../utils/retry"); /** * Creates a mock Logger instance for testing */ const createMockLogger = () => ({ debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn(), log: jest.fn(), prefix: undefined }); exports.createMockLogger = createMockLogger; /** * Creates a mock PluginLogger instance for testing */ const createMockPluginLogger = (log = (0, exports.createMockLogger)()) => { const logger = new logger_1.PluginLogger(log, true); return { ...logger, debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn(), stateChange: jest.fn(), operationStart: jest.fn(), operationEnd: jest.fn(), pollingEvent: jest.fn(), formatMessage: jest.fn((message) => message), }; }; exports.createMockPluginLogger = createMockPluginLogger; /** * Creates a mock RetryManager instance for testing */ const createMockRetryManager = () => { const manager = new retry_1.RetryManager((0, exports.createMockLogger)(), { maxRetries: 3, }); return { ...manager, execute: jest.fn(), getRetryCount: jest.fn().mockReturnValue(0), }; }; exports.createMockRetryManager = createMockRetryManager; /** * Creates a mock service instance for testing */ const createMockService = () => ({ getCharacteristic: jest.fn().mockReturnValue({ onSet: jest.fn(), onGet: jest.fn(), updateValue: jest.fn(), }), setCharacteristic: jest.fn().mockReturnThis(), }); exports.createMockService = createMockService; /** * Creates a mock info service instance for testing */ const createMockInfoService = () => ({ setCharacteristic: jest.fn().mockReturnThis(), }); exports.createMockInfoService = createMockInfoService; /** * Creates a mock device instance for testing */ const createMockDevice = (config = {}) => ({ deviceName: config.deviceName || 'Test Device', uuid: config.uuid || '12345', deviceType: config.deviceType || 'outlet', getDetails: config.getDetails || jest.fn(), }); exports.createMockDevice = createMockDevice; /** * Waits for all promises in the queue to resolve */ const flushPromises = () => new Promise(resolve => setImmediate(resolve)); exports.flushPromises = flushPromises; /** * Helper to run async tests with proper timeout and error handling */ const runAsyncTest = async (testFn, timeout = 5000) => { return new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { reject(new Error(`Test timed out after ${timeout}ms`)); }, timeout); testFn() .then(() => { clearTimeout(timeoutId); resolve(); }) .catch((error) => { clearTimeout(timeoutId); reject(error); }); }); }; exports.runAsyncTest = runAsyncTest; /** * Simulates a network delay */ const simulateNetworkDelay = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms)); exports.simulateNetworkDelay = simulateNetworkDelay; /** * Creates a mock outlet instance for testing */ const createMockOutlet = (config = {}) => { const details = { power: config.power || 0, voltage: config.voltage || 120, energy: config.energy || 0, current: config.current || 0, }; return { deviceName: config.deviceName || 'Test Outlet', deviceType: config.deviceType || 'wifi-switch-1.3', cid: config.cid || 'test-cid', uuid: config.uuid || 'test-uuid', deviceStatus: 'on', subDeviceNo: 0, isSubDevice: false, deviceRegion: 'US', configModule: 'Outlet', macId: '00:11:22:33:44:55', deviceCategory: 'outlet', connectionStatus: 'online', getDetails: jest.fn().mockResolvedValue(details), setApiBaseUrl: jest.fn(), turnOn: jest.fn().mockResolvedValue(true), turnOff: jest.fn().mockResolvedValue(true), ...details, }; }; exports.createMockOutlet = createMockOutlet; /** * Creates a mock VeSync client for testing */ const createMockVeSync = () => { return { login: jest.fn().mockResolvedValue(true), getDevices: jest.fn().mockResolvedValue(true), fans: [], outlets: [], switches: [], bulbs: [], humidifiers: [], purifiers: [], _debug: false, _redact: false, _energyUpdateInterval: 0, _energyCheck: false, username: 'test@example.com', password: 'test-password', token: 'test-token', accountID: 'test-account', apiKey: 'test-key', apiBase: 'test-base', timezone: 'UTC', debug: false, redact: false, traceSocket: false, apiUrl: 'test-url', initialized: true, setToken: jest.fn(), setAccountID: jest.fn(), setAPIKey: jest.fn(), setAPIBase: jest.fn(), setInitialized: jest.fn(), setDevices: jest.fn(), getDevicesByType: jest.fn(), getDeviceByUUID: jest.fn(), getDeviceByCid: jest.fn(), getDeviceByName: jest.fn(), getDevicesByCategory: jest.fn(), getDevicesByMacID: jest.fn(), getDevicesByDeviceType: jest.fn(), getDevicesByConfigModule: jest.fn(), getDevicesByDeviceRegion: jest.fn(), getDevicesByConnectionStatus: jest.fn(), }; }; exports.createMockVeSync = createMockVeSync; /** * Creates a mock switch instance for testing */ const createMockSwitch = (config = {}) => { const state = { power: config.power || false, deviceStatus: config.power ? 'on' : 'off', }; const mockSwitch = { deviceName: config.deviceName || 'Test Switch', deviceType: config.deviceType || 'ESW01-EU', cid: config.cid || 'test-cid', uuid: config.uuid || 'test-uuid', deviceStatus: state.deviceStatus, power: state.power, subDeviceNo: 0, isSubDevice: false, deviceRegion: 'US', configModule: 'Switch', macId: '00:11:22:33:44:55', deviceCategory: 'switch', connectionStatus: 'online', getDetails: jest.fn().mockImplementation(async () => { return { deviceStatus: state.deviceStatus, power: state.power, }; }), setApiBaseUrl: jest.fn(), turnOn: jest.fn().mockImplementation(async () => { state.power = true; state.deviceStatus = 'on'; mockSwitch.power = state.power; mockSwitch.deviceStatus = state.deviceStatus; return true; }), turnOff: jest.fn().mockImplementation(async () => { state.power = false; state.deviceStatus = 'off'; mockSwitch.power = state.power; mockSwitch.deviceStatus = state.deviceStatus; return true; }), }; return mockSwitch; }; exports.createMockSwitch = createMockSwitch; function createMockLight(options) { const state = { deviceStatus: options.power ? 'on' : 'off', brightness: options.brightness || 100, colorTemp: options.colorTemp || 140, hue: options.hue || 0, saturation: options.saturation || 0, }; const turnOn = jest.fn().mockImplementation(() => { state.deviceStatus = 'on'; mockLight.deviceStatus = state.deviceStatus; return Promise.resolve(true); }); const turnOff = jest.fn().mockImplementation(() => { state.deviceStatus = 'off'; mockLight.deviceStatus = state.deviceStatus; return Promise.resolve(true); }); const setBrightness = jest.fn().mockImplementation((brightness) => { state.brightness = brightness; mockLight.brightness = state.brightness; return Promise.resolve(true); }); const setColorTemperature = jest.fn().mockImplementation((colorTemp) => { state.colorTemp = colorTemp; mockLight.colorTemp = state.colorTemp; return Promise.resolve(true); }); const setColor = jest.fn().mockImplementation((hue, saturation) => { state.hue = hue; state.saturation = saturation; mockLight.hue = state.hue; mockLight.saturation = state.saturation; return Promise.resolve(true); }); const getDetails = jest.fn().mockImplementation(() => { return Promise.resolve({ deviceStatus: state.deviceStatus, brightness: state.brightness, colorTemp: state.colorTemp, hue: state.hue, saturation: state.saturation, }); }); const mockLight = { deviceName: options.deviceName, deviceType: options.deviceType, cid: options.cid, uuid: options.uuid, deviceStatus: state.deviceStatus, brightness: state.brightness, colorTemp: state.colorTemp, hue: state.hue, saturation: state.saturation, subDeviceNo: options.subDeviceNo || 0, isSubDevice: options.isSubDevice || false, deviceRegion: 'US', configModule: 'Light', macId: '00:11:22:33:44:55', deviceCategory: 'light', connectionStatus: 'online', setApiBaseUrl: jest.fn(), turnOn, turnOff, setBrightness, setColorTemperature, setColor, getDetails, }; return mockLight; } exports.createMockLight = createMockLight; /** * Creates a mock fan instance for testing */ const createMockFan = (config = {}) => { const state = { deviceStatus: 'on', speed: config.speed || 3, rotationDirection: config.rotationDirection || 'clockwise', oscillationState: config.oscillationState || false, childLock: config.childLock || false, mode: config.mode || 'normal' }; const mockFan = { deviceName: config.deviceName || 'Test Fan', deviceType: config.deviceType || 'LTF-F422', cid: config.cid || 'test-cid', uuid: config.uuid || 'test-uuid', deviceStatus: state.deviceStatus, speed: state.speed, maxSpeed: 5, rotationDirection: state.rotationDirection, oscillationState: state.oscillationState, childLock: state.childLock, mode: state.mode, subDeviceNo: 0, isSubDevice: false, deviceRegion: 'US', configModule: 'Fan', macId: '00:11:22:33:44:55', deviceCategory: 'fan', connectionStatus: 'online', getDetails: jest.fn().mockImplementation(async () => { return { deviceStatus: state.deviceStatus, speed: state.speed, rotationDirection: state.rotationDirection, oscillationState: state.oscillationState, childLock: state.childLock, mode: state.mode }; }), setApiBaseUrl: jest.fn(), turnOn: jest.fn().mockImplementation(async () => { state.deviceStatus = 'on'; mockFan.deviceStatus = state.deviceStatus; return true; }), turnOff: jest.fn().mockImplementation(async () => { state.deviceStatus = 'off'; mockFan.deviceStatus = state.deviceStatus; return true; }), changeFanSpeed: jest.fn().mockImplementation(async (speed) => { state.speed = speed; mockFan.speed = state.speed; return true; }), setRotationDirection: jest.fn().mockImplementation(async (direction) => { state.rotationDirection = direction; mockFan.rotationDirection = state.rotationDirection; return true; }), setOscillation: jest.fn().mockImplementation(async (enabled) => { state.oscillationState = enabled; mockFan.oscillationState = state.oscillationState; return true; }), setChildLock: jest.fn().mockImplementation(async (enabled) => { state.childLock = enabled; mockFan.childLock = state.childLock; return true; }), setMode: jest.fn().mockImplementation(async (mode) => { state.mode = mode; mockFan.mode = state.mode; return true; }) }; return mockFan; }; exports.createMockFan = createMockFan; /** * Creates a mock bulb instance for testing */ const createMockBulb = (config = {}) => { const state = { brightness: config.brightness || 100, colorTemp: config.colorTemp || 200, hue: config.hue || 0, saturation: config.saturation || 0, deviceStatus: 'off', }; return { deviceName: config.deviceName || 'Test Bulb', deviceType: config.deviceType || 'ESL100MC', cid: config.cid || 'test-cid', uuid: config.uuid || 'test-uuid', deviceStatus: state.deviceStatus, brightness: state.brightness, colorTemp: state.colorTemp, hue: state.hue, saturation: state.saturation, subDeviceNo: 0, isSubDevice: false, deviceRegion: 'US', configModule: 'Bulb', macId: '00:11:22:33:44:55', deviceCategory: 'bulb', connectionStatus: 'online', getDetails: jest.fn().mockResolvedValue(true), setApiBaseUrl: jest.fn(), turnOn: jest.fn().mockResolvedValue(true), turnOff: jest.fn().mockResolvedValue(true), setBrightness: jest.fn().mockResolvedValue(true), setColorTemperature: jest.fn().mockResolvedValue(true), setColor: jest.fn().mockResolvedValue(true), }; }; exports.createMockBulb = createMockBulb; //# sourceMappingURL=test-helpers.js.map