import { describe, expect, it, vi } from "vitest";
import type { Cid, ResourceUri } from "@atcute/lexicons/syntax";
import type { BobbinContext } from "#lib/api/client.ts";
import { awaitIndexedOrSaved, awaitIndexedRecord, awaitRecord } from "#lib/api/awaitRecord.ts";
const revision = {
uri: "at://did:plc:alice/sh.tangled.repo/demo" as ResourceUri,
cid: "bafyrevision" as Cid
};
const contextFor = (data: Record<string, unknown>) => {
const call = vi.fn(async () => ({ ok: true, data }));
const ctx = { xrpc: { call } } as unknown as BobbinContext;
return { call, ctx };
};
describe("awaitRecord", () => {
it("forwards a written revision and returns bobbin's result", async () => {
const { call, ctx } = contextFor({ status: "indexed", cid: revision.cid });
await expect(awaitRecord(ctx, revision)).resolves.toMatchObject({ status: "indexed" });
expect(call).toHaveBeenCalledWith(expect.anything(), {
params: { uri: revision.uri, cid: revision.cid }
});
});
it("supports cid-less delete waits", async () => {
const { call, ctx } = contextFor({ status: "deleted" });
await expect(awaitRecord(ctx, { uri: revision.uri })).resolves.toMatchObject({
status: "deleted"
});
expect(call).toHaveBeenCalledWith(expect.anything(), { params: { uri: revision.uri } });
});
});
describe("awaitIndexedRecord", () => {
it("rejects a revision bobbin did not index", async () => {
const { ctx } = contextFor({ status: "rejected", detail: "invalid repository" });
await expect(awaitIndexedRecord(ctx, revision)).rejects.toThrow("invalid repository");
});
});
describe("awaitIndexedOrSaved", () => {
it("reports a saved record when bobbin cannot be reached", async () => {
const call = vi.fn(async () => {
throw new TypeError("NetworkError when attempting to fetch resource.");
});
const ctx = { xrpc: { call } } as unknown as BobbinContext;
await expect(awaitIndexedOrSaved(ctx, revision)).rejects.toThrow(/^Saved\./);
});
});