Config Page

This commit is contained in:
chk
2026-06-07 10:03:34 +02:00
parent f205418640
commit faccbf55ce
16 changed files with 5375 additions and 69 deletions

75
test/reconfigure.test.js Normal file
View File

@@ -0,0 +1,75 @@
'use strict';
const { CameraSwitch } = require('../src/cameraSwitch');
// Mockt die FFmpeg-berührenden Methoden getestet wird NUR die
// Entscheidungslogik von reconfigure() (kill/spawn/no-op), keine Hardware.
function makeSwitch(opts = {}) {
const sw = new CameraSwitch({ id: 'camT', device: '/dev/null', liveSize: '640x480', ...opts });
sw._killCurrentAndWait = jest.fn(() => { sw.proc = null; sw.state = 'stopped'; return Promise.resolve(); });
sw._spawnLive = jest.fn(() => { sw.proc = {}; sw.state = 'live'; });
return sw;
}
describe('CameraSwitch.reconfigure', () => {
test('geänderte liveSize → genau 1× kill + 1× spawn', async () => {
const sw = makeSwitch({ onDemand: false });
sw.proc = {}; sw.state = 'live';
await sw.reconfigure({ liveSize: '320x240', stream: true });
expect(sw.liveSize).toBe('320x240');
expect(sw._killCurrentAndWait).toHaveBeenCalledTimes(1);
expect(sw._spawnLive).toHaveBeenCalledTimes(1);
});
test('gleiche liveSize → no-op (kein kill, kein spawn)', async () => {
const sw = makeSwitch({ onDemand: false });
sw.proc = {}; sw.state = 'live';
await sw.reconfigure({ liveSize: '640x480', stream: true });
expect(sw._killCurrentAndWait).not.toHaveBeenCalled();
expect(sw._spawnLive).not.toHaveBeenCalled();
});
test('lock aktiv (HD-Grab) → nur Feld setzen, kein kill/spawn', async () => {
const sw = makeSwitch({ onDemand: false });
sw.lock = true; sw.proc = {}; sw.state = 'grabbing';
await sw.reconfigure({ liveSize: '320x240', stream: true });
expect(sw.liveSize).toBe('320x240');
expect(sw._killCurrentAndWait).not.toHaveBeenCalled();
expect(sw._spawnLive).not.toHaveBeenCalled();
});
test('stream:false → kill, KEIN respawn, streamEnabled=false', async () => {
const sw = makeSwitch({ onDemand: false });
sw.proc = {}; sw.state = 'live';
await sw.reconfigure({ stream: false });
expect(sw._killCurrentAndWait).toHaveBeenCalledTimes(1);
expect(sw._spawnLive).not.toHaveBeenCalled();
expect(sw.streamEnabled).toBe(false);
});
test('On-Demand ohne Verbraucher → kill bei Resize, aber kein spawn', async () => {
const sw = makeSwitch({ onDemand: true });
sw.subscribers = 0;
sw.proc = {}; sw.state = 'live';
await sw.reconfigure({ liveSize: '320x240', stream: true });
expect(sw._killCurrentAndWait).toHaveBeenCalledTimes(1);
expect(sw._spawnLive).not.toHaveBeenCalled();
});
test('On-Demand mit Verbraucher → kill + spawn (nahtloser Resize)', async () => {
const sw = makeSwitch({ onDemand: true });
sw.subscribers = 1;
sw.proc = {}; sw.state = 'live';
await sw.reconfigure({ liveSize: '320x240', stream: true });
expect(sw._killCurrentAndWait).toHaveBeenCalledTimes(1);
expect(sw._spawnLive).toHaveBeenCalledTimes(1);
});
test('Wiedereinschalten (stream:true) startet bei vorhandenem Verbraucher', async () => {
const sw = makeSwitch({ onDemand: true, stream: false });
sw.subscribers = 1; sw.state = 'stopped'; sw.proc = null;
await sw.reconfigure({ liveSize: '320x240', stream: true });
expect(sw.streamEnabled).toBe(true);
expect(sw._spawnLive).toHaveBeenCalledTimes(1);
});
});