import { test, expect } from "bun:test"; import { applyIsolation, connectionsFromLinks, visibleSet, isVisible, type IsolationAccessors, } from "../src/isolation"; import type { Scope } from "../src/types"; // Generic item: owner + scope. ZERO domain — the accessors read these fields. interface Item { id: string; owner: string; scope: Scope; } const acc: IsolationAccessors = { ownerOf: (i) => i.owner, scopeOf: (i) => i.scope }; // alice —— bob (carol is unconnected) const links = [{ a: "alice", b: "bob" }]; const conns = connectionsFromLinks(links); test("connectionsFromLinks / visibleSet: self + direct connections, both directions", () => { expect([...conns.neighbors("alice")].sort()).toEqual(["bob"]); expect([...conns.neighbors("bob")].sort()).toEqual(["alice"]); expect([...conns.neighbors("carol")]).toEqual([]); expect([...visibleSet("alice", conns)].sort()).toEqual(["alice", "bob"]); expect([...visibleSet("carol", conns)].sort()).toEqual(["carol"]); }); test("isVisible matrix: public=all, protected=owner+connections, private=owner", () => { const vis = visibleSet("alice", conns); // { alice, bob } // public → everyone, regardless of owner expect(isVisible("public", "carol", "alice", vis)).toBe(true); // protected → owner must be in the visible set expect(isVisible("protected", "bob", "alice", vis)).toBe(true); expect(isVisible("protected", "carol", "alice", vis)).toBe(false); // private → owner must be the current principal expect(isVisible("private", "alice", "alice", vis)).toBe(true); expect(isVisible("private", "bob", "alice", vis)).toBe(false); }); test("applyIsolation narrows a mixed collection for the current principal", () => { const items: Item[] = [ { id: "e", owner: "carol", scope: "public" }, // public → kept for all { id: "p1", owner: "alice", scope: "protected" }, // own protected → kept { id: "p2", owner: "bob", scope: "protected" }, // connection's protected → kept { id: "p3", owner: "carol", scope: "protected" }, // stranger's protected → dropped { id: "s1", owner: "alice", scope: "private" }, // own private → kept { id: "s2", owner: "bob", scope: "private" }, // connection's private → dropped ]; const forAlice = applyIsolation(items, "alice", conns, acc).map((i) => i.id); expect(forAlice).toEqual(["e", "p1", "p2", "s1"]); const forCarol = applyIsolation(items, "carol", conns, acc).map((i) => i.id); // carol sees: public + her own protected + her own private expect(forCarol).toEqual(["e", "p3"]); }); test("applyIsolation with empty principal passes everything through (hydration guard)", () => { const items: Item[] = [ { id: "s1", owner: "alice", scope: "private" }, { id: "p1", owner: "bob", scope: "protected" }, ]; expect(applyIsolation(items, "", conns, acc).map((i) => i.id)).toEqual(["s1", "p1"]); });