homebridge-tsvesync
Version:
Homebridge plugin for VeSync devices including Levoit air purifiers, humidifiers, and Etekcity smart outlets
427 lines • 14.4 kB
JavaScript
"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