1234import { describe, expect, test } from "bun:test";5import { runInNewContext } from "node:vm";6import { Browser, instance } from "./browser.ts";7import { makeRepos } from "./fixture.ts";89const script = await Bun.file(new URL("../public/js/nav.js", import.meta.url)).text();10const TOKEN = "ab".repeat(32);1112function run(cookie: string) {13 const nodes: Record<string, unknown>[] = [];14 let replacement: unknown[] = [];15 const document = {16 cookie,17 querySelector: () => ({18 replaceWith: (...replaced: unknown[]) => {19 replacement = replaced;20 },21 }),22 createElement: (tag: string) => {23 const node: Record<string, unknown> = {24 tag,25 append: (...children: unknown[]) => {26 node.children = children;27 },28 };29 nodes.push(node);30 return node;31 },32 };33 runInNewContext(script, { document });34 return { nodes, replacement };35}3637describe("the signed-in navbar", () => {38 test("stays as it is without a mark carrying a form token", () => {39 for (const cookie of ["", "kepr_editor=1", `kepr_editor=${TOKEN.slice(1)}`]) {40 expect(run(cookie).replacement).toEqual([]);41 }42 });4344 test("offers admin and a log out form posting the mark's token", () => {45 const { nodes, replacement } = run(`theme=dark; kepr_editor=${TOKEN}`);46 const [admin, form] = replacement as Record<string, unknown>[];47 expect(admin).toMatchObject({ tag: "a", href: "/admin", textContent: "admin" });48 expect(form).toMatchObject({ tag: "form", method: "post", action: "/admin/sign-out" });49 const [field, button] = (form?.children ?? []) as Record<string, unknown>[];50 expect(field).toMatchObject({ tag: "input", type: "hidden", name: "form", value: TOKEN });51 expect(button).toMatchObject({ tag: "button", type: "submit", textContent: "log out" });52 expect(nodes).toHaveLength(4);53 });5455 test("the mark's token is the one log out needs", async () => {56 const repos = await makeRepos(["app"]);57 const browser = new Browser((await instance(repos.bucketDir)).app);58 await browser.signIn();59 const mark = browser.cookies.get("kepr_editor") ?? "";60 expect(mark).toMatch(/^[0-9a-f]{64}$/);61 62 browser.cookies.set("kepr_editor", "1");63 await browser.get("/admin");64 expect(browser.cookies.get("kepr_editor")).toBe(mark);65 expect((await browser.post("/admin/sign-out", { form: mark })).status).toBe(303);66 expect((await browser.get("/admin")).status).toBe(401);67 });68});