commit 653a73e2854c020165366402e36f55346e742971
parent 343961902afdb2f8ba1ef71292a541e724387632
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Tue, 18 Aug 2026 11:17:25 -0400
deck.spec: read the clashing corner out of the fixture
It spelled `v1`, which stopped being true the moment make-fixture began
deriving its cover corners from real episodes so /browse/faces would have
frames to draw and a detector to run. The test then went red while the
mechanism it checks -- a cover that reuses a face is refused, and the refusal
NAMES the episode -- was working perfectly.
Which episode the fixture picks is the fixture's business. That the refusal
names it is the assertion, so the expected id is read back out of
thumb-manifest.json, with a guard that fails loudly if alpha-d ever stops
sharing a corner with alpha-c (at which point the test would otherwise pass
while checking nothing).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat:
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/umtool/e2e/deck.spec.ts b/umtool/e2e/deck.spec.ts
@@ -1,4 +1,6 @@
import { test, expect } from "@playwright/test";
+import { readFileSync } from "node:fs";
+import path from "node:path";
// The six deck tools, against the `deck` song make-fixture.mjs builds for them.
//
@@ -233,10 +235,23 @@ test("the index serves the ACCEPTED cover, not the filename guess", async ({ req
test("accepting a cover that reuses a face is refused, and names the clash", async ({ request }) => {
const before = await (await request.get("/api/browse/thumbs?song=alpha")).json();
+ // The shared corner is READ OUT OF THE FIXTURE, not spelled here. It used to
+ // be the literal `v1`, which stopped being true the moment make-fixture began
+ // deriving its corners from real episodes so /browse/faces would have frames
+ // to draw -- and the test then failed while the mechanism it checks was
+ // working perfectly. What matters is that the refusal NAMES the episode, not
+ // which episode the fixture happened to pick.
+ const manifest = JSON.parse(
+ readFileSync(path.join(process.cwd(), ".e2e-song", "code", "thumb-manifest.json"), "utf8"),
+ ) as { thumbs: Record<string, { corners?: { video: string }[] }> };
+ const inC = new Set((manifest.thumbs["alpha-c"].corners ?? []).map((c) => c.video));
+ const shared = (manifest.thumbs["alpha-d"].corners ?? []).map((c) => c.video).find((v) => inC.has(v));
+ expect(shared, "the fixture's alpha-d no longer shares a corner with alpha-c").toBeTruthy();
+
const r = await request.post("/api/browse/thumbs", { data: { song: "alpha", name: "alpha-d" } });
expect(r.status()).toBe(409);
const body = await r.json();
- expect(body.error).toContain("v1");
+ expect(body.error).toContain(shared);
expect(body.error).toContain("alpha-c");
// Nothing was written: the refusal happens before any job starts.