clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/184-task-notice-migration
lofi / package / tooling / csp_test.ts
csp_test.ts 2.1K
1// CSP tooling contract: meta parsing, policy union, warning analysis, and2// the header snippet.3import { cspPolicyWarnings, mergeCspPolicies, parseCspMeta, renderHeadersSnippet } from "./csp.ts";4import { assert } from "../runtime/test-assert.ts";56Deno.test("parseCspMeta extracts and entity-decodes the policy", () => {7 const html = `<html><head><meta http-equiv="content-security-policy" content="script-src ` +8 `&#39;self&#39; &#39;sha256-abc&#39;; style-src &#39;self&#39;"></head><body></body></html>`;9 const policy = parseCspMeta(html);10 assert(11 policy === "script-src 'self' 'sha256-abc'; style-src 'self'",12 `unexpected parse: ${policy}`,13 );14 assert(parseCspMeta("<html><head></head></html>") === null, "no meta must parse to null");15});1617Deno.test("mergeCspPolicies unions directive values and dedupes", () => {18 const merged = mergeCspPolicies([19 "script-src 'self' 'sha256-a'; style-src 'self'",20 "script-src 'self' 'sha256-b'; style-src 'self' 'sha256-s'; object-src 'none'",21 ]);22 assert(23 merged === "script-src 'self' 'sha256-a' 'sha256-b'; style-src 'self' 'sha256-s'; " +24 "object-src 'none'",25 `unexpected union: ${merged}`,26 );27});2829Deno.test("cspPolicyWarnings flags weakenings and stays quiet otherwise", () => {30 const clean = cspPolicyWarnings(31 "script-src 'self' 'wasm-unsafe-eval' 'sha256-a'; object-src 'none'",32 );33 assert(clean.length === 0, `clean policy warned: ${clean.join(" | ")}`);34 const inline = cspPolicyWarnings("script-src 'self' 'unsafe-inline'");35 assert(inline.some((w) => w.includes("unsafe-inline")), "unsafe-inline must warn");36 const remote = cspPolicyWarnings("script-src 'self' https://cdn.example.com");37 assert(remote.some((w) => w.includes("cdn.example.com")), "remote origins must warn");38});3940Deno.test("the headers snippet carries the policy and frame-ancestors", () => {41 const snippet = renderHeadersSnippet("script-src 'self'");42 assert(43 snippet.includes("Content-Security-Policy: script-src 'self'; frame-ancestors 'none'"),44 "snippet must render the full header",45 );46 assert(snippet.startsWith("#"), "snippet must lead with its commentary");47});