openreader/tests/unit/tts-epub-handoff.spec.ts
Richard R d7e6a7b7ba fix(api,rate-limit): centralize daily quota exceeded response and update imports
Move daily quota exceeded problem response logic to a dedicated utility in `lib/server/rate-limit/problem-response`. Refactor API routes to use the new builder and remove duplicated formatting code. Update all relevant imports for consistency. This improves maintainability and ensures uniform error responses across TTS endpoints.
2026-05-12 18:24:39 -06:00

115 lines
4 KiB
TypeScript

import { expect, test } from '@playwright/test';
import {
completedEpubBoundarySegment,
resolveEpubBoundaryHandoffStartIndex,
resolveEpubReplaySuppressionAction,
shouldSuppressCompletedEpubBoundaryReplay,
} from '../../src/lib/client/epub/tts-epub-handoff';
import type { CanonicalTtsSegment } from '../../src/lib/shared/tts-segment-plan';
const segment = (
text: string,
overrides: Partial<CanonicalTtsSegment> = {},
): CanonicalTtsSegment => ({
key: `segment:${text}`,
ordinal: 0,
text,
ownerSourceKey: 'str:page-a',
ownerLocator: { location: 'page-a', readerType: 'epub' },
startAnchor: { sourceKey: 'str:page-a', offset: 0 },
endAnchor: { sourceKey: 'str:page-a', offset: text.length },
spansSourceBoundary: false,
...overrides,
});
test.describe('EPUB boundary handoff', () => {
test('records only completed segments that span a source boundary', () => {
expect(completedEpubBoundarySegment(segment('same page'))).toBeNull();
const completed = completedEpubBoundarySegment(segment('cross page', {
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 5 },
}), 100);
expect(completed).toMatchObject({
key: 'segment:cross page',
fingerprint: 'cross page',
completedAt: 100,
});
});
test('skips a leading replay of the completed boundary segment', () => {
const completed = completedEpubBoundarySegment(segment('The same audio crosses the page.', {
key: 'old-key',
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 10 },
}), 1000);
const startIndex = resolveEpubBoundaryHandoffStartIndex([
segment('The same audio crosses the page.', { key: 'new-cfi-key' }),
segment('Fresh audio on the next page.'),
], completed, 1100);
expect(startIndex).toBe(1);
});
test('does not skip stale or non-leading matches', () => {
const completed = completedEpubBoundarySegment(segment('Repeated later.', {
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 10 },
}), 1000);
expect(resolveEpubBoundaryHandoffStartIndex([
segment('Fresh start.'),
segment('Repeated later.'),
], completed, 1100)).toBe(0);
expect(resolveEpubBoundaryHandoffStartIndex([
segment('Repeated later.'),
], completed, 200_000)).toBe(0);
});
test('suppresses a completed boundary segment at playback time even if setText handoff missed it', () => {
const completed = completedEpubBoundarySegment(segment('Boundary audio that already played.', {
key: 'completed-key',
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 10 },
}), 1000);
expect(shouldSuppressCompletedEpubBoundaryReplay(
segment('Boundary audio that already played.', { key: 'different-render-key' }),
completed,
1500,
)).toBe(true);
expect(shouldSuppressCompletedEpubBoundaryReplay(
segment('Actually fresh audio.'),
completed,
1500,
)).toBe(false);
});
test('suppression skips only within the current rendered segment list', () => {
const completed = completedEpubBoundarySegment(segment('Boundary audio that already played.', {
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 10 },
}), 1000);
expect(resolveEpubReplaySuppressionAction([
segment('Boundary audio that already played.', { key: 'rerendered-key' }),
segment('Fresh local audio.'),
], 0, completed, 1100)).toEqual({ kind: 'skip-to-index', index: 1 });
});
test('suppression pauses instead of requesting another page turn when no fresh local segment exists', () => {
const completed = completedEpubBoundarySegment(segment('Boundary audio that already played.', {
spansSourceBoundary: true,
endAnchor: { sourceKey: 'str:page-b', offset: 10 },
}), 1000);
expect(resolveEpubReplaySuppressionAction([
segment('Boundary audio that already played.', { key: 'rerendered-key' }),
], 0, completed, 1100)).toEqual({ kind: 'pause' });
});
});