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 / DeviceStatus_test.tsx
DeviceStatus_test.tsx 1.9K
1import { describeSyncState } from "./DeviceStatus.tsx";23// The report's contract after the sync-state integrity pass: a reader must be4// able to tell *why* nothing is syncing. Each blocked disposition names its5// cause, and the precedence puts the most specific cause first — an owner6// mismatch explains more than a store answer, a store refusal more than a7// missing sink.8Deno.test("describeSyncState names each blocked disposition first-class", () => {9 const base = {10 syncing: false,11 syncAvailable: false,12 ownerMismatch: false,13 storeState: "unchecked" as const,14 sinkUnopenable: false,15 };16 const cases: [Parameters<typeof describeSyncState>[0], string][] = [17 [{ ...base, ownerMismatch: true, syncing: true }, "another account"],18 [{ ...base, storeState: "no_schema", syncing: true }, "no schema"],19 [{ ...base, storeState: "ticket_rejected", syncing: true }, "ticket no longer accepted"],20 [{ ...base, sinkUnopenable: true }, "unopenable"],21 [{ ...base, syncing: true, syncAvailable: true }, "syncing to your account"],22 [{ ...base, syncAvailable: true }, "not yet backed up"],23 [base, "local-only"],24 ];25 for (const [input, needle] of cases) {26 const verdict = describeSyncState(input);27 if (!verdict.includes(needle)) {28 throw new Error(`disposition lost its cause: ${JSON.stringify(input)} → ${verdict}`);29 }30 }31});3233// The owner mismatch outranks every other explanation: transport is suppressed34// because of it, so store-level answers describe a connection that is not35// being attempted.36Deno.test("describeSyncState puts the owner mismatch above store answers", () => {37 const verdict = describeSyncState({38 syncing: true,39 syncAvailable: true,40 ownerMismatch: true,41 storeState: "no_schema",42 sinkUnopenable: false,43 });44 if (!verdict.includes("another account")) {45 throw new Error(`owner mismatch was outranked: ${verdict}`);46 }47});