wrolpi/app/src/components/VideoPlayer.test.js
Roland 15787104fd
videos: address review — tighten auto-caption detection
- Require `line === 'auto'` in the auto-caption signature so a cue that
  is deliberately placed (e.g. `line:0` for top-edge) is left alone even
  if it is also `align:start position:0%`. YouTube auto-captions never
  set `line`.
- For lazily-loaded language tracks, only detach the cuechange listener
  after the cue list is actually populated, in case a cuechange fires
  before cues load.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 18:29:18 -06:00

71 lines
2.6 KiB
JavaScript

import {centerAutoCaptions} from './VideoPlayer';
// Build a fake TextTrack whose cues mimic what the browser parses from a .vtt file.
const makeTrack = (cues) => ({cues});
describe('centerAutoCaptions', () => {
test('re-centers YouTube auto-caption cues (align:start position:0%)', () => {
const track = makeTrack([
{align: 'start', position: 0, line: 'auto', size: 100, text: 'hello'},
{align: 'start', position: 0, line: 'auto', size: 100, text: 'world'},
]);
const changed = centerAutoCaptions(track);
expect(changed).toBe(2);
for (const cue of track.cues) {
expect(cue.align).toBe('center');
expect(cue.position).toBe('auto');
expect(cue.line).toBe('auto');
}
});
test('leaves deliberately-positioned cues untouched', () => {
const track = makeTrack([
// Already centered (no cue settings in the .vtt file).
{align: 'center', position: 'auto', line: 'auto'},
// Deliberately placed at the top, right-aligned.
{align: 'end', position: 90, line: 0},
]);
const changed = centerAutoCaptions(track);
expect(changed).toBe(0);
expect(track.cues[0].align).toBe('center');
expect(track.cues[1].align).toBe('end');
expect(track.cues[1].position).toBe(90);
expect(track.cues[1].line).toBe(0);
});
test('does not touch a left/bottom cue that was deliberately given a line', () => {
// align:start + position:0 but an explicit line -> intentional placement, not the auto-caption
// signature (YouTube never sets line). Must be left alone.
const track = makeTrack([
{align: 'start', position: 0, line: 0},
]);
const changed = centerAutoCaptions(track);
expect(changed).toBe(0);
expect(track.cues[0]).toEqual({align: 'start', position: 0, line: 0});
});
test('handles a track with no cues yet (mode disabled)', () => {
expect(centerAutoCaptions({cues: null})).toBe(0);
expect(centerAutoCaptions(null)).toBe(0);
expect(centerAutoCaptions(undefined)).toBe(0);
});
test('only normalizes the auto-caption cues in a mixed track', () => {
const track = makeTrack([
{align: 'start', position: 0, line: 'auto'},
{align: 'end', position: 90, line: 0},
]);
const changed = centerAutoCaptions(track);
expect(changed).toBe(1);
expect(track.cues[0].align).toBe('center');
expect(track.cues[1].align).toBe('end');
});
});