The connectivity store now drives the "downloaded only" view so an offline library page shows just on-device media, with the server catalog revealed only when "Show all server media" is toggled. TRACES: UR-052 | DR-078, DR-079
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
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<string, (event: { payload: unknown }) => 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);
|
|
});
|
|
});
|