Add adaptive per-vehicle layouts, full-panel dragging, source controls and automatic preview recovery for RealSense, Insta360 X4 and XGRIDS K1 observation views. Integrate cached Cesium map layers through the private NAS gateway link, retain bounded sensor command receipts, and document validation and operational handoff.
53 lines
3.9 KiB
JavaScript
53 lines
3.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import {after,before,test} from 'node:test';
|
|
import {createServer} from 'vite';
|
|
let server,activation,x4;
|
|
before(async()=>{
|
|
server=await createServer({appType:'custom',logLevel:'silent',server:{middlewareMode:true}});
|
|
activation=await server.ssrLoadModule('../../packages/sensor-ui/src/observationStart.ts');
|
|
x4=await server.ssrLoadModule('../../plugins/insta360-x4/frontend/src/observationStart.ts');
|
|
});
|
|
after(async()=>{await server?.close();});
|
|
const device=(id='camera-1')=>({id,online:true,prepared:true,layers:['color'],snapshot:{acquisition:'idle',context:{session_id:'session-1',execution:{node_id:'board-1'}}},camera_status:{connected:true,preview:0,recording:0}});
|
|
function transport(items,submit=()=>({state:'complete'})){
|
|
const commands=[];return {commands,inventory:async()=>({fresh:true,items}),submit:async c=>{commands.push(c);return submit(c);},operation:async()=>({state:'complete'})};
|
|
}
|
|
test('opening two views shares one start; another camera keeps its own lifecycle',async()=>{
|
|
const a=device(),b=device('camera-2'),t=transport([a,b]);
|
|
await Promise.all([activation.startCameraObservation(a,t),activation.startCameraObservation(a,t),activation.startCameraObservation(b,t)]);
|
|
assert.equal(t.commands.length,2);
|
|
assert.deepEqual(t.commands.map(c=>c.session.device_id).sort(),[a.id,b.id]);
|
|
for(const c of t.commands){assert.equal(c.action_id,'start');assert.deepEqual(c.parameters,{record:false});}
|
|
});
|
|
test('opening observer cannot replace active capture, recording or playback',async()=>{
|
|
for(const value of [{snapshot:{acquisition:'streaming'}},{snapshot:{acquisition:'starting'}},{snapshot:{acquisition:'stopping'}},{playback_id:'recorded-source'}]){
|
|
const a=device();Object.assign(a,{...value,snapshot:{...a.snapshot,...value.snapshot}});const t=transport([a]);
|
|
await activation.startCameraObservation(a,t);assert.equal(t.commands.length,0);
|
|
}
|
|
});
|
|
test('stale inventory and replaced sessions never receive starts',async()=>{
|
|
const original=device(),replacement=device();replacement.snapshot.context.session_id='new-session';
|
|
for(const t of [transport([replacement]),{...transport([original]),inventory:async()=>({fresh:false,items:[original]})}]){
|
|
await assert.rejects(activation.startCameraObservation(original,t));assert.equal(t.commands.length,0);
|
|
}
|
|
});
|
|
test('X4 auto start uses preview only and attaches without restarting an active camera',async()=>{
|
|
const a=device(),t=transport([a]);await x4.startX4Observation(a,t);assert.deepEqual(t.commands.map(c=>c.action_id),['preview.start']);
|
|
a.camera_status.preview=1;t.commands.length=0;await x4.startX4Observation(a,t);assert.equal(t.commands.length,0);
|
|
});
|
|
test('stalled X4 preview recovers once for both lenses without any recording action',async()=>{
|
|
const a=device();a.camera_status.preview=1;const t=transport([a]);
|
|
await Promise.all([x4.startX4Observation(a,t,true),x4.startX4Observation(a,t,true)]);
|
|
assert.deepEqual(t.commands.map(c=>c.action_id),['preview.stop','preview.start']);
|
|
});
|
|
test('X4 recovery requires confirmed stopped recording and successful preview stop',async()=>{
|
|
for(const recording of [1,null,-1]){const a=device();a.camera_status={connected:true,preview:1,recording};const t=transport([a]);await assert.rejects(x4.startX4Observation(a,t,true));assert.equal(t.commands.length,0);}
|
|
const a=device();a.camera_status.preview=1;const t=transport([a],()=>({state:'unknown'}));
|
|
await assert.rejects(x4.startX4Observation(a,t,true));assert.deepEqual(t.commands.map(c=>c.action_id),['preview.stop']);
|
|
});
|
|
test('recovery cannot start a replacement camera session after its stop',async()=>{
|
|
const a=device();a.camera_status.preview=1;const b=device();b.snapshot.context.session_id='replacement';
|
|
const items=[a],t=transport(items,()=>{items[0]=b;return {state:'complete'};});
|
|
await assert.rejects(x4.startX4Observation(a,t,true));assert.deepEqual(t.commands.map(c=>c.action_id),['preview.stop']);
|
|
});
|