import { beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_RELAY_URL } from "../shared/rendezvous"; const setRelayUrlForAllPairedDevices = vi.fn(async (_relayUrl: string) => undefined); vi.mock("./paired-devices", () => ({ setRelayUrlForAllPairedDevices: (url: string) => setRelayUrlForAllPairedDevices(url), })); import { getSyncSettings, isPrivateRelayUnconfigured, relayInForce, setRelayUrl, setSyncMode, } from "./sync-settings"; const PRIVATE_RELAY = "wss://relay.example.com"; let store: Record = {}; beforeEach(() => { store = {}; setRelayUrlForAllPairedDevices.mockClear(); (globalThis as unknown as { chrome: unknown }).chrome = { storage: { local: { get: async (keys: string[]) => Object.fromEntries(keys.filter((k) => k in store).map((k) => [k, store[k]])), set: async (values: Record) => { Object.assign(store, values); }, }, }, }; }); describe("sync settings", () => { it("defaults to public relay with nothing stored", async () => { expect(await getSyncSettings()).toEqual({ mode: "public", relayUrl: DEFAULT_RELAY_URL }); }); it("maps a configured custom relay with no stored mode to private", async () => { store.peach_relay_url_v1 = PRIVATE_RELAY; expect(await getSyncSettings()).toEqual({ mode: "private", relayUrl: PRIVATE_RELAY }); }); it("keeps a configured private relay through off and back", async () => { await setRelayUrl(PRIVATE_RELAY); await setSyncMode("off"); expect((await getSyncSettings()).relayUrl).toBe(PRIVATE_RELAY); expect(await setSyncMode("private")).toEqual({ mode: "private", relayUrl: PRIVATE_RELAY }); }); }); describe("relayInForce", () => { it("returns the relay under public and private", async () => { expect(relayInForce(await getSyncSettings())).toBe(DEFAULT_RELAY_URL); expect(relayInForce(await setRelayUrl(PRIVATE_RELAY))).toBe(PRIVATE_RELAY); }); it("refuses when sync is off", async () => { expect(() => relayInForce({ mode: "off", relayUrl: DEFAULT_RELAY_URL })).toThrow("sync_disabled"); }); // Adoption hands the source's relay over setRelayUrl. When that relay is // Peach's own, the joining device must land on `public` — labelling it // `private` would strand it in the fail-closed state below. it("stays public when the adopted relay is Peach's own", async () => { const settings = await setRelayUrl(DEFAULT_RELAY_URL); expect(settings.mode).toBe("public"); expect(relayInForce(settings)).toBe(DEFAULT_RELAY_URL); }); it("refuses private with no URL rather than falling back to the public relay", async () => { const settings = await setSyncMode("private"); expect(isPrivateRelayUnconfigured(settings)).toBe(true); expect(() => relayInForce(settings)).toThrow("private_relay_unset"); }); }); describe("mesh relay propagation", () => { it("does not push the public relay to peers when private has no URL yet", async () => { await setSyncMode("private"); expect(setRelayUrlForAllPairedDevices).not.toHaveBeenCalled(); }); it("pushes the relay once it is a real choice", async () => { await setRelayUrl(PRIVATE_RELAY); expect(setRelayUrlForAllPairedDevices).toHaveBeenCalledWith(PRIVATE_RELAY); setRelayUrlForAllPairedDevices.mockClear(); await setSyncMode("public"); expect(setRelayUrlForAllPairedDevices).toHaveBeenCalledWith(DEFAULT_RELAY_URL); }); });