diff --git a/frontend/src/lib/api/core.test.ts b/frontend/src/lib/api/core.test.ts index c71b2b01..2f23ca1f 100644 --- a/frontend/src/lib/api/core.test.ts +++ b/frontend/src/lib/api/core.test.ts @@ -221,7 +221,7 @@ describe("req — a file, not a parsed answer", () => { // A zip. Without the `raw` branch this falls into `r.json()`, throws on the first byte, and the // download dies as an opaque failure — which no lane would see, because the only consumer test // mocks the api method wholesale. - const zip = new Response(new Blob(["PK"]), { + const zip = new Response("PK", { status: 200, headers: { "content-type": "application/zip", @@ -234,7 +234,16 @@ describe("req — a file, not a parsed answer", () => { expect(r).toBe(zip); expect(r.headers.get("content-disposition")).toContain("siftlode-debug-260919.zip"); - expect(await r.blob()).toBeInstanceOf(Blob); // the body is still there to be read + // NOT `toBeInstanceOf(Blob)`: that asserts which realm built the body, not that there is one. + // Under jsdom the ambient `Blob` is jsdom's class, while `Response.blob()` hands back node's own + // on Node 22 and jsdom's on Node 24 — so the same assertion passed here and failed on the server + // gate (measured 2026-09-20). Nor `.text()`, for the mirror-image reason: jsdom's Blob has no + // such method, so reading the bytes back is green on 22 and red on 24. The brand and the size + // are the two things both realms agree on, and they are what this test means. + const body = await r.blob(); + expect(Object.prototype.toString.call(body)).toBe("[object Blob]"); + expect(body.size).toBe(4); // the body is still there to be read, all four of its bytes + expect(body.type).toBe("application/zip"); }); it("still refuses before the body is touched, so a refusal is shown and not saved", async () => { diff --git a/frontend/src/lib/api/diagnostics.dom.test.ts b/frontend/src/lib/api/diagnostics.dom.test.ts index 68ba8010..af46e429 100644 --- a/frontend/src/lib/api/diagnostics.dom.test.ts +++ b/frontend/src/lib/api/diagnostics.dom.test.ts @@ -42,7 +42,10 @@ describe("debugExport", () => { expect(out.name).toBe("siftlode-debug-20260919-1402-abc123.zip"); // The body is read as bytes, not parsed: `r.json()` on a zip would throw on its first one. - expect(out.blob).toBeInstanceOf(Blob); + // Brand, not `toBeInstanceOf(Blob)` — that asks which realm built the body: under jsdom the + // ambient `Blob` is jsdom's class, while `Response.blob()` returns node's own on Node 22 and + // jsdom's on Node 24, so the instance check passed locally and failed on the server gate. + expect(Object.prototype.toString.call(out.blob)).toBe("[object Blob]"); expect(out.blob.size).toBe(4); });