Files
silo-server/web/src/player/components/SubtitleTranslateModal.test.ts
T
QuickandClaude Opus 4.8 669050d025 fix(subtitles): address review feedback on AI translation
- Heartbeat queued jobs (before the semaphore), not just running ones, so
  the stale-job reaper can't fail a job that is alive but waiting for a slot
  (which would otherwise let it resurrect itself on acquire, or admit a
  duplicate once the partial unique index no longer sees it as active).
- Filter the translate modal's source list to the formats the server accepts
  (text external/downloaded, non-bitmap embedded), so an unsupported source
  is prevented up front instead of failing the job asynchronously.
- Tell a duplicate requester (e.g. a second viewer, or after a reload) that a
  translation is already in progress instead of silently closing; the
  finished track still arrives via the subtitle_ready refresh.
- Note in the admin card that AI subtitle settings take effect after a
  restart (the running service snapshots them at construction).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 00:19:02 -04:00

39 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { isTranslatableSource } from "./SubtitleTranslateModal";
import type { PlayerSubtitleInfo } from "../types";
function track(p: Partial<PlayerSubtitleInfo>): PlayerSubtitleInfo {
return { index: 0, language: "en", label: "", url: "", ...p };
}
describe("isTranslatableSource", () => {
it("accepts text external/downloaded subtitles", () => {
expect(isTranslatableSource(track({ source: "external", codec: "srt" }))).toBe(true);
expect(isTranslatableSource(track({ source: "downloaded", codec: "subrip" }))).toBe(true);
expect(isTranslatableSource(track({ source: "external", codec: "vtt" }))).toBe(true);
});
it("rejects ASS/SSA external/downloaded subtitles the server can't parse", () => {
expect(isTranslatableSource(track({ source: "external", codec: "ass" }))).toBe(false);
expect(isTranslatableSource(track({ source: "downloaded", codec: "ssa" }))).toBe(false);
});
it("accepts non-bitmap embedded tracks (extracted via ffmpeg, incl. ASS)", () => {
expect(isTranslatableSource(track({ source: "embedded", codec: "ass" }))).toBe(true);
expect(isTranslatableSource(track({ source: "embedded", codec: "subrip" }))).toBe(true);
});
it("rejects bitmap embedded tracks", () => {
expect(isTranslatableSource(track({ source: "embedded", codec: "hdmv_pgs_subtitle" }))).toBe(
false,
);
expect(isTranslatableSource(track({ source: "embedded", codec: "dvd_subtitle" }))).toBe(false);
});
it("rejects the in-progress live track", () => {
expect(isTranslatableSource(track({ source: "downloaded", codec: "srt", live: true }))).toBe(
false,
);
});
});