Menu
Public repository / 3af23b0e937520000e1aa43c7e2eb9de2675abd1
AkurAI-Mail / src/framework/sync-state.test.js
Latest change ecdd82c68dc11022c41dbf1ff22cac68e002a3e1 - OLI-247: wave 2 — signal-badge view model and signals-based sync state on framework runtime by Ólafur Búi Ólafsson
// @ts-nocheck
import { afterEach, describe, expect, jest, test } from "bun:test";
import { createSyncState } from "./sync-state.js";
describe("framework sync state (signals)", () => {
test("starts idle, never synced, no error", () => {
const s = createSyncState();
expect([s.status(), s.lastSyncAt(), s.errorKind(), s.dismissed(), s.retryCount()]).toEqual(["idle", null, null, false, 0]);
});
test("reportSuccess clears error, resets retries, stamps time", () => {
const s = createSyncState(() => 1234);
s.reportError("offline");
s.reportSuccess();
expect([s.errorKind(), s.retryCount(), s.lastSyncAt(), s.status()]).toEqual([null, 0, 1234, "idle"]);
});
test("reportError schedules backoff retry, except auth-expired", () => {
const timers = [];
const s = createSyncState(Date.now, (fn, ms) => { timers.push(ms); return timers.length; }, () => {});
s.reportError("offline", () => {});
s.reportError("server-error", () => {});
s.reportError("auth-expired", () => {});
expect(timers).toEqual([2000, 4000]);
expect(s.errorKind()).toBe("auth-expired");
});
test("dismiss hides until the next error", () => {
const s = createSyncState();
s.reportError("offline");
s.dismiss();
expect(s.dismissed()).toBe(true);
s.reportError("offline");
expect(s.dismissed()).toBe(false);
});
test("retryNow cancels the pending timer and runs", () => {
const cleared = [];
const s = createSyncState(Date.now, () => 7, (id) => cleared.push(id));
s.reportError("offline", () => {});
let ran = false;
s.retryNow(() => { ran = true; });
expect(cleared).toEqual([7]);
expect(ran).toBe(true);
});
});