|
|
@@ -135,7 +135,7 @@ test('an unconfirmed playback control is refused locally without a request', asy
|
|
|
const sent = []
|
|
|
const playback = createVideoPlaybackSession({
|
|
|
records: async () => ({ records: [] }), playback: async () => started('A'),
|
|
|
- control: async (session, action) => { sent.push(action); return {} },
|
|
|
+ control: async (session, action, value) => { sent.push([action, value]); return {} },
|
|
|
stop: async (session) => stopped(session),
|
|
|
}, () => {})
|
|
|
try {
|
|
|
@@ -151,6 +151,43 @@ test('an unconfirmed playback control is refused locally without a request', asy
|
|
|
} finally { await playback.dispose() }
|
|
|
})
|
|
|
|
|
|
+test('a confirmed control is forwarded with its action and rate, and a speed rate maps to one capability', async () => {
|
|
|
+ const sent = []
|
|
|
+ let visible = {}
|
|
|
+ const playback = createVideoPlaybackSession({
|
|
|
+ records: async () => ({ records: [] }),
|
|
|
+ // A device that proved pause and speed support, but not seek.
|
|
|
+ playback: async () => ({ ...started('A'), controls: { pause: true, resume: true, speed: true, seek: false } }),
|
|
|
+ control: async (session, action, value) => { sent.push([action, value]); return { sessionId: session.sessionId, status: 'ACTIVE' } },
|
|
|
+ stop: async (session) => stopped(session),
|
|
|
+ }, (patch) => { visible = { ...visible, ...patch } })
|
|
|
+ try {
|
|
|
+ await playback.play('A', '2026-11-10 01:00:00', '2026-11-10 02:00:00')
|
|
|
+ assert.equal(visible.controls.pause, true, 'a confirmed capability must reach the panel')
|
|
|
+ assert.equal(await playback.control('pause'), true)
|
|
|
+ // Each rate key is one capability on the server but carries its own rate value.
|
|
|
+ assert.equal(await playback.control('speed-0.25'), true)
|
|
|
+ assert.equal(await playback.control('speed-4'), true)
|
|
|
+ assert.equal(await playback.control('seek'), false, 'an unconfirmed seek must still be refused')
|
|
|
+ assert.deepEqual(sent, [['pause', undefined], ['speed', 0.25], ['speed', 4]])
|
|
|
+ } finally { await playback.dispose() }
|
|
|
+})
|
|
|
+
|
|
|
+test('stopping resets the playback capability set so it cannot leak into the next session', async () => {
|
|
|
+ let visible = {}
|
|
|
+ const playback = createVideoPlaybackSession({
|
|
|
+ records: async () => ({ records: [] }),
|
|
|
+ playback: async () => ({ ...started('A'), controls: { pause: true, resume: true, speed: true, seek: true } }),
|
|
|
+ stop: async (session) => stopped(session),
|
|
|
+ }, (patch) => { visible = { ...visible, ...patch } })
|
|
|
+ try {
|
|
|
+ await playback.play('A', '2026-11-10 01:00:00', '2026-11-10 02:00:00')
|
|
|
+ assert.equal(visible.controls.pause, true)
|
|
|
+ await playback.stop()
|
|
|
+ assert.deepEqual(visible.controls, {}, 'a released session must not keep its capabilities')
|
|
|
+ } finally { await playback.dispose() }
|
|
|
+})
|
|
|
+
|
|
|
test('stopping releases the owned playback session and reports unconfirmed cleanup truthfully', async () => {
|
|
|
const clock = new Clock(), updates = []
|
|
|
let visible = {}
|