the universal sandbox runtime for agents and humans.
pocketenv.io
sandbox
openclaw
agent
claude-code
vercel-sandbox
deno-sandbox
cloudflare-sandbox
atproto
sprites
daytona
1import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2import extractPdsFromDid from "../../lib/extractPdsFromDid";
3
4const makeFetch = (body: unknown, ok = true) =>
5 vi.fn().mockResolvedValue({
6 ok,
7 json: vi.fn().mockResolvedValue(body),
8 });
9
10describe("extractPdsFromDid", () => {
11 beforeEach(() => {
12 vi.stubGlobal("fetch", makeFetch({}));
13 });
14
15 afterEach(() => {
16 vi.unstubAllGlobals();
17 });
18
19 it("builds the plc.directory URL for did:plc DIDs", async () => {
20 const fetchMock = makeFetch({ service: [] });
21 vi.stubGlobal("fetch", fetchMock);
22
23 await extractPdsFromDid("did:plc:abc123");
24
25 expect(fetchMock).toHaveBeenCalledWith(
26 "https://plc.directory/did:plc:abc123",
27 );
28 });
29
30 it("builds the well-known URL for did:web DIDs", async () => {
31 const fetchMock = makeFetch({ service: [] });
32 vi.stubGlobal("fetch", fetchMock);
33
34 await extractPdsFromDid("did:web:example.com");
35
36 expect(fetchMock).toHaveBeenCalledWith(
37 "https://example.com/.well-known/did.json",
38 );
39 });
40
41 it("throws for unsupported DID methods", async () => {
42 await expect(extractPdsFromDid("did:key:xyz")).rejects.toThrow(
43 "Unsupported DID method",
44 );
45 });
46
47 it("throws when the DID doc fetch fails", async () => {
48 vi.stubGlobal("fetch", makeFetch({}, false));
49
50 await expect(extractPdsFromDid("did:plc:abc123")).rejects.toThrow(
51 "Failed to fetch DID doc",
52 );
53 });
54
55 it("returns the PDS endpoint when the AtprotoPersonalDataServer service is present", async () => {
56 const doc = {
57 service: [
58 {
59 id: "did:plc:abc123#atproto_pds",
60 type: "AtprotoPersonalDataServer",
61 serviceEndpoint: "https://bsky.social",
62 },
63 ],
64 };
65 vi.stubGlobal("fetch", makeFetch(doc));
66
67 const result = await extractPdsFromDid("did:plc:abc123");
68 expect(result).toBe("https://bsky.social");
69 });
70
71 it("returns null when no matching service is present", async () => {
72 vi.stubGlobal("fetch", makeFetch({ service: [] }));
73
74 const result = await extractPdsFromDid("did:plc:abc123");
75 expect(result).toBeNull();
76 });
77
78 it("returns null when service array is absent", async () => {
79 vi.stubGlobal("fetch", makeFetch({}));
80
81 const result = await extractPdsFromDid("did:plc:abc123");
82 expect(result).toBeNull();
83 });
84
85 it("ignores services whose id does not end with #atproto_pds", async () => {
86 const doc = {
87 service: [
88 {
89 id: "did:plc:abc123#other",
90 type: "AtprotoPersonalDataServer",
91 serviceEndpoint: "https://should-not-match.example",
92 },
93 ],
94 };
95 vi.stubGlobal("fetch", makeFetch(doc));
96
97 const result = await extractPdsFromDid("did:plc:abc123");
98 expect(result).toBeNull();
99 });
100});