diff options
| author | Yuriy Andamasov <yuriy@vyos.io> | 2026-07-22 16:11:16 +0300 |
|---|---|---|
| committer | Yuriy Andamasov <yuriy@vyos.io> | 2026-07-22 16:11:16 +0300 |
| commit | f1fc5d8d45242c3b259ce216c0705e828a51fb2a (patch) | |
| tree | b801641bf8d502254f3d4e8b9005e9c84dcedf96 /workers/branch/test | |
| parent | cce3f36602e285a13efe02bf8906f871f04c5ada (diff) | |
| download | vyos-documentation-claude/html-handling-parity.tar.gz vyos-documentation-claude/html-handling-parity.zip | |
workers: html_handling none + worker index-mapping — RTD .html URL parity (smoke 307 fix)claude/html-handling-parity
Diffstat (limited to 'workers/branch/test')
| -rw-r--r-- | workers/branch/test/content.test.ts | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/workers/branch/test/content.test.ts b/workers/branch/test/content.test.ts index fcf068da..807b1dd1 100644 --- a/workers/branch/test/content.test.ts +++ b/workers/branch/test/content.test.ts @@ -78,3 +78,98 @@ describe("default fetch entrypoint", () => { expect(resp.headers.get("Cache-Control")).toBe("no-store"); }); }); + +describe("directory-index mapping (html_handling \"none\", §3.2.3 amended 2026-07-22)", () => { + // Assets binding stub emulating html_handling:"none": exact-path lookups only — + // no extension inference and no directory auto-index. A bare "/foo/" therefore only + // resolves because the worker rewrites it to "/foo/index.html" before this runs, which + // is exactly the RTD-parity behavior under test. + const ASSET_MAP: Record<string, string> = { + "/en/rolling/index.html": "<html>root index</html>", + "/en/rolling/cli.html": "<html>cli page</html>", + "/en/rolling/guide/index.html": "<html>guide index</html>", + }; + + const makeAssetsEnv = (docsEnv: Env["DOCS_ENV"], seen: string[]): Env => ({ + ASSETS: { + fetch: async (req: Request) => { + seen.push(req.url); + const body = ASSET_MAP[new URL(req.url).pathname]; + return body === undefined + ? new Response("not found", { status: 404, headers: { "content-type": "text/html" } }) + : new Response(body, { headers: { "content-type": "text/html" } }); + }, + } as unknown as Fetcher, + DOCS_BUILD_SHA: "testsha", + DOCS_ENV: docsEnv, + }); + + it("trailing-slash directory URL is mapped to index.html → 200 + index content", async () => { + const seen: string[] = []; + const resp = await worker.fetch( + new Request("https://docs.vyos.io/en/rolling/"), + makeAssetsEnv("production", seen), + ); + expect(resp.status).toBe(200); + expect(await resp.text()).toBe("<html>root index</html>"); + // worker rewrote "/en/rolling/" → "/en/rolling/index.html" before hitting ASSETS + expect(seen).toEqual(["https://docs.vyos.io/en/rolling/index.html"]); + // 200 still carries the build stamp + the page cache class + expect(resp.headers.get("X-Docs-Build")).toBe("testsha"); + expect(resp.headers.get("Cache-Control")) + .toBe("public, max-age=0, s-maxage=300, must-revalidate"); + }); + + it("explicit .html URL is served directly — 200, never a 3xx redirect", async () => { + const seen: string[] = []; + const resp = await worker.fetch( + new Request("https://docs.vyos.io/en/rolling/cli.html"), + makeAssetsEnv("production", seen), + ); + expect(resp.status).toBe(200); + expect(resp.status).toBeLessThan(300); // no 307/308 for explicit .html paths + expect(await resp.text()).toBe("<html>cli page</html>"); + // passed through unmodified — the worker never rewrites explicit-file paths + expect(seen).toEqual(["https://docs.vyos.io/en/rolling/cli.html"]); + expect(resp.headers.get("X-Docs-Build")).toBe("testsha"); + expect(resp.headers.get("Cache-Control")) + .toBe("public, max-age=0, s-maxage=300, must-revalidate"); + }); + + it("explicit nested /folder/index.html is served directly → 200", async () => { + const seen: string[] = []; + const resp = await worker.fetch( + new Request("https://docs.vyos.io/en/rolling/guide/index.html"), + makeAssetsEnv("production", seen), + ); + expect(resp.status).toBe(200); + expect(await resp.text()).toBe("<html>guide index</html>"); + expect(seen).toEqual(["https://docs.vyos.io/en/rolling/guide/index.html"]); + expect(resp.headers.get("X-Docs-Build")).toBe("testsha"); + expect(resp.headers.get("Cache-Control")) + .toBe("public, max-age=0, s-maxage=300, must-revalidate"); + }); + + it("extensionless page path (no trailing slash) is not mapped → 404", async () => { + const seen: string[] = []; + const resp = await worker.fetch( + new Request("https://docs.vyos.io/en/rolling/cli"), + makeAssetsEnv("production", seen), + ); + expect(resp.status).toBe(404); + // passed through unmodified; html_handling:"none" does not infer ".html" + expect(seen).toEqual(["https://docs.vyos.io/en/rolling/cli"]); + // a 404 must never carry a cacheable page/asset class + expect(resp.headers.get("Cache-Control")).toBe("no-store"); + }); + + it("directory mapping preserves the original query string", async () => { + const seen: string[] = []; + const resp = await worker.fetch( + new Request("https://docs.vyos.io/en/rolling/?q=foo"), + makeAssetsEnv("production", seen), + ); + expect(resp.status).toBe(200); + expect(seen).toEqual(["https://docs.vyos.io/en/rolling/index.html?q=foo"]); + }); +}); |
