import { expect, tap } from '@git.zone/tstest/tapbundle'; import { AndroidIpWebcamClient } from '../../ts/integrations/android_ip_webcam/index.js'; tap.test('fetches live snapshots and only reports command success after Ok response', async () => { const originalFetch = globalThis.fetch; const requests: string[] = []; globalThis.fetch = (async (inputArg: RequestInfo | URL) => { const url = typeof inputArg === 'string' ? inputArg : inputArg instanceof URL ? inputArg.toString() : inputArg.url; requests.push(url); if (url.endsWith('/status.json?show_avail=1')) { return new Response(JSON.stringify({ curvals: { torch: 'off', motion_detect: 'on' }, avail: { torch: ['on', 'off'] }, audio_connections: 1, video_connections: 0, }), { headers: { 'content-type': 'application/json' } }); } if (url.endsWith('/sensors.json')) { return new Response(JSON.stringify({ battery_level: { unit: '%', data: [[ [87, 123] ]] }, motion_active: { data: [[ [1, 123] ]] }, }), { headers: { 'content-type': 'application/json' } }); } if (url.endsWith('/enabletorch')) { return new Response('Ok'); } return new Response('Not Found', { status: 404 }); }) as typeof fetch; try { const client = new AndroidIpWebcamClient({ host: '192.168.1.20', port: 8080 }); const snapshot = await client.getSnapshot(); expect(snapshot.connected).toBeTrue(); expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'battery_level')?.value).toEqual(87); expect(snapshot.binarySensors[0].isOn).toBeTrue(); expect(snapshot.switches.find((switchArg) => switchArg.key === 'torch')?.isOn).toEqual(false); const result = await client.execute({ type: 'torch', service: 'set_torch', activate: true }); expect(result).toEqual({ ok: true, key: 'torch', value: true }); expect(requests.some((requestArg) => requestArg.endsWith('/enabletorch'))).toBeTrue(); } finally { globalThis.fetch = originalFetch; } }); tap.test('does not pretend live commands succeeded without a live endpoint', async () => { const client = new AndroidIpWebcamClient({}); let error = ''; try { await client.execute({ type: 'torch', service: 'set_torch', activate: true }); } catch (errorArg) { error = errorArg instanceof Error ? errorArg.message : String(errorArg); } expect(error.includes('requires config.host or config.url')).toBeTrue(); }); export default tap.start();