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 / preact / TicketEnrollForm_test.tsx
TicketEnrollForm_test.tsx 2.4K
1import { render } from "npm:preact-render-to-string@6.7.0";2import { describeEnrollmentProblem, TicketEnrollForm } from "./TicketEnrollForm.tsx";3import { SyncEnrollmentError } from "../runtime/session.ts";4import { SyncOwnerError } from "../runtime/sync-owner.ts";56// The form's manager-facing semantics are the contract: password managers key7// on a real form with a current-password field, a username companion, and a8// genuine submit button. These assertions pin exactly the markup those9// heuristics need.10Deno.test("TicketEnrollForm renders password-manager-compatible form semantics", () => {11 const html = render(<TicketEnrollForm />);12 for (13 const needle of [14 "<form",15 'type="password"',16 'autocomplete="current-password"',17 'autocomplete="username"',18 'type="submit"',19 ]20 ) {21 if (!html.includes(needle)) throw new Error(`manager-facing markup omitted: ${needle}`);22 }23});2425// The typed refusals carry their own remediation; the form must not flatten26// them into the generic "paste it again" line — re-pasting cannot fix an27// unprovisioned store or a foreign sync owner.28Deno.test("describeEnrollmentProblem relays typed refusals verbatim", () => {29 const cases: [Error, string][] = [30 [new SyncEnrollmentError("no_schema", "sync"), "no schema deployed"],31 [new SyncEnrollmentError("ticket_rejected"), "revoked or the node was reset"],32 [new SyncOwnerError("alice"), "set up by a different account"],33 ];34 for (const [error, needle] of cases) {35 const problem = describeEnrollmentProblem(error);36 if (problem !== error.message) {37 throw new Error(`typed refusal was rewritten: ${problem}`);38 }39 if (!problem.includes(needle)) {40 throw new Error(`refusal message lost its remediation: ${problem}`);41 }42 }43});4445Deno.test("describeEnrollmentProblem keeps the generic line for unknown failures", () => {46 const problem = describeEnrollmentProblem(new TypeError("fetch failed"));47 if (!problem.includes("check the ticket and the node")) {48 throw new Error(`unknown failure leaked internals: ${problem}`);49 }50});5152Deno.test("TicketEnrollForm states the custody story without overclaiming", () => {53 const html = render(<TicketEnrollForm />);54 if (!html.includes("bearer credential")) {55 throw new Error("the ticket's bearer nature was hidden");56 }57 if (!html.includes("password manager")) {58 throw new Error("the manager custody guidance was omitted");59 }60});