Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586import { describe, expect, it, vi } from "vitest";import { hydrateNotifications, type NotificationItem } from "$lib/api/notifications";import { createBobbinClient, type BobbinContext } from "$lib/api/client";
const collaborationOffer: NotificationItem = { uri: "at://did:plc:scallop/sh.tangled.repo.collaboratorInvite/did:plc:limpet", type: "collaborator_invited", category: "work", actorDid: "did:plc:akshay", read: false, createdAt: "2026-06-01T00:00:00.000Z", repoDid: "did:plc:scallop"};
const repoRecord = (knot: string) => ({ $type: "sh.tangled.repo", name: "shoal", knot, repoDid: "did:plc:scallop", createdAt: "2026-05-01T00:00:00.000Z"});
const ctxWithRepo = (value: Record<string, unknown>) => createBobbinClient({ serviceUrl: "https://bobbin.oyster.cafe", fetch: vi.fn<typeof globalThis.fetch>(async (input) => String(input).includes("sh.tangled.repo.getReposByRepoDids") ? Response.json({ items: [ { uri: "at://did:plc:akshay/sh.tangled.repo/3lk", cid: "bafy", value } ] }) : new Response(null, { status: 404 }) ) });
const ctxWithoutBobbin = () => ({ xrpc: { call: vi.fn() } }) as unknown as BobbinContext;
describe("an offer the row can act on", () => { it.each(["did:plc:scallop/path", "scallop", "..", ""])( "offers nothing to accept where %s can't be an acceptance record key", async (repoDid) => { const rows = await hydrateNotifications(ctxWithRepo(repoRecord("knot.nel.pet")), [ { ...collaborationOffer, repoDid } ]);
expect(rows[0].offer).toBeUndefined(); } );
it("a collaboration offer takes its knot from the repo record, never from the row", async () => { const rows = await hydrateNotifications(ctxWithRepo(repoRecord("knot.nel.pet")), [ collaborationOffer ]);
expect(rows[0].offer).toEqual({ kind: "collaboration", knot: new URL("https://knot.nel.pet"), subject: "did:plc:scallop" }); });
it("offers nothing where the repo record's host won't parse into a url", async () => { const rows = await hydrateNotifications( ctxWithRepo(repoRecord("knot.nel.pet:not-a-port")), [collaborationOffer] );
expect(rows[0].offer).toBeUndefined(); });
it("offers nothing when bobbin can't serve the repo record", async () => { const rows = await hydrateNotifications(ctxWithoutBobbin(), [collaborationOffer]);
expect(rows[0].offer).toBeUndefined(); });
it("leaves every other notification type alone", async () => { const rows = await hydrateNotifications(ctxWithRepo(repoRecord("knot.nel.pet")), [ { ...collaborationOffer, type: "followed" } ]);
expect(rows[0].offer).toBeUndefined(); });});