import test from "node:test"; import assert from "node:assert/strict"; import { mkdir, mkdtemp, 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/ops/transcribe/route.test.ts" // // The adapter's surface: the token, the body's keys, and the controller's // refusals answered as 400s before any job exists. Every request here is // refused — no job is queued and no engine runs (the job itself is covered by // common/controller/transcribeFile.test.ts). const ROOT = await mkdtemp(path.join(os.tmpdir(), "transcribe-route-")); const CORPUS = path.join(ROOT, "transcripts"); await mkdir(CORPUS, { recursive: true }); const SETTINGS_FILE = path.join(ROOT, "settings.json"); const SETTINGS_TEXT = JSON.stringify({ workers: [ { id: "gpu", name: "GPU", kind: "local", enabled: true, priority: 0, appId: "parakeet", config: { model: "/models/x.gguf" }, }, ], }); await writeFile(SETTINGS_FILE, SETTINGS_TEXT); const MEDIA = path.join(ROOT, "clip.wav"); await writeFile(MEDIA, "x"); // Set before the route (and getPaths, which caches) is first imported. process.env.WORKER_TOKEN = "test-token"; process.env.TRANSCRIPTS_DIR = CORPUS; process.env.SETTINGS_FILE = SETTINGS_FILE; const { POST } = await import("./route"); test.after(() => rm(ROOT, { recursive: true, force: true })); async function post( body: Record, token = "test-token", ): Promise<{ status: number; json: { ok?: boolean; error?: string; jobId?: string } }> { const res = await POST( new Request("http://localhost/api/ops/transcribe", { method: "POST", headers: { authorization: `Bearer ${token}`, "content-type": "application/json", }, body: JSON.stringify(body), }), ); return { status: res.status, json: await res.json() }; } test("a wrong token is a 401", async () => { const { status } = await post({ path: MEDIA }, "wrong"); assert.equal(status, 401); }); test("an unknown key is a 400 naming the accepted ones", async () => { const { status, json } = await post({ path: MEDIA, model: "/x.gguf" }); assert.equal(status, 400); assert.match(json.error!, /unknown key\(s\): model — this route accepts path, start, end, workerId, out/); }); test("the controller's refusals come back as 400s", async () => { const cases: [Record, RegExp][] = [ [{ path: "clip.wav" }, /"path" must be absolute/], [{ path: path.join(ROOT, "missing.wav") }, /does not exist/], [{ path: MEDIA, start: 30, end: 10 }, /"end" \(10\) must be after "start" \(30\)/], [{ path: MEDIA, workerId: "nope" }, /no worker "nope" — known: gpu/], [{ path: MEDIA, out: path.join(CORPUS, "r.json") }, /inside the corpus/], ]; for (const [body, re] of cases) { const { status, json } = await post(body); assert.equal(status, 400, JSON.stringify(body)); assert.equal(json.ok, false); assert.match(json.error!, re); assert.equal(json.jobId, undefined); } assert.equal(await readFile(SETTINGS_FILE, "utf8"), SETTINGS_TEXT); });