import test from "node:test"; import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdir, mkdtemp, readdir, readFile, rm, writeFile } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; // Run with: // pnpm -C editor exec tsx --test "app/api/media/fetch-window/route.saved.test.ts" // // A window of a video whose source is in the saved-video store (release 21 // D2): cut on the spot and answered `cached: true`, with no job and no // network; a container that does not reach the window goes to the network // path exactly as before; a pointer whose container is missing is refused. // // THE NETWORK PATH IS SEEN BY ITS DOOR: YouTube is put in a rate-limit // cooldown before the first request, so a request that reaches the network // path answers 409 with the cooldown's sentence — before any job is queued, // and never a real fetch. Real ffmpeg over an 8 s 160×90 lavfi container. const ROOT = await mkdtemp(path.join(os.tmpdir(), "fetch-window-saved-")); const SLUG = "demo-channel"; // Set before the route (and getPaths, which caches) is first imported. process.env.WORKER_TOKEN = "test-token"; process.env.TRANSCRIPTS_DIR = ROOT; process.env.SETTINGS_FILE = path.join(ROOT, "settings.json"); delete process.env.FFPROBE_BIN; delete process.env.FFMPEG_BIN; await mkdir(path.join(ROOT, "channels", SLUG), { recursive: true }); await writeFile( path.join(ROOT, "channels", SLUG, "config.json"), JSON.stringify({ name: "Demo", handling: "youtube", url: "https://www.youtube.com/@demo" }), ); // `held1` has its container in the store; `gone1` has a pointer to a file that // is not there (the store's drive unplugged). async function pointTo(id: string, withFile: boolean): Promise { const videoDir = path.join(ROOT, "channels", SLUG, "data", id); const store = path.join(ROOT, "saved-videos", SLUG, id); await mkdir(videoDir, { recursive: true }); await mkdir(store, { recursive: true }); if (withFile) { execFileSync("ffmpeg", [ "-nostdin", "-v", "error", "-y", "-f", "lavfi", "-i", "testsrc=size=160x90:rate=10:duration=8", "-f", "lavfi", "-i", "sine=frequency=440:duration=8", "-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p", "-c:a", "aac", "-shortest", path.join(store, "source-media.mp4"), ]); } await writeFile( path.join(videoDir, "saved-video.json"), JSON.stringify({ storedAt: "2026-10-10T00:00:00.000Z", dir: store, file: "source-media.mp4", bytes: 1, keepReason: "pin", origin: { requestedBy: "attach-media", kind: "local-archive", archive: "/archive/example.zip", entry: "e.mp4" }, }), ); return videoDir; } const HELD = await pointTo("held1", true); const GONE = await pointTo("gone1", false); const { POST } = await import("./route"); const { getRegistry } = await import("yt-dlp-transcript-common/jobs/registry"); const { recordDownloadBackoff } = await import("yt-dlp-transcript-common/jobs/downloadBackoff"); const { getPaths } = await import("yt-dlp-transcript-common/lib/paths"); await recordDownloadBackoff("youtube", getPaths()); const NETWORK_DOOR = /youtube is in a rate-limit cooldown/; test.after(() => rm(ROOT, { recursive: true, force: true })); function post(body: Record): Promise { return POST( new Request("http://localhost/api/media/fetch-window", { method: "POST", headers: { authorization: "Bearer test-token", "content-type": "application/json" }, body: JSON.stringify(body), }), ); } const base = { channelSlug: SLUG, requestedBy: "test", manifest: "m", clipId: "c1", pad: 1 }; const jobsNow = () => getRegistry().list().length; test("a window the saved container holds is cut and answered cached, with no job", async () => { const jobs = jobsNow(); const res = await post({ ...base, videoId: "held1", from: 2, to: 5 }); assert.equal(res.status, 200); const body = (await res.json()) as { cached: boolean; file: string; from: number; to: number; bytes: number; height?: number; provenance: Record; }; assert.equal(body.cached, true); assert.equal(body.from, 2); assert.equal(body.to, 5); assert.equal(body.file, path.join(HELD, "clips", "2.00-5.00.mp4")); assert.ok(body.bytes > 0); assert.equal(body.height, 90); assert.equal(body.provenance.source, "saved-video"); assert.equal(body.provenance.requestedBy, "test"); assert.equal(body.provenance.clipId, "c1"); assert.equal(jobsNow(), jobs, "no job was queued"); const sidecar = JSON.parse(await readFile(path.join(HELD, "clips", "2.00-5.00.json"), "utf8")); assert.equal(sidecar.source, "saved-video"); // Asked again (or for seconds inside it), the clip cache answers it. const again = await post({ ...base, videoId: "held1", from: 2.5, to: 4.5 }); assert.equal(again.status, 200); const b2 = (await again.json()) as { file: string; provenance: Record }; assert.equal(b2.file, body.file); assert.equal(b2.provenance.source, "saved-video"); assert.deepEqual((await readdir(path.join(HELD, "clips"))).sort(), ["2.00-5.00.json", "2.00-5.00.mp4"]); }); test("a window past the container's end goes to the network path, as before", async () => { const res = await post({ ...base, videoId: "held1", from: 6, to: 12 }); assert.equal(res.status, 409); const body = (await res.json()) as { error: string }; assert.match(body.error, NETWORK_DOOR); assert.ok( !(await readdir(path.join(HELD, "clips"))).some((f) => f.startsWith("6.00-")), "nothing was cut", ); }); test("a pointer whose container is missing is refused with the media guard's sentence, never fetched", async () => { const res = await post({ ...base, videoId: "gone1", from: 2, to: 5 }); assert.equal(res.status, 503); const body = (await res.json()) as { error: string }; assert.match( body.error, /^Channel "demo-channel": media is not reachable — its saved video .*source-media\.mp4 is not there \(drive not mounted\?\)$/, ); assert.deepEqual(await readdir(GONE), ["saved-video.json"]); }); test("a video with no pointer goes to the network path, as before", async () => { await mkdir(path.join(ROOT, "channels", SLUG, "data", "plain1"), { recursive: true }); const res = await post({ ...base, videoId: "plain1", from: 2, to: 5 }); assert.equal(res.status, 409); assert.match(((await res.json()) as { error: string }).error, NETWORK_DOOR); });