Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139import { afterEach, describe, expect, it, vi } from "vitest";import type { OAuthUserAgent } from "@atcute/oauth-browser-client";import { cidOf, didOf, knotOf, recordKeyOf } from "$lib/api/syntax";
vi.mock("$app/environment", () => ({ 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 rkey = recordKeyOf("3labc");const liveCid = cidOf("bafyreilive" + "a".repeat(48));
const load = async () => { vi.resetModules(); const knotWrites: { record?: Record<string, unknown> }[] = []; const legacy: { record: Record<string, unknown>; swap?: string }[] = []; const attested: unknown[] = []; const awaited: string[] = []; vi.doMock("$lib/api/repo", () => ({ resolveRepoKnot: vi.fn(async () => knot) })); vi.doMock("$lib/auth/agent", () => ({ mintServiceAuth: vi.fn(async () => "jwt") })); vi.doMock("$lib/api/cache", () => ({ clear: () => {} })); vi.doMock("$lib/api/attestation", () => ({ attest: vi.fn((_a: unknown, subject: unknown) => { attested.push(subject); }) })); vi.doMock("$lib/api/awaitRecord", () => ({ awaitReadable: vi.fn(async (_b: string | undefined, saved: { uri: string }) => { awaited.push(saved.uri); }), awaitRemoved: vi.fn(async () => {}) })); vi.doMock("$lib/api/write", () => ({ putRecord: vi.fn( async (_a: unknown, _c: string, _r: string, record: unknown, swap?: string) => { legacy.push({ record: record as Record<string, unknown>, swap }); return { uri: `at://${agent.sub}/sh.tangled.repo.issue/3lnew`, cid: "bafylegacy" }; } ), deleteRecord: vi.fn(async () => {}) })); vi.doMock("$lib/api/cob", () => ({ withRkey: (saved: { uri: string; cid: string }) => ({ uri: saved.uri, cid: saved.cid, rkey: recordKeyOf("3lnew") }), createCob: vi.fn( async (_a: unknown, _k: unknown, _d: unknown, _c: string, record: unknown) => { knotWrites.push({ record: record as Record<string, unknown> }); return { uri: `at://${repoDid}/org.tangled.track.ticket/${rkey}`, cid: liveCid }; } ), updateCob: vi.fn( async ( _a: unknown, _k: unknown, _uri: string, mutate: (current: Record<string, unknown>) => Record<string, unknown> ) => { const record = mutate({ $type: "org.tangled.track.ticket", title: { $type: "org.tangled.markup.markdown#inline", text: "old" }, state: "open", tangledLabels: [ { $type: "org.tangled.label.defs#labelToken", key: "reviewer" } ], targetBranch: "release", createdAt: "2026-10-01T00:00:00Z" }); knotWrites.push({ record }); return { uri: `at://${repoDid}/org.tangled.track.ticket/${rkey}`, cid: liveCid, value: record }; } ), eraseCob: vi.fn(async () => {}) })); const issue = await import("./issue"); return { issue, knotWrites, legacy, attested, awaited };};
const capabilities = (list: string[]) => vi.stubGlobal( "fetch", vi.fn(async () => ({ ok: true, json: async () => ({ capabilities: list }) }) as Response) );
afterEach(() => { vi.unstubAllGlobals();});
describe("ticket write targets", () => { it("writes lexicon ticket records on knots and restates live labels and branch on edits", async () => { capabilities(["knot-social-writes"]); const { issue, knotWrites } = await load(); await issue.openTicket(agent, "https://bobbin.test", repoDid, { title: "new", body: "prose" }); expect(knotWrites[0]?.record).toMatchObject({ $type: "org.tangled.track.ticket", title: { $type: "org.tangled.markup.markdown#inline", text: "new" }, body: { $type: "org.tangled.markup.markdown", text: "prose" }, state: "open" });
await issue.editTicket(agent, "https://bobbin.test", repoDid, { rkey, swapRecord: liveCid, title: "newer" }); expect(knotWrites[1]?.record).toMatchObject({ title: { text: "newer" }, state: "open", tangledLabels: [{ key: "reviewer" }], targetBranch: "release" }); });
it("writes legacy issue collections when knots don't advertise social writes", async () => { capabilities(["knot-acl"]); const { issue, knotWrites, legacy, attested, awaited } = await load(); await issue.openTicket(agent, "https://bobbin.test", repoDid, { title: "new" }); expect(knotWrites).toEqual([]); expect(attested).toEqual([]); expect(legacy[0]?.record).toEqual({ $type: "sh.tangled.repo.issue", repo: repoDid, title: "new", body: "", createdAt: expect.any(String) }); expect(awaited).toHaveLength(1); });});