import { describe, expect, test } from "bun:test"; import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { eq } from "drizzle-orm"; import { createApp } from "../src/app"; import { openDb } from "../src/db"; import { biomarkers, labDrafts } from "../src/db/schema"; import { loadOrCreateKey } from "../src/lib/crypto"; async function setup() { const dir = mkdtempSync(join(tmpdir(), "helios-")); const db = openDb(dir); const app = createApp({ db, key: loadOrCreateKey(dir), dataDir: dir }); const j = (b: unknown) => ({ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(b) }); await app.request("/api/setup", j({ password: "hunter2hunter2" })); const cookie = (await app.request("/api/login", j({ password: "hunter2hunter2" }))).headers.get("set-cookie")!; await db.insert(labDrafts).values({ id: "draft1", filename: "r.pdf", filePath: "/tmp/none.pdf", status: "pending", extracted: JSON.stringify({ collectedDate: "2026-01-15", labName: "Sample Diagnostics", markers: [ { panel: "chemistry", name: "Glucose", value: "100", unit: "mg/dL", referenceRange: "70-99", flagged: true }, ] }), error: null, createdAt: 1, }); return { app, db, cookie }; } describe("draft review", () => { test("get, confirm with edits → normalized biomarkers, draft confirmed", async () => { const { app, db, cookie } = await setup(); const h = { cookie, "content-type": "application/json" }; const got = await (await app.request("/api/labs/drafts/draft1", { headers: { cookie } })).json(); expect(got.draft.markers).toHaveLength(1); const confirm = await app.request("/api/labs/drafts/draft1/confirm", { method: "POST", headers: h, body: JSON.stringify({ collectedDate: "2026-01-15", labName: "Sample Diagnostics", markers: [ { panel: "chemistry", name: "Glucose", value: "100", unit: "mg/dL", referenceRange: "70-99", flagged: true }, { panel: null, name: "Ferritin", value: "30", unit: "ng/mL", referenceRange: null, flagged: false }, // user-added row ], }), }); expect(confirm.status).toBe(201); const rows = await db.select().from(biomarkers); expect(rows).toHaveLength(2); const glucose = rows.find((r) => r.analyteKey === "glucose")!; expect(glucose.valueCanonical).toBeCloseTo(5.551, 2); expect(glucose.flagged).toBe(1); const ferritin = rows.find((r) => r.analyteKey === "ferritin")!; expect(ferritin.valueCanonical).toBeCloseTo(30); // ng/mL → µg/L 1:1 expect(ferritin.canonicalUnit).toBe("µg/L"); const draft = (await db.select().from(labDrafts).where(eq(labDrafts.id, "draft1")))[0]; expect(draft.status).toBe("confirmed"); // second confirm → 409 const again = await app.request("/api/labs/drafts/draft1/confirm", { method: "POST", headers: h, body: JSON.stringify({ collectedDate: "2026-01-15", labName: null, markers: [{ panel: null, name: "X", value: "1", unit: null, referenceRange: null, flagged: false }] }), }); expect(again.status).toBe(409); }); test("discard marks draft discarded", async () => { const { app, db, cookie } = await setup(); const r = await app.request("/api/labs/drafts/draft1/discard", { method: "POST", headers: { cookie } }); expect(r.status).toBe(204); const draft = (await db.select().from(labDrafts).where(eq(labDrafts.id, "draft1")))[0]; expect(draft.status).toBe("discarded"); }); test("unknown draft 404; bad date 400", async () => { const { app, cookie } = await setup(); expect((await app.request("/api/labs/drafts/nope", { headers: { cookie } })).status).toBe(404); const bad = await app.request("/api/labs/drafts/draft1/confirm", { method: "POST", headers: { cookie, "content-type": "application/json" }, body: JSON.stringify({ collectedDate: "15/01/2026", labName: null, markers: [{ panel: null, name: "X", value: "1", unit: null, referenceRange: null, flagged: false }] }), }); expect(bad.status).toBe(400); }); });