import type { Did } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { getOrCreateDelegatedSession } from "$lib/api/actAs"; import { provisionDelegate } from "$lib/api/delegation"; import { createOrg, createOrgAccount, ORG_HANDLE_SUFFIX, ORG_PROFILE_MARKER } from "$lib/api/orgCreate"; import { ensureProfile } from "$lib/api/profile"; vi.mock("$lib/api/delegation", () => ({ provisionDelegate: vi.fn() })); vi.mock("$lib/api/actAs", () => ({ getOrCreateDelegatedSession: vi.fn() })); vi.mock("$lib/api/profile", () => ({ PROFILE_COLLECTION: "sh.tangled.actor.profile", ensureProfile: vi.fn() })); const service = { serviceUrl: "https://gate.example" }; const controllerDid = "did:plc:controller" as Did; const controller = { sub: controllerDid } as OAuthUserAgent; const orgAgent = {} as OAuthUserAgent; const orgDid = "did:plc:org" as Did; const orgLabel = "acme"; const fullHandle = `${orgLabel}${ORG_HANDLE_SUFFIX}`; beforeEach(() => { vi.resetAllMocks(); vi.mocked(provisionDelegate).mockResolvedValue({ did: orgDid, handle: fullHandle, controllerDid }); vi.mocked(getOrCreateDelegatedSession).mockResolvedValue(orgAgent); }); describe("createOrgAccount", () => { it("provisions through the sidecar", async () => { const org = await createOrgAccount(controller, " ACME ", service); expect(provisionDelegate).toHaveBeenCalledWith(controller, fullHandle, service); expect(org).toEqual({ did: orgDid, handle: fullHandle }); }); it("rejects a name that is not a valid subdomain label", async () => { await expect(createOrgAccount(controller, "-bad", service)).rejects.toThrow(/name/); expect(provisionDelegate).not.toHaveBeenCalled(); }); it("rejects a name carrying its own domain", async () => { await expect(createOrgAccount(controller, "acme.owner.example", service)).rejects.toThrow( /name/ ); expect(provisionDelegate).not.toHaveBeenCalled(); }); }); describe("createOrg", () => { it("creates the account, then writes the profile marker as the organization", async () => { const org = await createOrg(controller, orgLabel, service); expect(provisionDelegate).toHaveBeenCalledWith(controller, fullHandle, service); expect(getOrCreateDelegatedSession).toHaveBeenCalledWith(controller, orgDid); expect(ensureProfile).toHaveBeenCalledWith(orgAgent, ORG_PROFILE_MARKER); expect(ORG_PROFILE_MARKER).toEqual({ $type: "sh.tangled.actor.profile", bluesky: false, isOrganization: true }); expect(org).toEqual({ did: orgDid, handle: fullHandle, warnings: [] }); }); it("keeps the account and warns when the profile cannot be written", async () => { vi.mocked(getOrCreateDelegatedSession).mockRejectedValue(new Error("grant unavailable")); const org = await createOrg(controller, orgLabel, service); expect(org).toEqual({ did: orgDid, handle: fullHandle, warnings: ["Unable to set up the organization's profile. Try again later."] }); expect(ensureProfile).not.toHaveBeenCalled(); }); it("retries with the existing account without consuming another quota slot", async () => { await createOrg(controller, orgLabel, service, { did: orgDid, handle: fullHandle }); expect(provisionDelegate).not.toHaveBeenCalled(); expect(getOrCreateDelegatedSession).toHaveBeenCalledWith(controller, orgDid); expect(ensureProfile).toHaveBeenCalledWith(orgAgent, ORG_PROFILE_MARKER); }); });