clone

a self-hosted sync node for lofi apps: jazz sync over iroh, ticket-gated, with no static ip or cloud needed

release/0.4.0
lofi-node / tests / verdict_test.ts
verdict_test.ts 2.1K
1// The taxonomy contract: consumers act on the code's classification, never on2// the reason string, and unknown codes fail safe (keep waiting, never3// compensate).45import { assert, assertEquals } from "@std/assert";6import {7 classifyMutationError,8 isPermanentMutationError,9 MUTATION_ERROR_CLASSES,10} from "../src/verdict.ts";1112Deno.test("verdict: permission_denied is permanent", () => {13 assertEquals(classifyMutationError("permission_denied"), "permanent");14 assert(isPermanentMutationError("permission_denied"));15});1617Deno.test("verdict: transaction_conflict is permanent", () => {18 assertEquals(classifyMutationError("transaction_conflict"), "permanent");19 assert(isPermanentMutationError("transaction_conflict"));20});2122Deno.test("verdict: permissions_head_missing is permanent", () => {23 assertEquals(classifyMutationError("permissions_head_missing"), "permanent");24 assert(isPermanentMutationError("permissions_head_missing"));25});2627Deno.test("verdict: expired is permanent", () => {28 assertEquals(classifyMutationError("expired"), "permanent");29 assert(isPermanentMutationError("expired"));30});3132Deno.test("verdict: invalid_batch_submission stays unregistered (transient)", () => {33 // Unreachable from the public API by construction (the registry doc comment34 // records why); it must not classify permanent until a rejection carrying it35 // has actually been observed.36 assertEquals(classifyMutationError("invalid_batch_submission"), "transient");37 assertEquals(isPermanentMutationError("invalid_batch_submission"), false);38});3940Deno.test("verdict: unknown codes classify transient", () => {41 for (42 const code of ["", "store_unreachable", "some_future_code", "PERMISSION_DENIED", "EXPIRED"]43 ) {44 assertEquals(classifyMutationError(code), "transient", `code ${JSON.stringify(code)}`);45 assertEquals(isPermanentMutationError(code), false);46 }47});4849Deno.test("verdict: the registry only holds valid classes", () => {50 for (const [code, klass] of Object.entries(MUTATION_ERROR_CLASSES)) {51 assert(klass === "permanent" || klass === "transient", `code ${code}`);52 }53});