matterbridge-roborock-vacuum-plugin
Version:
Matterbridge Roborock Vacuum Plugin
248 lines • 10.5 kB
JavaScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { MapInfo } from '../core/application/models/MapInfo.js';
import { RoomMap } from '../core/application/models/RoomMap.js';
import { HomeEntity } from '../core/domain/entities/Home.js';
import { PlatformConfigManager } from '../platform/platformConfigManager.js';
import { RoborockVacuumCleaner } from '../types/roborockVacuumCleaner.js';
import { asPartial, asType } from './testUtils.js';
function createMockLogger() {
return asType({
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
notice: vi.fn(),
logLevel: 'info',
});
}
describe('RoborockVacuumCleaner', () => {
let device;
let homeInfo;
let routineAsRoom;
let logger;
let vacuum;
let configManager;
let roborockService;
beforeEach(() => {
device = {
duid: 'duid-123',
specs: { model: 'roborock.s5', firmwareVersion: '1.0.0' },
serialNumber: 'serial-123',
deviceName: 'TestVac',
name: 'TestVac',
scenes: [],
};
const roomMap = new RoomMap([]);
const mapInfo = MapInfo.empty();
homeInfo = new HomeEntity(1, 'Test Home', roomMap, mapInfo, 0);
routineAsRoom = [];
configManager = PlatformConfigManager.create(asPartial({
pluginConfiguration: asPartial({
enableMultipleMap: false,
enableServerMode: false,
}),
}), createMockLogger());
logger = createMockLogger();
roborockService = asPartial({
setSupportedRoutines: vi.fn(),
setSupportedAreas: vi.fn(),
setSupportedAreaIndexMap: vi.fn(),
});
vacuum = new RoborockVacuumCleaner(device, homeInfo, configManager, roborockService, logger);
vi.spyOn(vacuum.log, 'info').mockImplementation(() => { });
vi.spyOn(vacuum.log, 'warn').mockImplementation(() => { });
vi.spyOn(vacuum.log, 'debug').mockImplementation(() => { });
vi.spyOn(vacuum.log, 'error').mockImplementation(() => { });
});
it('should construct with correct properties', () => {
expect(vacuum).toBeInstanceOf(RoborockVacuumCleaner);
expect(vacuum.device).toBe(device);
});
it('should call behaviorHandler for identify command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('identify', {
request: { identifyTime: 5 },
cluster: 1,
attributes: {},
endpoint: 1,
});
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('identify', 5);
});
it('should warn if selectAreas called with empty areas', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('selectAreas', { request: { newAreas: [] } });
expect(behaviorHandler.executeCommand).not.toHaveBeenCalled();
});
it('should call behaviorHandler for selectAreas command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('selectAreas', { newAreas: [1, 2] });
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('selectAreas', [1, 2]);
});
it('should call behaviorHandler for changeToMode command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
const request = { newMode: 42 };
await vacuum.executeCommandHandler('changeToMode', request);
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('changeToMode', 42);
});
it('should call behaviorHandler for pause command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('pause', { request: {} });
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('pause');
});
it('should call behaviorHandler for resume command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('resume', { request: {} });
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('resume');
});
it('should call behaviorHandler for goHome command', async () => {
const behaviorHandler = {
executeCommand: vi.fn(),
setCommandHandler: vi.fn(),
log: logger,
commands: {},
};
vacuum.configureHandler(behaviorHandler);
await vacuum.executeCommandHandler('goHome', { request: {} });
expect(behaviorHandler.executeCommand).toHaveBeenCalledWith('goHome');
});
it('should cover initializeDeviceConfiguration with experimental features', () => {
const expLogger = createMockLogger();
const expConfig = asPartial({
authentication: {
username: 'user',
region: 'US',
forceAuthentication: false,
authenticationMethod: 'Password',
},
pluginConfiguration: {
whiteList: [],
enableServerMode: true,
enableMultipleMap: true,
sanitizeSensitiveLogs: false,
refreshInterval: 60,
debug: false,
unregisterOnShutdown: false,
},
advancedFeature: {
enableAdvancedFeature: true,
settings: {
clearStorageOnStartup: false,
showRoutinesAsRoom: false,
includeDockStationStatus: false,
includeVacuumErrorStatus: false,
forceRunAtDefault: true,
useVacationModeToSendVacuumToDock: false,
enableCleanModeMapping: false,
cleanModeSettings: {},
overrideMatterConfiguration: false,
matterOverrideSettings: {
matterVendorName: 'xxx',
matterVendorId: 123,
matterProductName: 'yy',
matterProductId: 456,
},
enableEmailNotification: false,
emailNotificationSettings: {},
},
},
});
const configManager = PlatformConfigManager.create(expConfig, expLogger);
const dev = { ...device, data: { model: 'roborock.s7', firmwareVersion: '2.0.0' } };
const testHomeInfo = new HomeEntity(1, 'Test', new RoomMap([]), MapInfo.empty(), 0);
const result = RoborockVacuumCleaner['initializeDeviceConfiguration'](dev, testHomeInfo, configManager, roborockService, expLogger);
expect(result.cleanModes).toBeDefined();
expect(result.supportedAreas).toBeDefined();
expect(result.supportedMaps).toBeDefined();
expect(result.supportedAreaAndRoutines).toBeDefined();
expect(result.deviceName).toContain(dev.name);
expect(result.bridgeMode).toBe('server');
});
it('should cover initializeDeviceConfiguration with minimal config', () => {
const minLogger = createMockLogger();
const minConfig = asPartial({
authentication: {
username: 'user',
region: 'US',
forceAuthentication: false,
authenticationMethod: 'Password',
},
pluginConfiguration: {
whiteList: [],
enableServerMode: false,
enableMultipleMap: false,
sanitizeSensitiveLogs: false,
refreshInterval: 60,
debug: false,
unregisterOnShutdown: false,
},
advancedFeature: {
enableAdvancedFeature: false,
settings: {
clearStorageOnStartup: false,
showRoutinesAsRoom: false,
includeDockStationStatus: false,
includeVacuumErrorStatus: false,
forceRunAtDefault: false,
useVacationModeToSendVacuumToDock: false,
enableCleanModeMapping: false,
cleanModeSettings: {},
overrideMatterConfiguration: false,
matterOverrideSettings: {
matterVendorName: 'xxx',
matterVendorId: 123,
matterProductName: 'yy',
matterProductId: 456,
},
enableEmailNotification: false,
emailNotificationSettings: {},
},
},
});
const configManager = PlatformConfigManager.create(minConfig, minLogger);
const testHomeInfo = new HomeEntity(1, 'Test', new RoomMap([]), MapInfo.empty(), 0);
const result = RoborockVacuumCleaner['initializeDeviceConfiguration'](device, testHomeInfo, configManager, roborockService, minLogger);
expect(result.cleanModes).toBeDefined();
expect(result.supportedAreas).toBeDefined();
expect(result.supportedMaps).toBeDefined();
expect(result.supportedAreaAndRoutines).toBeDefined();
expect(result.deviceName).toContain(device.name);
expect(result.bridgeMode).toBe('matter');
});
});
//# sourceMappingURL=roborockVacuumCleaner.test.js.map