80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
|
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||
|
|
import { BleboxIntegration } from '../../ts/integrations/blebox/index.js';
|
||
|
|
import type { IBleboxSnapshot } from '../../ts/integrations/blebox/index.js';
|
||
|
|
|
||
|
|
const switchSnapshot: IBleboxSnapshot = {
|
||
|
|
device: {
|
||
|
|
id: '1afe34e750b8',
|
||
|
|
type: 'switchBoxD',
|
||
|
|
deviceName: 'Kitchen Switch',
|
||
|
|
fv: '0.200',
|
||
|
|
hv: '0.7',
|
||
|
|
apiLevel: 20200831,
|
||
|
|
},
|
||
|
|
state: {
|
||
|
|
relays: [
|
||
|
|
{ relay: 0, state: 0, name: 'Counter' },
|
||
|
|
{ relay: 1, state: 0, name: 'Sink' },
|
||
|
|
],
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
tap.test('runs safe BleBox switch commands through modeled local HTTP paths', async () => {
|
||
|
|
const originalFetch = globalThis.fetch;
|
||
|
|
const calls: Array<{ url: string; method?: string }> = [];
|
||
|
|
globalThis.fetch = (async (urlArg: URL | RequestInfo, initArg?: RequestInit) => {
|
||
|
|
calls.push({ url: String(urlArg), method: initArg?.method });
|
||
|
|
return new Response('{}', { status: 200, headers: { 'content-type': 'application/json' } });
|
||
|
|
}) as typeof globalThis.fetch;
|
||
|
|
|
||
|
|
try {
|
||
|
|
const runtime = await new BleboxIntegration().setup({ host: '192.168.1.50', snapshot: switchSnapshot }, {});
|
||
|
|
const result = await runtime.callService?.({
|
||
|
|
domain: 'switch',
|
||
|
|
service: 'turn_on',
|
||
|
|
target: { entityId: 'switch.kitchen_switch_relay_1' },
|
||
|
|
});
|
||
|
|
expect(result?.success).toBeTrue();
|
||
|
|
expect(calls[0].url).toEqual('http://192.168.1.50/s/1/1');
|
||
|
|
await runtime.destroy();
|
||
|
|
} finally {
|
||
|
|
globalThis.fetch = originalFetch;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('rejects unsafe BleBox light service payloads before HTTP commands', async () => {
|
||
|
|
const runtime = await new BleboxIntegration().setup({ host: '192.168.1.50', snapshot: {
|
||
|
|
device: {
|
||
|
|
id: '2bee34e750b8',
|
||
|
|
type: 'wLightBox',
|
||
|
|
deviceName: 'Cabinet Light',
|
||
|
|
fv: '0.993',
|
||
|
|
hv: '4.3',
|
||
|
|
apiLevel: 20200229,
|
||
|
|
},
|
||
|
|
extendedState: { rgbw: { desiredColor: 'fa00203a', colorMode: 4, effectID: 0 } },
|
||
|
|
} }, {});
|
||
|
|
const result = await runtime.callService?.({
|
||
|
|
domain: 'light',
|
||
|
|
service: 'turn_on',
|
||
|
|
target: { entityId: 'light.cabinet_light_color' },
|
||
|
|
data: { brightness: 999 },
|
||
|
|
});
|
||
|
|
expect(result?.success).toBeFalse();
|
||
|
|
expect(result?.error).toContain('brightness');
|
||
|
|
await runtime.destroy();
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('config flow returns a local HTTP config and validates credentials', async () => {
|
||
|
|
const integration = new BleboxIntegration();
|
||
|
|
const step = await integration.configFlow.start({ source: 'manual', integrationDomain: 'blebox', host: '192.168.1.50' }, {});
|
||
|
|
const incomplete = await step.submit?.({ host: '192.168.1.50', port: 80, username: 'admin' });
|
||
|
|
expect(incomplete?.kind).toEqual('error');
|
||
|
|
const done = await step.submit?.({ host: '192.168.1.50', port: 80, username: 'admin', password: 'secret' });
|
||
|
|
expect(done?.kind).toEqual('done');
|
||
|
|
expect(done?.config?.host).toEqual('192.168.1.50');
|
||
|
|
expect(done?.config?.protocol).toEqual('http');
|
||
|
|
});
|
||
|
|
|
||
|
|
export default tap.start();
|