import { beforeEach, describe, expect, it, vi } from "vitest";
import type { Auth } from "#lib/auth.svelte.ts";
import type { Fetch } from "#lib/fetch.ts";
vi.mock("#lib/auth/agent.ts", () => ({
mintServiceAuth: async () => "service-token",
serviceDidForHost: () => "did:web:bobbin.test"
}));
const viewer = "did:plc:viewer";
const auth = {
bobbinUrl: "https://bobbin.test",
currentDid: viewer,
agent: {}
} as unknown as Auth;
const vouch = (actor: string) => ({
actor,
uri: `at://${viewer}/org.tangled.graph.vouch/${actor}`,
value: {
$type: "org.tangled.graph.vouch",
kind: "vouch",
createdAt: "2026-01-01T00:00:00.000Z"
}
});
const respondWith = (actors: readonly string[]) =>
vi.fn<Fetch>(async (input) => {
const requested = new URL(String(input)).searchParams.getAll("actors");
return new Response(
JSON.stringify({
items: requested.flatMap((a) => (actors.includes(a) ? [vouch(a)] : []))
}),
{
status: 200,
headers: { "content-type": "application/json" }
}
);
});
const freshModule = async () => {
vi.resetModules();
return import("#lib/components/profile/vouchBadge.svelte.ts");
};
describe("network vouch batching", () => {
beforeEach(() => {
vi.unstubAllGlobals();
});
it("coalesces every actor asked for in one tick into a single request", async () => {
const fetchMock = respondWith(["did:plc:a", "did:plc:b"]);
vi.stubGlobal("fetch", fetchMock);
const { networkVouchesFor } = await freshModule();
const [first, second, again] = await Promise.all([
networkVouchesFor(auth, "did:plc:a"),
networkVouchesFor(auth, "did:plc:b"),
networkVouchesFor(auth, "did:plc:a")
]);
expect(fetchMock).toHaveBeenCalledTimes(1);
expect(new URL(String(fetchMock.mock.calls[0][0])).searchParams.getAll("actors")).toEqual([
"did:plc:a",
"did:plc:b"
]);
expect(first.map((item) => item.actor)).toEqual(["did:plc:a"]);
expect(second.map((item) => item.actor)).toEqual(["did:plc:b"]);
expect(again).toEqual(first);
});
it("serves a later ask for the same actor from cache", async () => {
const fetchMock = respondWith(["did:plc:c"]);
vi.stubGlobal("fetch", fetchMock);
const { networkVouchesFor } = await freshModule();
await networkVouchesFor(auth, "did:plc:c");
await networkVouchesFor(auth, "did:plc:c");
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it("asks for nothing when the viewer is signed out", async () => {
const fetchMock = respondWith([]);
vi.stubGlobal("fetch", fetchMock);
const { networkVouchesFor } = await freshModule();
await expect(networkVouchesFor(undefined, "did:plc:d")).resolves.toEqual([]);
await expect(
networkVouchesFor({ ...auth, agent: null } as unknown as Auth, "did:plc:d")
).resolves.toEqual([]);
expect(fetchMock).not.toHaveBeenCalled();
});
});