// ACC-11: the hosted product has no shared password and no "Connect Azure model" form, and the
// old /preview route is not in a production build. ACC-2: Try a fictional patient still works
// with no account, on the fictional records only, with the local reader only.
import { mkdtemp, readdir, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { build } from "vite";
import { afterEach, describe, expect, it, vi } from "vitest";
import { CASES } from "../server/cases";
import { createNetlifyHandler } from "../server/netlify-handler";
class MemoryBlobs {
rows = new Map<string, { value: unknown; etag: string }>();
n = 0;
async get(key: string) { return this.rows.get(key)?.value ?? null; }
async getWithMetadata(key: string) { const row = this.rows.get(key); return row ? { data: row.value, etag: row.etag, metadata: {} } : null; }
async setJSON(key: string, value: unknown, opts: { onlyIfNew?: boolean; onlyIfMatch?: string } = {}) {
const row = this.rows.get(key);
if ((opts.onlyIfNew && row) || (opts.onlyIfMatch && row?.etag !== opts.onlyIfMatch)) return { modified: false };
this.rows.set(key, { value, etag: `e${++this.n}` });
return { modified: true, etag: `e${this.n}` };
}
async delete(key: string) { this.rows.delete(key); }
async list() { return { blobs: [...this.rows.entries()].map(([key, row]) => ({ key, etag: row.etag })) }; }
}
const req = (path: string, body?: unknown, cookie?: string) =>
new Request("https://context.marmar.life/api/" + path, {
method: body === undefined ? "GET" : "POST",
headers: { Origin: "https://context.marmar.life", ...(body === undefined ? {} : { "Content-Type": "application/json" }), ...(cookie ? { Cookie: cookie } : {}) },
body: body === undefined ? undefined : JSON.stringify(body),
});
describe("the hosted demo (CONTEXT_AUTH_MODE=demo)", () => {
afterEach(() => vi.unstubAllEnvs());
it("runs a fictional patient with no account and no model", async () => {
vi.stubEnv("CONTEXT_AUTH_MODE", "demo");
const handler = createNetlifyHandler(() => new MemoryBlobs() as never);
const status = await handler(req("status"));
expect(status.status).toBe(200);
expect(await status.json()).toMatchObject({ modelConfigured: false, model: null, demo: true });
const cookie = status.headers.get("set-cookie")!;
expect(cookie).toMatch(/^__Host-marmar-context-demo=[a-f0-9-]{36}; Secure; HttpOnly; SameSite=Strict/);
const sources = CASES[0].sources;
const draft = await handler(req("extract", { sources, syntheticOnly: true, useModel: false }, cookie.split(";")[0]));
expect(draft.status).toBe(200);
expect((await draft.json()).mode).toBe("local");
});
it("refuses the model, pasted or changed text, and has no password sign-in", async () => {
vi.stubEnv("CONTEXT_AUTH_MODE", "demo");
const handler = createNetlifyHandler(() => new MemoryBlobs() as never);
const sources = CASES[0].sources;
expect((await handler(req("extract", { sources, syntheticOnly: true, useModel: true }))).status).toBe(403);
const pasted = [{ ...sources[0], text: "Patient: a real person\nMedication: Warfarin 5 mg" }];
expect((await handler(req("extract", { sources: pasted, syntheticOnly: true, useModel: false }))).status).toBe(403);
expect((await handler(req("auth", { password: "anything" }))).status).not.toBe(200);
expect((await handler(req("model", {}))).status).toBe(403);
});
it("still fails closed without Cloudflare Access outside the demo", async () => {
vi.stubEnv("CONTEXT_AUTH_MODE", "password");
vi.stubEnv("CONTEXT_ACCESS_ISSUER", "https://marmar-test.cloudflareaccess.com");
vi.stubEnv("CONTEXT_ACCESS_AUD", "test-audience");
expect((await createNetlifyHandler(() => new MemoryBlobs() as never)(req("status"))).status).toBe(401);
});
});
describe("the production build", () => {
it("has no /preview route, no shared password and no model connection form", async () => {
const outDir = await mkdtemp(join(tmpdir(), "context-build-"));
// Vitest runs with NODE_ENV=test; a real build runs with production, which makes import.meta.env.DEV false.
vi.stubEnv("NODE_ENV", "production");
try {
await build({ root: fileURLToPath(new URL("..", import.meta.url)), logLevel: "silent", mode: "production", build: { outDir, emptyOutDir: true } });
const files = (await readdir(join(outDir, "assets"))).filter((f) => f.endsWith(".js"));
const code = (await Promise.all(files.map((f) => readFile(join(outDir, "assets", f), "utf8")))).join("\n");
for (const banned of ['"/preview"', "Preview password", "preview-password", "Reviewer sign-in", "Connect your Azure model", "Save session connection", "Azure endpoint"])
expect(code.includes(banned), banned).toBe(false);
// Try a fictional patient is still there.
expect(code.includes('"/demo"')).toBe(true);
expect(code.includes("Fictional demo")).toBe(true);
} finally {
vi.unstubAllEnvs();
await rm(outDir, { recursive: true, force: true });
}
}, 60_000);
});