1import assert from 'node:assert/strict';2import test from 'node:test';34import {5 detectAndPublishVideoDeliveryMode,6 probeH264WebCodecsSupport,7} from './video-capability.mjs';89test('requires VideoDecoder and its asynchronous support probe', async () => {10 assert.equal(await probeH264WebCodecsSupport({ VideoDecoder: undefined }), false);11 assert.equal(await probeH264WebCodecsSupport({ VideoDecoder: class {} }), false);12});1314test('reports only explicit support for Sigil current H.264 format', async () => {15 let probedConfig = null;16 class SupportedDecoder {17 static async isConfigSupported(config) {18 probedConfig = config;19 return { supported: true, config };20 }21 }2223 assert.equal(await probeH264WebCodecsSupport({ VideoDecoder: SupportedDecoder }), true);24 assert.deepEqual(probedConfig, {25 codec: 'avc1.64001f',26 optimizeForLatency: true,27 });2829 class UnsupportedDecoder {30 static async isConfigSupported(config) {31 return { supported: false, config };32 }33 }34 assert.equal(await probeH264WebCodecsSupport({ VideoDecoder: UnsupportedDecoder }), false);35});3637test('fails closed when the webview rejects its H.264 support probe', async () => {38 const warnings = [];39 class RejectingDecoder {40 static async isConfigSupported() {41 throw new Error('codec support unavailable');42 }43 }4445 assert.equal(await probeH264WebCodecsSupport({46 VideoDecoder: RejectingDecoder,47 logger: { warn: (...args) => warnings.push(args) },48 }), false);49 assert.equal(warnings.length, 1);50 assert.match(warnings[0][0], /capability probe failed/);51});5253test('awaits the probe before publishing the exact raw delivery mode', async () => {54 const calls = [];55 let finishProbe;56 class DelayedDecoder {57 static isConfigSupported() {58 calls.push('probe');59 return new Promise((resolve) => { finishProbe = resolve; });60 }61 }62 const pending = detectAndPublishVideoDeliveryMode({63 VideoDecoder: DelayedDecoder,64 invokeCommand: async (...args) => {65 calls.push(args);66 return true;67 },68 });6970 await Promise.resolve();71 assert.deepEqual(calls, ['probe']);72 finishProbe({ supported: true });73 assert.equal(await pending, true);74 assert.deepEqual(calls, [75 'probe',76 ['set_webcodecs_available', { available: true }],77 ]);78});7980test('keeps the real probe but obeys native publication of the effective mode', async () => {81 const calls = [];82 class SupportedDecoder {83 static async isConfigSupported(config) {84 calls.push(['probe', config]);85 return { supported: true, config };86 }87 }8889 assert.equal(await detectAndPublishVideoDeliveryMode({90 VideoDecoder: SupportedDecoder,91 invokeCommand: async (...args) => {92 calls.push(args);93 return false;94 },95 logger: { warn() {}, error() {} },96 }), false);97 assert.deepEqual(calls, [98 ['probe', {99 codec: 'avc1.64001f',100 optimizeForLatency: true,101 }],102 ['set_webcodecs_available', { available: true }],103 ]);104});105106test('reports unavailable when capability publication fails', async () => {107 const errors = [];108 class SupportedDecoder {109 static async isConfigSupported() { return { supported: true }; }110 }111112 assert.equal(await detectAndPublishVideoDeliveryMode({113 VideoDecoder: SupportedDecoder,114 invokeCommand: async () => { throw new Error('native command failed'); },115 logger: { warn() {}, error: (...args) => errors.push(args) },116 }), false);117 assert.equal(errors.length, 1);118 assert.match(errors[0][0], /could not publish WebCodecs capability/);119});120121test('rejects a missing native publication boundary', async () => {122 await assert.rejects(detectAndPublishVideoDeliveryMode(), TypeError);123});