import { describe, expect, test } from "bun:test"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; // Guards the one rule that broke the preview: an asset URL starting with "/" escapes the proxy prefix. // // Served through a path-prefix proxy the app lives under //, and only the HTML is // rewritten — a root-absolute path inside a component reaches the platform root, which answers // 200 text/html. The image is broken and the network tab shows no error, so this is worth a test // rather than a note someone reads after losing an afternoon to it. const frontendDir = dirname(fileURLToPath(import.meta.url)); const templatePath = resolve(frontendDir, "index.html"); describe("asset URLs", () => { test("index.html declares a base so relative URLs can be rewritten", async () => { const html = await Bun.file(templatePath).text(); expect(html).toMatch(//); }); test("no component uses a root-absolute asset URL", async () => { const offenders: string[] = []; for await (const relative of new Bun.Glob("**/*.tsx").scan({ cwd: frontendDir })) { const source = await Bun.file(resolve(frontendDir, relative)).text(); for (const [match] of source.matchAll(/\b(?:src|srcSet|poster)=["']\/[^/][^"']*["']/g)) { offenders.push(`${relative}: ${match}`); } } expect(offenders).toEqual([]); }); });