Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131import { afterEach, describe, expect, it, vi } from "vitest";import type { OAuthUserAgent } from "@atcute/oauth-browser-client";import { atUriOf, cidOf, knotOf, labelKeyOf } from "#lib/api/syntax.ts";import type { Blob } from "@atcute/lexicons/interfaces";import type * as Ticket from "#lib/api/ticket.ts";
const agent = { sub: "did:plc:limpet" } as unknown as OAuthUserAgent;const knot = knotOf("knot.example.com");const uri = atUriOf("at://did:plc:barnacle/org.tangled.track.ticket/3lk");const storedCid = "bafyreistored" + "a".repeat(46);const nextCid = "bafyreinext" + "a".repeat(48);const from = { uri, cid: cidOf(storedCid) };const sealCid = "bafkreiseal" + "a".repeat(48);const otterCid = "bafkreiotter" + "a".repeat(47);const imageOf = (cid: string) => ({ $type: "org.tangled.markup.embed.image", image: { $type: "blob", ref: { $link: cid }, mimeType: "image/png", size: 3 }});
const stored = { $type: "org.tangled.track.ticket", title: { $type: "org.tangled.markup.markdown#inline", text: "kelp" }, body: { $type: "org.tangled.markup.markdown", text: `forest `, blobs: [imageOf(sealCid)] }, state: "open", targetBranch: "main", tangledLabels: [{ key: "bug" }], mentions: ["did:plc:urchin"], createdAt: "2026-01-01T00:00:00Z", "x-tngl-editor": "did:plc:limpet"};
const load = async () => { vi.resetModules(); vi.doMock("$app/env", () => ({ browser: true })); vi.doMock("#lib/auth/agent.ts", () => ({ mintServiceAuth: async () => "token" })); const ticket = (await import("#lib/api/ticket.ts")) as typeof Ticket; const sent: Record<string, unknown>[] = []; vi.stubGlobal("fetch", async (_input: URL | RequestInfo, init?: RequestInit) => { if (!init?.body) return Response.json({ uri, cid: storedCid, value: stored }); sent.push(JSON.parse(String(init.body))); return Response.json({ uri, cid: nextCid }); }); return { ticket, sent };};
const { "x-tngl-editor": _, ...kept } = stored;
afterEach(() => { vi.unstubAllGlobals();});
describe("ticket writes on the knot", () => { it("edits the prose and keeps everything the form doesn't show", async () => { const { ticket, sent } = await load();
const body = `deeper ${kept.body.text}`; await ticket.editTicket(agent, knot, from, { title: "kelp bed", body });
expect(sent[0]).toMatchObject({ swapRecord: storedCid }); expect(sent[0].record).toEqual({ ...kept, title: { ...kept.title, text: "kelp bed" }, body: { ...kept.body, text: body } }); });
it("pins the images the body links and lets the rest go", async () => { const { ticket, sent } = await load(); const otter = imageOf(otterCid).image as Blob;
await ticket.editTicket(agent, knot, from, { title: "kelp", body: ` `, blobs: [otter, otter] });
expect(sent[0].record).toMatchObject({ body: { blobs: [imageOf(otterCid)] } }); });
it("leaves a blank body out, because the knot refuses an empty one", async () => { const { ticket, sent } = await load();
await ticket.editTicket(agent, knot, from, { title: "kelp", body: " " });
expect(sent[0].record).not.toHaveProperty("body"); });
it("moves a pull to another target branch", async () => { const { ticket, sent } = await load();
await ticket.editTicket(agent, knot, from, { title: "kelp", body: "forest", targetBranch: "next" });
expect(sent[0].record).toMatchObject({ targetBranch: "next" }); });
it("changes state by rewriting the ticket", async () => { const { ticket, sent } = await load();
const written = await ticket.setTicketState(agent, knot, from, "closed");
expect(sent[0].record).toEqual({ ...kept, state: "closed" }); expect(written.cid).toBe(nextCid); });
it("replaces the label set and drops it when it ends up empty", async () => { const { ticket, sent } = await load();
await ticket.setTicketLabels(agent, knot, from, [ labelKeyOf("docs"), labelKeyOf("wontfix") ]); await ticket.setTicketLabels(agent, knot, from, []);
expect(sent[0].record).toMatchObject({ tangledLabels: [ { $type: "org.tangled.label.defs#labelToken", key: "docs" }, { $type: "org.tangled.label.defs#labelToken", key: "wontfix" } ] }); expect(sent[1].record).not.toHaveProperty("tangledLabels"); });});