import test from "node:test"; import assert from "node:assert/strict"; import { getSyncStatus } from "../src/sync_status.js"; import { syncStateToBackendHelper } from "../src/runtime_services.js"; test("save status distinguishes dirty, saving, failed, connected and saved", () => { assert.equal(getSyncStatus({}, false).kind, "connecting"); assert.equal(getSyncStatus({ available: true }, false).kind, "connected"); assert.equal(getSyncStatus({ available: true, lastSavedAt: "now" }, true).kind, "pending"); assert.equal(getSyncStatus({ pendingWrites: 1 }, true).kind, "saving"); assert.equal(getSyncStatus({ available: true, writeError: "failed" }, true).kind, "error"); assert.equal(getSyncStatus({ available: true, lastSavedAt: "now" }, false).kind, "saved"); }); test("offline and stale contact are not displayed as a successful live connection", () => { assert.equal(getSyncStatus({ connectionChecked: true }, false).kind, "offline"); assert.equal(getSyncStatus({ available: true, lastContactAt: 1000 }, false, 17000).kind, "stale"); assert.equal(getSyncStatus({ available: true, lastContactAt: 1000 }, false, 2000).kind, "connected"); }); test("failed writes retain dirty state and a successful retry clears the error", async () => { const previousFetch = globalThis.fetch; const backend = {}; let dirty = true; const deps = { backend, t: key => key, getBackendUrl: () => "http://test", buildPersistableState: () => ({}), getLocalStateVersion: () => 1, getSyncedStateVersion: () => 0, setSyncedStateVersion: () => {}, setLocalStateDirty: value => { dirty = value; } }; try { globalThis.fetch = async () => { throw new Error("offline"); }; await syncStateToBackendHelper(deps); assert.equal(dirty, true); assert.equal(backend.pendingWrites, 0); assert.ok(backend.writeError); globalThis.fetch = async () => ({ ok: true }); await syncStateToBackendHelper(deps); assert.equal(dirty, false); assert.equal(backend.writeError, ""); assert.ok(backend.lastSavedAt); assert.equal(backend.pendingWrites, 0); } finally { globalThis.fetch = previousFetch; } });