'use strict'; const { CameraSwitch } = require('../src/cameraSwitch'); // Testet die Entscheidungslogik von grabSnapshot() ohne Hardware: // _captureAt (FFmpeg) und _spawnLive sind gemockt. function makeSwitch(opts = {}) { const sw = new CameraSwitch({ id: 'camT', device: '/dev/null', liveSize: '640x480', ...opts }); sw._captureAt = jest.fn(() => Promise.resolve(Buffer.from([0xFF, 0xD8, 9]))); sw._spawnLive = jest.fn(() => { sw.proc = {}; sw.state = 'live'; }); return sw; } describe('CameraSwitch.grabSnapshot', () => { test('Live läuft (latest gesetzt) → liefert latest, kein Capture', async () => { const sw = makeSwitch({ stream: true }); sw.latest = Buffer.from([1, 2, 3]); const f = await sw.grabSnapshot(); expect(f).toBe(sw.latest); expect(sw._captureAt).not.toHaveBeenCalled(); }); test('stream:false ohne latest → one-shot _captureAt an liveSize', async () => { const sw = makeSwitch({ stream: false }); sw.latest = null; const f = await sw.grabSnapshot(); expect(Buffer.isBuffer(f)).toBe(true); expect(sw._captureAt).toHaveBeenCalledTimes(1); expect(sw._captureAt.mock.calls[0][0]).toBe('640x480'); // size = liveSize expect(sw._spawnLive).not.toHaveBeenCalled(); // kein Dauer-Stream }); test('Lock wird nach dem one-shot wieder freigegeben', async () => { const sw = makeSwitch({ stream: false }); sw.latest = null; await sw.grabSnapshot(); expect(sw.lock).toBe(false); expect(sw.state).toBe('stopped'); }); test('belegtes Gerät (lock) → Fehler, kein zweiter Capture', async () => { const sw = makeSwitch({ stream: false }); sw.latest = null; sw.lock = true; await expect(sw.grabSnapshot()).rejects.toThrow(/belegt/i); expect(sw._captureAt).not.toHaveBeenCalled(); }); });