sync-settings.test.ts

3.6 KB · raw

1import { beforeEach, describe, expect, it, vi } from "vitest";2import { DEFAULT_RELAY_URL } from "../shared/rendezvous";34const setRelayUrlForAllPairedDevices = vi.fn(async (_relayUrl: string) => undefined);5vi.mock("./paired-devices", () => ({6  setRelayUrlForAllPairedDevices: (url: string) => setRelayUrlForAllPairedDevices(url),7}));89import {10  getSyncSettings,11  isPrivateRelayUnconfigured,12  relayInForce,13  setRelayUrl,14  setSyncMode,15} from "./sync-settings";1617const PRIVATE_RELAY = "wss://relay.example.com";1819let store: Record<string, unknown> = {};2021beforeEach(() => {22  store = {};23  setRelayUrlForAllPairedDevices.mockClear();24  (globalThis as unknown as { chrome: unknown }).chrome = {25    storage: {26      local: {27        get: async (keys: string[]) =>28          Object.fromEntries(keys.filter((k) => k in store).map((k) => [k, store[k]])),29        set: async (values: Record<string, unknown>) => {30          Object.assign(store, values);31        },32      },33    },34  };35});3637describe("sync settings migration", () => {38  it("defaults to public relay with nothing stored", async () => {39    expect(await getSyncSettings()).toEqual({ mode: "public", relayUrl: DEFAULT_RELAY_URL });40  });4142  it("maps the retired lanOnly flag to off, never to public", async () => {43    store.peach_sync_lan_only_v1 = true;44    expect((await getSyncSettings()).mode).toBe("off");45  });4647  it("maps a configured custom relay with no stored mode to private", async () => {48    store.peach_relay_url_v1 = PRIVATE_RELAY;49    expect(await getSyncSettings()).toEqual({ mode: "private", relayUrl: PRIVATE_RELAY });50  });5152  it("keeps a configured private relay through off and back", async () => {53    await setRelayUrl(PRIVATE_RELAY);54    await setSyncMode("off");55    expect((await getSyncSettings()).relayUrl).toBe(PRIVATE_RELAY);56    expect(await setSyncMode("private")).toEqual({ mode: "private", relayUrl: PRIVATE_RELAY });57  });58});5960describe("relayInForce", () => {61  it("returns the relay under public and private", async () => {62    expect(relayInForce(await getSyncSettings())).toBe(DEFAULT_RELAY_URL);63    expect(relayInForce(await setRelayUrl(PRIVATE_RELAY))).toBe(PRIVATE_RELAY);64  });6566  it("refuses when sync is off", async () => {67    expect(() => relayInForce({ mode: "off", relayUrl: DEFAULT_RELAY_URL })).toThrow("sync_disabled");68  });6970  // Adoption hands the source's relay over setRelayUrl. When that relay is71  // Peach's own, the joining device must land on `public` — labelling it72  // `private` would strand it in the fail-closed state below.73  it("stays public when the adopted relay is Peach's own", async () => {74    const settings = await setRelayUrl(DEFAULT_RELAY_URL);75    expect(settings.mode).toBe("public");76    expect(relayInForce(settings)).toBe(DEFAULT_RELAY_URL);77  });7879  it("refuses private with no URL rather than falling back to the public relay", async () => {80    const settings = await setSyncMode("private");81    expect(isPrivateRelayUnconfigured(settings)).toBe(true);82    expect(() => relayInForce(settings)).toThrow("private_relay_unset");83  });84});8586describe("mesh relay propagation", () => {87  it("does not push the public relay to peers when private has no URL yet", async () => {88    await setSyncMode("private");89    expect(setRelayUrlForAllPairedDevices).not.toHaveBeenCalled();90  });9192  it("pushes the relay once it is a real choice", async () => {93    await setRelayUrl(PRIVATE_RELAY);94    expect(setRelayUrlForAllPairedDevices).toHaveBeenCalledWith(PRIVATE_RELAY);95    setRelayUrlForAllPairedDevices.mockClear();96    await setSyncMode("public");97    expect(setRelayUrlForAllPairedDevices).toHaveBeenCalledWith(DEFAULT_RELAY_URL);98  });99});