import { afterEach, describe, expect, it, vi } from "vitest"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { atUriOf, cidOf, datetimeOf, didOf, gitOidOf, knotOf, recordKeyOf } from "#lib/api/syntax.ts"; vi.mock("$app/env", () => ({ browser: false })); const agent = { sub: "did:plc:writer" } as unknown as OAuthUserAgent; const repoDid = didOf("did:web:knot.test:repo"); const knot = knotOf("knot.test"); const createdAt = datetimeOf("2026-10-05T00:00:00Z"); const subject = { uri: atUriOf(`at://${repoDid}/org.tangled.track.ticket/3labc`), cid: cidOf("bafyreimister" + "a".repeat(46)) }; const embed = { repo: repoDid, commit: gitOidOf("0f1e2d3c9b8a7f6e5d4c3b2a1908877665544332") }; const receipt = (link: string) => ({ $type: "blob" as const, ref: { $link: cidOf(link) }, mimeType: "image/png", size: 1 }); const load = async () => { vi.resetModules(); const legacy: { collection: string; rkey: string; record: Record }[] = []; const knotWrites: { collection?: string; record?: unknown; uri?: string }[] = []; const attested: unknown[] = []; const awaited: string[] = []; vi.doMock("#lib/api/repo.ts", () => ({ resolveRepoKnot: vi.fn(async () => knot) })); vi.doMock("#lib/api/write.ts", () => ({ putRecord: vi.fn(async (_a: unknown, collection: string, rkey: string, record: unknown) => { legacy.push({ collection, rkey, record: record as Record }); return { uri: `at://${agent.sub}/${collection}/${rkey}`, cid: "bafyreilegacy" + "a".repeat(46) }; }), deleteRecord: vi.fn(async () => {}) })); vi.doMock("#lib/api/attestation.ts", () => ({ attest: vi.fn((_a: unknown, subject: unknown) => { attested.push(subject); }) })); vi.doMock("#lib/api/awaitRecord.ts", () => ({ awaitReadable: vi.fn(async (_b: string | undefined, saved: { uri: string }) => { awaited.push(saved.uri); }), awaitRemoved: vi.fn(async (_b: string | undefined, uri: string) => { awaited.push(uri); }) })); vi.doMock("#lib/api/cob.ts", () => ({ withRkey: (saved: { uri: string; cid: string }) => ({ uri: atUriOf(saved.uri), cid: cidOf(saved.cid), rkey: recordKeyOf("3lnew") }), createCob: vi.fn( async (_a: unknown, _k: unknown, _d: unknown, collection: string, record: unknown) => { knotWrites.push({ collection, record }); return { uri: `at://${repoDid}/${collection}/3lnew`, cid: "bafyreiknot" + "a".repeat(48) }; } ), updateCob: vi.fn( async ( _a: unknown, _k: unknown, uri: string, mutate: (current: Record) => Record ) => { const record = mutate({ $type: "org.tangled.feed.comment", subject: {}, body: { $type: "org.tangled.markup.markdown", text: "old" }, createdAt }); knotWrites.push({ uri, record }); return { uri, cid: "bafyreinew" + "a".repeat(49), value: record }; } ), eraseCob: vi.fn(async () => {}) })); const comment = await import("./comment"); return { comment, legacy, knotWrites, attested, awaited }; }; const capabilities = (list: string[]) => vi.stubGlobal( "fetch", vi.fn(async () => ({ ok: true, json: async () => ({ capabilities: list }) }) as Response) ); afterEach(() => { vi.unstubAllGlobals(); }); describe("comment write targets", () => { it("keeps commit embeds on PDS writes and waits for appview indexing", async () => { capabilities(["knot-acl"]); const { comment, legacy, knotWrites, attested, awaited } = await load(); await comment.openComment(agent, "https://bobbin.test", repoDid, { subject, text: "look", embed, createdAt }); expect(legacy[0]?.collection).toBe("sh.tangled.feed.comment"); expect(legacy[0]?.record.embed).toEqual({ $type: "sh.tangled.embed.commit", repo: repoDid, commit: { $type: "sh.tangled.git.oid", oid: "0f1e2d3c9b8a7f6e5d4c3b2a1908877665544332" } }); expect(awaited).toEqual([`at://${agent.sub}/sh.tangled.feed.comment/${legacy[0]?.rkey}`]); expect(knotWrites).toEqual([]); expect(attested).toEqual([]); }); it("keeps commit embeds on knot writes and restates image embeds on edits", async () => { capabilities(["knot-social-writes"]); const { comment, knotWrites } = await load(); const written = await comment.openComment(agent, "https://bobbin.test", repoDid, { subject, text: "look", embed, createdAt }); expect(written.rkey).toBe("3lnew"); expect(knotWrites[0]?.collection).toBe("org.tangled.feed.comment"); expect((knotWrites[0]?.record as Record).embed).toEqual({ $type: "org.tangled.embed.commit", repo: repoDid, commit: { $type: "org.tangled.git.oid", oid: "0f1e2d3c9b8a7f6e5d4c3b2a1908877665544332" } }); await comment.editCommentOn(agent, "https://bobbin.test", repoDid, { subject, text: "look again", rkey: recordKeyOf("3lnew"), swapRecord: cidOf("bafyreiknot" + "a".repeat(48)), blobs: [receipt("bafyreiold" + "a".repeat(49)), receipt("bafyreinew" + "a".repeat(49))], createdAt }); const edited = knotWrites[1]?.record as Record; expect((edited.body as Record).text).toBe("look again"); expect(edited.body).toMatchObject({ blobs: [ { image: { ref: { $link: "bafyreiold" + "a".repeat(49) } } }, { image: { ref: { $link: "bafyreinew" + "a".repeat(49) } } } ] }); }); });