import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; import { cpSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { request as httpRequest } from "node:http"; import type { AddressInfo } from "node:net"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { after, before, test } from "node:test"; import { fileURLToPath } from "node:url"; import ejs from "ejs"; import { createApp } from "./app.ts"; import { createLogger } from "../logger.ts"; import { CSRF_COOKIE } from "../auth/csrf.ts"; import { staticJwks } from "../auth/jwks.ts"; import type { Plugin } from "../plugin-host/plugin.ts"; import { ENGLISH_LOCALS } from "../i18n/view-locals.ts"; import { ecJwk, session, startApp } from "./app-harness.ts"; const viewsDir = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "views"); const server = createApp({ jwks: staticJwks([ecJwk]) }); let base = ""; before(async () => { await new Promise((resolve) => server.listen(0, resolve)); base = `http://localhost:${(server.address() as AddressInfo).port}`; }); after(() => server.close()); test("the dashboard at /dashboard: the instructional starter in the unified shell, gated to a session", async () => { // The dashboard is gated to a signed-in user, so present a session. const res = await fetch(base + "/dashboard", { headers: { cookie: session() } }); assert.equal(res.status, 200); assert.match(res.headers.get("content-type") ?? "", /text\/html/); const html = await res.text(); // The unified app shell: the same sidebar/menu every page renders. assert.match(html, /Plainpages/); // sidebar brand assert.match(html, /