electron/companion-settings.node-test.mjs
Rama main · réplica de lectura del repositorio original.
import assert from "node:assert/strict";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import {
COMPANION_SETTINGS_VERSION, RECENT_DEVICE_MS, anyRouteOn, companionDevicesFile, countPairedPhones, defaultCompanionSettings, directRoutesOn,
hasTailnetAddress, phoneLinkShouldSleep, phoneLinkStartsAtLaunch, readCompanionSettings, setRoute,
} from "./companion-settings.mjs";
const NOW = 1_800_000_000_000;
const on = (routes) => routes.reduce((settings, route) => setRoute(settings, route, true, { now: NOW }), defaultCompanionSettings());
const here = { remoteClient: false, serverReady: true, settings: on(["wifi"]), pairedPhones: 1 };
test("every way in is off on a new install", () => {
const settings = readCompanionSettings(null);
assert.equal(anyRouteOn(settings), false);
assert.deepEqual(settings.notices, []);
});
test("the phone link starts at launch only for this computer's own server, with a way in on and a device paired", () => {
assert.equal(phoneLinkStartsAtLaunch(here), true);
assert.equal(phoneLinkStartsAtLaunch({ ...here, remoteClient: true }), false, "a desktop that is only a client of another computer");
assert.equal(phoneLinkStartsAtLaunch({ ...here, serverReady: false }), false, "no server of its own running");
assert.equal(phoneLinkStartsAtLaunch({ ...here, settings: defaultCompanionSettings() }), false, "every way in off");
assert.equal(phoneLinkStartsAtLaunch({ ...here, pairedPhones: 0 }), false, "on, but nothing paired: it sleeps");
assert.equal(phoneLinkStartsAtLaunch({ ...here, pairedPhones: null }), false, "the paired list could not be read");
});
test("an empty sidecar sleeps; one with a device or an open code stays", () => {
assert.equal(phoneLinkShouldSleep({ enabled: true, devices: [], pairing: null }), true);
assert.equal(phoneLinkShouldSleep({ enabled: true, devices: [{ id: "a" }], pairing: null }), false);
assert.equal(phoneLinkShouldSleep({ enabled: true, devices: [], pairing: { code: "1" } }), false);
assert.equal(phoneLinkShouldSleep({ enabled: true, devices: [], pairing: null, devicesUnreadable: true }), false);
assert.equal(phoneLinkShouldSleep({ enabled: false, devices: [], pairing: null }), false);
});
test("each route is its own switch; turning one off drops its notice", () => {
let settings = setRoute(defaultCompanionSettings(), "tailscale", true, { now: NOW, name: "mac.tail1.ts.net" });
assert.deepEqual(directRoutesOn(settings), { wifi: false, tailscale: true });
assert.deepEqual(settings.routes.tailscale, { on: true, since: NOW, name: "mac.tail1.ts.net" });
settings = { ...settings, notices: ["tailscale"] };
settings = setRoute(settings, "tailscale", false);
assert.deepEqual(settings.routes.tailscale, { on: false, since: null });
assert.deepEqual(settings.notices, []);
});
const device = (overrides = {}) => ({ id: "d", lastSeenAt: NOW - 60_000, routes: "any", e2eAt: NOW - 1e9, ...overrides });
const migrate = (facts, raw = { enabled: true, keepAwake: true }) => readCompanionSettings(raw, { now: NOW, ...facts });
const kept = (settings) => Object.entries(settings.routes).filter(([, route]) => route.on).map(([name]) => name);
test("the update turns everything off when nothing was paired, and keeps nothing on silently", () => {
assert.deepEqual(kept(migrate({ devices: [] })), []);
assert.deepEqual(kept(migrate({ devices: [device()] }, { enabled: false })), []);
const stale = migrate({ devices: [device({ lastSeenAt: NOW - RECENT_DEVICE_MS - 1 })], tailnetAddress: true, managedAddress: true });
assert.deepEqual(kept(stale), [], "a device not seen in 30 days keeps nothing on");
});
test("the update keeps on what a recently seen device could use, each with a notice", () => {
const phone = migrate({ devices: [device()], managedAddress: true });
assert.deepEqual(kept(phone), ["wifi", "relay", "https"]);
assert.deepEqual(phone.notices, ["wifi", "relay", "https"]);
assert.equal(phone.keepAwake, true);
assert.equal(phone.version, COMPANION_SETTINGS_VERSION);
assert.deepEqual(kept(migrate({ devices: [device({ routes: "local" })], managedAddress: true })), ["wifi"], "a home-only device keeps Same Wi-Fi only");
assert.deepEqual(kept(migrate({ devices: [device({ e2eAt: undefined })] })), ["wifi"], "an old app has no relay");
const tailnet = migrate({ devices: [device({ routes: "local" })], tailnetAddress: true });
assert.deepEqual(kept(tailnet), ["wifi", "tailscale"]);
assert.equal(tailnet.routes.tailscale.name, null, "the name is asked for only on Check again");
});
test("settings already in the new shape are read as written", () => {
const written = { ...on(["relay"]), notices: ["relay", "wifi"] };
const read = readCompanionSettings(JSON.parse(JSON.stringify(written)), { devices: [device()], tailnetAddress: true });
assert.deepEqual(kept(read), ["relay"]);
assert.deepEqual(read.notices, ["relay"], "a notice for a route that is off is dropped");
assert.equal(readCompanionSettings({ version: COMPANION_SETTINGS_VERSION, routes: { wifi: { on: "yes" } } }).routes.wifi.on, false);
});
test("paired devices are read from the companion's own store", () => {
const dir = mkdtempSync(path.join(tmpdir(), "omb-companion-settings-"));
try {
const file = companionDevicesFile({ OMB_COMPANION_DIR: dir });
assert.equal(file, path.join(dir, "devices.json"));
assert.equal(countPairedPhones(file), 0, "nothing paired yet");
writeFileSync(file, JSON.stringify({ devices: [{ id: "a" }, { id: "b" }] }));
assert.equal(countPairedPhones(file), 2);
writeFileSync(file, "{not json");
assert.equal(countPairedPhones(file), null);
} finally {
rmSync(dir, { recursive: true, force: true });
}
});
test("Tailscale is seen by its own interface, never by a 100.64/10 address alone", () => {
assert.equal(hasTailnetAddress({ en0: [{ family: "IPv4", address: "192.168.1.4" }] }), false);
assert.equal(hasTailnetAddress({ utun4: [{ family: "IPv4", address: "100.101.2.3" }] }), false, "carrier NAT or another VPN");
assert.equal(hasTailnetAddress({ en0: [{ family: "IPv4", address: "100.80.0.1" }] }), false);
assert.equal(hasTailnetAddress({ utun4: [{ family: "IPv4", address: "100.101.2.3" }, { family: "IPv6", address: "fd7a:115c:a1e0::1" }] }), true);
assert.equal(hasTailnetAddress({ tailscale0: [{ family: "IPv4", address: "100.70.0.1" }] }), true);
assert.equal(hasTailnetAddress({ Tailscale: [{ family: "IPv4", address: "100.70.0.1" }] }), true);
});
test("the switch for other computers lives on the Tailscale route and goes with it", () => {
const on = setRoute(defaultCompanionSettings(), "tailscale", true, { now: 5, name: "mac.tail1.ts.net" });
assert.equal(on.routes.tailscale.computers, undefined, "off unless the person turns it on");
const shared = setRoute(on, "tailscale", true, { now: 6, computers: true });
assert.deepEqual(shared.routes.tailscale, { on: true, since: 5, name: "mac.tail1.ts.net", computers: true });
assert.equal(setRoute(shared, "tailscale", true, { now: 7, name: "mac.tail1.ts.net" }).routes.tailscale.computers, true, "a name refresh keeps it");
assert.equal(setRoute(shared, "tailscale", true, { now: 7, computers: false }).routes.tailscale.computers, undefined);
assert.deepEqual(setRoute(shared, "tailscale", false).routes.tailscale, { on: false, since: null });
const read = readCompanionSettings({ version: COMPANION_SETTINGS_VERSION, routes: { tailscale: { on: true, since: 5, name: "mac.tail1.ts.net", computers: "yes" } } });
assert.equal(read.routes.tailscale.computers, undefined, "anything but true is off: this opens a listener");
});