import { expect, tap } from '@git.zone/tstest/tapbundle'; import { BoschShcIntegration } from '../../ts/integrations/bosch_shc/index.js'; import type { IBoschShcModeledCommand, IBoschShcSnapshot } from '../../ts/integrations/bosch_shc/index.js'; const snapshot: IBoschShcSnapshot = { host: '192.168.1.10', devices: [ { id: 'hdm:ZigBee:plug', rootDeviceId: 'AA:BB:CC:DD:EE:FF', deviceModel: 'PSM', manufacturer: 'BOSCH', serial: 'PSM123', name: 'Kitchen Plug', status: 'AVAILABLE', profile: 'GENERIC', deviceServiceIds: ['PowerSwitch'] }, { id: 'shutter:living', rootDeviceId: 'AA:BB:CC:DD:EE:FF', deviceModel: 'BBL', manufacturer: 'BOSCH', serial: 'BBL123', name: 'Living Shutter', status: 'AVAILABLE', profile: 'GENERIC', deviceServiceIds: ['ShutterControl'] }, ], services: [ { id: 'PowerSwitch', deviceId: 'hdm:ZigBee:plug', state: { '@type': 'powerSwitchState', switchState: 'ON', automaticPowerOffTime: 0 } }, { id: 'ShutterControl', deviceId: 'shutter:living', state: { '@type': 'shutterControlState', operationState: 'STOPPED', level: 0.5, calibrated: true } }, ], }; tap.test('runs modeled Bosch SHC service commands through an injected executor', async () => { const calls: IBoschShcModeledCommand[] = []; const runtime = await new BoschShcIntegration().setup({ host: '192.168.1.10', snapshot, executor: async (commandArg) => { calls.push(commandArg); return { ok: true }; }, }, {}); const result = await runtime.callService?.({ domain: 'switch', service: 'turn_off', target: { entityId: 'switch.kitchen_plug' }, }); expect(result?.success).toBeTrue(); expect(calls[0].action).toEqual('put_device_service_state'); expect(calls[0].path).toEqual('/devices/hdm:ZigBee:plug/services/PowerSwitch/state'); expect(calls[0].body).toEqual({ '@type': 'powerSwitchState', switchState: 'OFF' }); const coverResult = await runtime.callService?.({ domain: 'cover', service: 'set_cover_position', target: { entityId: 'cover.living_shutter' }, data: { position: 75 }, }); expect(coverResult?.success).toBeTrue(); expect(calls[1].body).toEqual({ '@type': 'shutterControlState', level: 0.75 }); await runtime.destroy(); }); tap.test('returns clear unsupported errors without executor for writes and pairing', async () => { const runtime = await new BoschShcIntegration().setup({ host: '192.168.1.10', snapshot }, {}); const result = await runtime.callService?.({ domain: 'switch', service: 'turn_on', target: { entityId: 'switch.kitchen_plug' }, }); expect(result?.success).toBeFalse(); expect(result?.error).toContain('requires config.snapshot or an injected executor'); const pairResult = await runtime.callService?.({ domain: 'bosch_shc', service: 'pair_client', target: {}, data: { system_password: 'secret' }, }); expect(pairResult?.success).toBeFalse(); expect(pairResult?.error).toContain('pairing transport'); await runtime.destroy(); }); tap.test('models Bosch SHC pairing only through an injected executor', async () => { const calls: IBoschShcModeledCommand[] = []; const runtime = await new BoschShcIntegration().setup({ host: '192.168.1.10', executor: async (commandArg) => { calls.push(commandArg); return { token: 'token:bosch-shc' }; }, }, {}); const result = await runtime.callService?.({ domain: 'bosch_shc', service: 'pair_client', target: {}, data: { system_password: 'secret', client_id: 'homeassistant', client_name: 'HomeAssistant' }, }); expect(result?.success).toBeTrue(); expect(calls[0].action).toEqual('pair_client'); expect(calls[0].sensitiveFields).toEqual(['systemPassword', 'certificatePem']); expect(calls[0].body?.clientName).toEqual('HomeAssistant'); await runtime.destroy(); }); export default tap.start();