import { describe, it, expect, vi, beforeEach } from "vitest"; import { get } from "svelte/store"; // UT-069: `isConnected` must follow backend server reachability ALONE, never // navigator.onLine. See docs/specs/offline-downloaded-only-filter.md (DR-079). // // The connectivity store registers a `connectivity:changed` listener at import // time and mirrors its payload into `isServerReachable`. We capture that // listener via the mocked `listen`, then drive reachability directly while // pinning navigator.onLine to the *opposite* value to prove it is ignored. const h = vi.hoisted(() => { const listeners = new Map void>(); return { listeners }; }); vi.mock("@tauri-apps/api/event", () => ({ listen: vi.fn(async (name: string, cb: (event: { payload: unknown }) => void) => { h.listeners.set(name, cb); return () => h.listeners.delete(name); }), })); vi.mock("$lib/api/bindings", () => ({ commands: { connectivityCheckServer: vi.fn(async () => true), connectivityGetStatus: vi.fn(async () => ({ isServerReachable: true, lastChecked: null, connectionError: null, isChecking: false, })), connectivitySetServerUrl: vi.fn(async () => {}), connectivityStartMonitoring: vi.fn(async () => {}), connectivityStopMonitoring: vi.fn(async () => {}), }, })); vi.mock("$app/environment", () => ({ browser: true })); function setNavigatorOnLine(value: boolean) { Object.defineProperty(window.navigator, "onLine", { configurable: true, get: () => value, }); } function emitReachable(isReachable: boolean) { const cb = h.listeners.get("connectivity:changed"); if (!cb) throw new Error("connectivity:changed listener was not registered"); cb({ payload: { isReachable } }); } describe("isConnected follows server reachability alone (UT-069)", () => { beforeEach(() => { h.listeners.clear(); vi.resetModules(); // fresh connectivity module ⇒ re-registers its listener }); it("is false when the server is unreachable even though navigator.onLine is true", async () => { setNavigatorOnLine(true); const { isConnected } = await import("./connectivity"); emitReachable(false); expect(get(isConnected)).toBe(false); }); it("is true when the server is reachable even though navigator.onLine is false", async () => { setNavigatorOnLine(false); const { isConnected } = await import("./connectivity"); emitReachable(true); expect(get(isConnected)).toBe(true); }); });