NODEDC_MISSION_CORE/apps/control-station/test/rerunViewportProgressivePla...

242 lines
7.2 KiB
JavaScript

import assert from "node:assert/strict";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let canPublishRecordedPlaybackController;
let createRecordedAutoplayGate;
let isRecordedPlaybackReady;
let isRecordedPlaybackPresentationReady;
let isUsableRecordedPlaybackRange;
let recordedPlaybackBufferState;
let recordedPlaybackRangeWhenReady;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
canPublishRecordedPlaybackController,
createRecordedAutoplayGate,
isRecordedPlaybackReady,
isRecordedPlaybackPresentationReady,
isUsableRecordedPlaybackRange,
recordedPlaybackBufferState,
recordedPlaybackRangeWhenReady,
} = await server.ssrLoadModule("/src/components/RerunViewport.tsx"));
});
after(async () => {
await server?.close();
});
test("a first frame reports buffer telemetry but is not ready for presentation", () => {
assert.equal(isUsableRecordedPlaybackRange(null), false);
assert.equal(isUsableRecordedPlaybackRange({ min: Number.NaN, max: 0 }), false);
assert.equal(isUsableRecordedPlaybackRange({ min: 2, max: 1 }), false);
assert.equal(isUsableRecordedPlaybackRange({ min: 0, max: 0 }), true);
const firstFrame = recordedPlaybackBufferState({ min: 0, max: 0 }, 20);
assert.deepEqual(firstFrame, {
bufferedEndNs: 0,
expectedStartNs: 0,
expectedEndNs: 20_000_000_000,
bufferProgress: 0,
fullyBuffered: false,
});
assert.equal(isRecordedPlaybackReady(true, true, firstFrame), false);
assert.equal(recordedPlaybackRangeWhenReady({ min: 0, max: 0 }, firstFrame, true), null);
});
test("host timeline remains unmounted until the verified recording is fully ready", () => {
const partial = {
recordingId: "partial",
timeline: "session_time",
rangeNs: null,
currentNs: 0,
playing: false,
bufferedEndNs: 5,
expectedStartNs: 0,
expectedEndNs: 10,
bufferProgress: 0.5,
fullyBuffered: false,
};
assert.equal(isRecordedPlaybackPresentationReady("loading", partial), false);
assert.equal(isRecordedPlaybackPresentationReady("ready", partial), false);
assert.equal(isRecordedPlaybackPresentationReady("error", partial), false);
assert.equal(isRecordedPlaybackPresentationReady("ready", {
...partial,
rangeNs: { min: 0, max: 10 },
bufferedEndNs: 10,
bufferProgress: 1,
fullyBuffered: true,
}), true);
});
test("buffer progress grows independently and preserves the full-buffer tolerance", () => {
assert.deepEqual(recordedPlaybackBufferState({ min: 0, max: 5_000_000_000 }, 20), {
bufferedEndNs: 5_000_000_000,
expectedStartNs: 0,
expectedEndNs: 20_000_000_000,
bufferProgress: 0.25,
fullyBuffered: false,
});
const complete = recordedPlaybackBufferState({ min: 0, max: 19_999_500_000 }, 20);
assert.equal(complete.bufferProgress, 0.999975);
assert.equal(complete.fullyBuffered, true);
assert.equal(isRecordedPlaybackReady(false, true, complete), false);
assert.equal(isRecordedPlaybackReady(true, false, complete), false);
assert.equal(isRecordedPlaybackReady(true, true, complete), true);
assert.equal(
recordedPlaybackRangeWhenReady({ min: 0, max: 19_999_500_000 }, complete, false),
null,
);
assert.deepEqual(
recordedPlaybackRangeWhenReady({ min: 0, max: 19_999_500_000 }, complete, true),
{ min: 0, max: 19_999_500_000 },
);
const missingDeclaredStart = recordedPlaybackBufferState(
{ min: 5_000_000_000, max: 20_000_000_000 },
20,
0,
);
assert.equal(missingDeclaredStart.bufferProgress, 1);
assert.equal(missingDeclaredStart.fullyBuffered, false);
assert.equal(isRecordedPlaybackReady(true, true, missingDeclaredStart), false);
});
test("a verified split boundary spill covers and clamps the declared LAB window", () => {
const actualRange = {
min: 34_756_228_209,
max: 95_383_857_292,
};
const buffer = recordedPlaybackBufferState(
actualRange,
95.383857292,
35.421857292,
);
assert.equal(buffer.bufferProgress, 1);
assert.equal(buffer.fullyBuffered, true);
assert.equal(isRecordedPlaybackReady(true, true, buffer), true);
assert.deepEqual(
recordedPlaybackRangeWhenReady(actualRange, buffer, true),
{
min: 35_421_857_292,
max: 95_383_857_292,
},
);
});
test("recorded autoplay waits for the full range and then runs exactly once", () => {
const gate = createRecordedAutoplayGate();
const seeks = [];
let plays = 0;
const seek = (value) => seeks.push(value);
const play = () => {
plays += 1;
};
assert.equal(gate.attempt(false, true, true, { min: 0, max: 0 }, seek, play), false);
assert.equal(gate.attempt(true, false, true, { min: 0, max: 500_000_000 }, seek, play), false);
assert.equal(gate.attempt(true, true, false, { min: 0, max: 20_000_000_000 }, seek, play), false);
assert.deepEqual(seeks, []);
assert.equal(plays, 0);
assert.equal(gate.attempt(true, true, true, { min: 0, max: 20_000_000_000 }, seek, play), true);
assert.equal(gate.attempt(true, true, true, { min: 0, max: 20_000_000_000 }, seek, play), false);
assert.deepEqual(seeks, [0]);
assert.equal(plays, 1);
assert.equal(gate.attempted(), true);
});
test("recorded autoplay starts at the first presentable camera frame without shrinking the range", () => {
const gate = createRecordedAutoplayGate();
const seeks = [];
const range = { min: 0, max: 535_717_620_042 };
assert.equal(gate.attempt(
true,
true,
true,
range,
(value) => seeks.push(value),
() => {},
35_421_857_292,
), true);
assert.deepEqual(seeks, [35_421_857_292]);
assert.deepEqual(range, { min: 0, max: 535_717_620_042 });
});
test("recorded autoplay clamps an invalid presentation start to the admitted archive", () => {
const before = createRecordedAutoplayGate();
const after = createRecordedAutoplayGate();
const seeks = [];
const range = { min: 5, max: 10 };
assert.equal(before.attempt(
true,
true,
true,
range,
(value) => seeks.push(value),
() => {},
-50,
), true);
assert.equal(after.attempt(
true,
true,
true,
range,
(value) => seeks.push(value),
() => {},
50,
), true);
assert.deepEqual(seeks, [5, 10]);
});
test("a failed vendor autoplay attempt is consumed instead of rewinding later", () => {
const gate = createRecordedAutoplayGate();
let seeks = 0;
let plays = 0;
assert.equal(gate.attempt(
true,
true,
true,
{ min: 0, max: 1 },
() => {
seeks += 1;
},
() => {
plays += 1;
throw new Error("receiver raced its first frame");
},
), false);
assert.equal(gate.attempt(
true,
true,
true,
{ min: 0, max: 2 },
() => {
seeks += 1;
},
() => {
plays += 1;
},
), false);
assert.equal(seeks, 1);
assert.equal(plays, 1);
});
test("recorded playback controller stays unpublished until the aggregate gate is ready", () => {
assert.equal(canPublishRecordedPlaybackController(false, "ready"), false);
assert.equal(canPublishRecordedPlaybackController(true, "loading"), false);
assert.equal(canPublishRecordedPlaybackController(true, "error"), false);
assert.equal(canPublishRecordedPlaybackController(true, "ready"), true);
});