syntaxai/tdd.md · main · src / b51_render_layout.test.ts

b51_render_layout.test.ts 60 lines · 2172 bytes raw
// Sibling test for c51_render_layout.ts (Layer 1, render). The page
// chrome plus the `escape` HTML-escaper. End-to-end coverage at every
// route that renders HTML; this sibling pins the pure helpers.

import { describe, test, expect } from "bun:test";
import { escape, renderPage, renderNotFound, htmlResponse } from "./b51_render_layout.ts";

describe("c51_render_layout — escape (HTML entity escaping)", () => {
  test("escapes ampersand, lt, gt, double-quote", () => {
    expect(escape("&")).toBe("&");
    expect(escape("<")).toBe("&lt;");
    expect(escape(">")).toBe("&gt;");
    expect(escape('"')).toBe("&quot;");
  });

  test("escapes ampersand FIRST so we don't double-escape", () => {
    // Naive ordering ("<&" → "&lt;&" then & → "&lt;&amp;") would
    // produce "&amp;lt;&amp;" if the order were wrong.
    expect(escape("<&>")).toBe("&lt;&amp;&gt;");
  });

  test("passes plain text through unchanged", () => {
    expect(escape("hello world")).toBe("hello world");
  });
});

describe("c51_render_layout — renderPage", () => {
  test("renders a complete HTML document with the supplied title", async () => {
    const html = await renderPage({
      title: "Hello",
      description: "Test page",
      bodyMarkdown: "# Hi\n\nbody",
      ogPath: "https://tdd.md/test",
    });
    expect(html).toContain("<!doctype html>");
    expect(html).toContain("<title>Hello");
    expect(html).toContain("body");
  });
});

describe("c51_render_layout — renderNotFound + htmlResponse", () => {
  test("renderNotFound produces a 404-friendly body string", async () => {
    const html = await renderNotFound("/nonexistent");
    expect(html).toContain("<!doctype html>");
    expect(html).toMatch(/not.found|404/i);
  });

  test("htmlResponse wraps a string in a 200 Response with text/html", async () => {
    const r = htmlResponse("<p>hi</p>");
    expect(r.status).toBe(200);
    expect(r.headers.get("content-type")).toMatch(/text\/html/);
    expect(await r.text()).toBe("<p>hi</p>");
  });

  test("htmlResponse honours the optional status arg", () => {
    const r = htmlResponse("<p>nope</p>", 404);
    expect(r.status).toBe(404);
  });
});