import { describe, expect, it, vi } from "vitest"; import type { Nsid } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; const agent = { sub: "did:plc:writer" } as unknown as OAuthUserAgent; const collection = "sh.tangled.repo.issue" as Nsid; const record = { $type: "sh.tangled.repo.issue", title: "hi" }; // doMock needs the modules loaded after it, so the imports are dynamic const load = async () => { vi.resetModules(); const inputs: Record[] = []; vi.doMock("$app/environment", () => ({ browser: true })); vi.doMock("$lib/auth/agent", () => ({ createClient: () => ({ call: async (_schema: unknown, options: { input: Record }) => { inputs.push(options.input); return { ok: true, data: { uri: "at://did:plc:writer/c/1", cid: "bafy" } }; } }) })); return { cache: await import("./cache"), write: await import("./write"), inputs }; }; describe("record writes", () => { it("drops cached reads so a write is visible on the next read", async () => { const { cache, write } = await load(); const read = vi.fn().mockResolvedValue("stale"); await cache.cached("issues:did:plc:repo:open:", 30_000, read); await write.putRecord(agent, collection, "3lk", record); await cache.cached("issues:did:plc:repo:open:", 30_000, read); expect(read).toHaveBeenCalledTimes(2); }); it("forwards the swap guard so a concurrent edit loses", async () => { const { write, inputs } = await load(); await write.putRecord(agent, collection, "3lk", record, "bafyread"); expect(inputs[0]).toMatchObject({ rkey: "3lk", swapRecord: "bafyread" }); }); it("forwards the swap guard on deletes used for rollback", async () => { const { write, inputs } = await load(); await write.deleteRecord(agent, collection, "3lk", "bafycreated"); expect(inputs[0]).toMatchObject({ rkey: "3lk", swapRecord: "bafycreated" }); }); it("takes a minted rkey instead of letting the pds assign one", async () => { const { write, inputs } = await load(); await write.createRecord(agent, collection, record, "3lkminted"); expect(inputs[0]).toMatchObject({ rkey: "3lkminted" }); }); it("keeps the cache when the write fails", async () => { vi.resetModules(); vi.doMock("$app/environment", () => ({ browser: true })); vi.doMock("$lib/auth/agent", () => ({ createClient: () => ({ call: async () => ({ ok: false, data: { error: "InvalidRequest", message: "nope" } }) }) })); const cache = await import("./cache"); const write = await import("./write"); const read = vi.fn().mockResolvedValue("fresh"); await cache.cached("issues:did:plc:repo:open:", 30_000, read); await expect(write.deleteRecord(agent, collection, "3lk")).rejects.toThrow(); await cache.cached("issues:did:plc:repo:open:", 30_000, read); expect(read).toHaveBeenCalledTimes(1); }); });