Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124import { describe, expect, it, vi } from "vitest";import { createBobbinClient, type BobbinContext } from "$lib/api/client";import { IdentityCache, type MiniDoc } from "$lib/api/identity";
const DOC: MiniDoc = { did: "did:plc:x", handle: "alice.test", pds: "https://pds.example", signing_key: "zQ3shSiLsnqpyQ4SfDTT1D8qzFEoeYT8rSDXW6o8pVY7VcRBJ"};
const docResponse = (doc: MiniDoc): Response => new Response(JSON.stringify(doc), { status: 200, headers: { "content-type": "application/json" } });
const makeCtx = (fetchMock: typeof globalThis.fetch): BobbinContext => createBobbinClient({ serviceUrl: "https://bobbin.test", fetch: fetchMock });
const deferred = <T>(): { promise: Promise<T>; resolve: (value: T) => void } => { let resolve!: (value: T) => void; const promise = new Promise<T>((r) => { resolve = r; }); return { promise, resolve };};
describe("IdentityCache.resolve", () => { it("fetches on the first miss then serves the cached document", async () => { const fetchMock = vi.fn<typeof globalThis.fetch>().mockResolvedValue(docResponse(DOC)); const cache = new IdentityCache(makeCtx(fetchMock));
const first = await cache.resolve("alice.test"); const second = await cache.resolve("alice.test");
expect(first).toEqual(DOC); expect(second).toEqual(DOC); expect(fetchMock).toHaveBeenCalledTimes(1); expect((fetchMock.mock.calls[0][0] as URL).searchParams.get("identifier")).toBe( "alice.test" ); });
it("coalesces concurrent misses for the same key into one in-flight fetch", async () => { const gate = deferred<Response>(); const fetchMock = vi.fn<typeof globalThis.fetch>().mockReturnValue(gate.promise); const cache = new IdentityCache(makeCtx(fetchMock));
const a = cache.resolve("alice.test"); const b = cache.resolve("alice.test"); expect(fetchMock).toHaveBeenCalledTimes(1);
gate.resolve(docResponse(DOC)); const [ra, rb] = await Promise.all([a, b]); expect(ra).toEqual(DOC); expect(rb).toEqual(DOC); expect(fetchMock).toHaveBeenCalledTimes(1); });
it("re-fetches after the in-flight promise settles (no permanent stampede lock)", async () => { const fetchMock = vi.fn<typeof globalThis.fetch>().mockResolvedValue(docResponse(DOC)); const cache = new IdentityCache(makeCtx(fetchMock));
await cache.resolve("bob.test"); fetchMock.mockResolvedValueOnce( docResponse({ did: "did:plc:y", handle: "carol.test", pds: "https://pds.example", signing_key: "zQ3shSiLsnqpyQ4SfDTT1D8qzFEoeYT8rSDXW6o8pVY7VcRBJ" }) ); await cache.resolve("carol.test"); expect(fetchMock).toHaveBeenCalledTimes(2); });
it("populates both directions of the index from a resolved document", async () => { const fetchMock = vi.fn<typeof globalThis.fetch>().mockResolvedValue(docResponse(DOC)); const cache = new IdentityCache(makeCtx(fetchMock));
await cache.resolve("alice.test"); expect(cache.didFor("alice.test")).toBe("did:plc:x"); expect(cache.handleFor("did:plc:x")).toBe("alice.test"); });});
describe("IdentityCache.prime & map selection", () => { it("seeds both directions without any fetch", () => { const fetchMock = vi.fn<typeof globalThis.fetch>(); const cache = new IdentityCache(makeCtx(fetchMock));
cache.prime(DOC); expect(cache.didFor("alice.test")).toBe("did:plc:x"); expect(cache.handleFor("did:plc:x")).toBe("alice.test"); expect(fetchMock).not.toHaveBeenCalled(); });
it("resolves a DID against the did map and a handle against the handle map", async () => { const fetchMock = vi.fn<typeof globalThis.fetch>(); const cache = new IdentityCache(makeCtx(fetchMock)); cache.prime(DOC);
await expect(cache.resolve("did:plc:x")).resolves.toEqual(DOC); await expect(cache.resolve("alice.test")).resolves.toEqual(DOC); expect(fetchMock).not.toHaveBeenCalled();
// unknown dids miss the handle map and fetch. fetchMock.mockResolvedValueOnce( docResponse({ did: "did:plc:z", handle: "dan.test", pds: "https://pds.example", signing_key: "zQ3shSiLsnqpyQ4SfDTT1D8qzFEoeYT8rSDXW6o8pVY7VcRBJ" }) ); await cache.resolve("did:plc:z"); expect(fetchMock).toHaveBeenCalledTimes(1); expect((fetchMock.mock.calls[0][0] as URL).searchParams.get("identifier")).toBe( "did:plc:z" ); });});