clone

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

feat/141-effect-library
lofi / package / testing / safety_test.ts
safety_test.ts 3.1K
1import { BrowserUnavailableError, rethrowBrowserLaunchError } from "./browser_error.ts";2import { assertValueFreeState, redactDiagnosticText } from "./safety.ts";3import { readTraceArchive, sanitizeTraceArchive, writeTraceArchive } from "./trace.ts";45function assert(condition: unknown, message: string): asserts condition {6 if (!condition) throw new Error(message);7}89Deno.test("value-free snapshots retain shape and reject values", () => {10 assertValueFreeState({ online: false, itemCount: 2, clients: [true, null] });11 for (12 const invalid of [13 { title: "private value" },14 { value: Number.NaN },15 new Date(),16 ]17 ) {18 let rejected = false;19 try {20 assertValueFreeState(invalid);21 } catch {22 rejected = true;23 }24 assert(rejected, `unsafe state was accepted: ${String(invalid)}`);25 }26});2728Deno.test("missing Chromium reports the exact install command", () => {29 const cause = new Error("browser executable doesn't exist");30 try {31 rethrowBrowserLaunchError(cause);32 } catch (error) {33 assert(error instanceof BrowserUnavailableError, `unexpected error: ${error}`);34 assert(35 error.message.includes("deno run -A npm:playwright@1.61.1 install chromium"),36 error.message,37 );38 assert(error.cause === cause, "browser launch failure was not retained");39 return;40 }41 throw new Error("missing browser error was not thrown");42});4344Deno.test("diagnostic redaction strips URL, JSON and literal credentials", () => {45 const input =46 'request https://user:pass@example.test/path?token=query#fragment {"authorization":"Bearer auth-value"} token=plain literal-value';47 const output = redactDiagnosticText(input, ["literal-value"]);48 assert(!output.includes("user:pass"), output);49 assert(!output.includes("query"), output);50 assert(!output.includes("fragment"), output);51 assert(!output.includes("auth-value"), output);52 assert(!output.includes("plain"), output);53 assert(!output.includes("literal-value"), output);54 assert(output.includes("https://example.test/path"), output);55});5657Deno.test("trace archives are sanitized without losing their structure", async () => {58 const directory = await Deno.makeTempDir({ dir: "." });59 const path = `${directory}/trace.zip`;60 try {61 const trace =62 '{"type":"console","text":"token=trace-secret","authorization":"Bearer auth-secret"}\n';63 await Deno.writeFile(64 path,65 writeTraceArchive({66 "trace.trace": new TextEncoder().encode(trace),67 "resources/private.dat": new TextEncoder().encode("literal-private-resource"),68 }),69 );70 await sanitizeTraceArchive(path, (value) => redactDiagnosticText(value, ["trace-secret"]));71 const entries = await readTraceArchive(path);72 const result = new TextDecoder().decode(entries["trace.trace"]);73 assert(!result.includes("trace-secret"), result);74 assert(!result.includes("auth-secret"), result);75 assert(result.includes("[redacted]"), result);76 JSON.parse(result);77 assert(!("resources/private.dat" in entries), "private trace resource was retained");78 } finally {79 await Deno.remove(directory, { recursive: true });80 }81});