import { afterEach, describe, expect, it } from "bun:test"; import { loadCredentials } from "../src/lib/credentials"; const realFetch = globalThis.fetch; const envKeys = ["ATP_IDENTIFIER", "ATP_APP_PASSWORD", "PDS_URL"] as const; const savedEnv = envKeys.map((key) => [key, process.env[key]] as const); function mockFetch(handler: (url: string) => Response): void { globalThis.fetch = (async (input: RequestInfo | URL) => handler( typeof input === "string" ? input : input.toString(), )) as typeof fetch; } afterEach(() => { globalThis.fetch = realFetch; for (const [key, value] of savedEnv) { if (value === undefined) { delete process.env[key]; } else { process.env[key] = value; } } }); describe("loadCredentials with app-password env vars", () => { it("resolves the PDS from the identifier when PDS_URL is unset", async () => { process.env.ATP_IDENTIFIER = "alice.example.com"; process.env.ATP_APP_PASSWORD = "app-password"; delete process.env.PDS_URL; mockFetch((url) => url.includes("plc.directory") ? Response.json({ service: [ { id: "#atproto_pds", type: "AtprotoPersonalDataServer", serviceEndpoint: "https://pds.example.com", }, ], }) : Response.json({ did: "did:plc:abc123" }), ); const credentials = await loadCredentials(); expect(credentials).toEqual({ type: "app-password", identifier: "alice.example.com", password: "app-password", pdsUrl: "https://pds.example.com", }); }); it("prefers an explicit PDS_URL without any lookup", async () => { process.env.ATP_IDENTIFIER = "alice.example.com"; process.env.ATP_APP_PASSWORD = "app-password"; process.env.PDS_URL = "https://custom.example.com"; mockFetch(() => { throw new Error("should not fetch"); }); const credentials = await loadCredentials(); expect(credentials).toMatchObject({ pdsUrl: "https://custom.example.com", }); }); it("falls back to bsky.social when the identifier cannot be resolved", async () => { process.env.ATP_IDENTIFIER = "alice.example.com"; process.env.ATP_APP_PASSWORD = "app-password"; delete process.env.PDS_URL; mockFetch(() => new Response("nope", { status: 500 })); const credentials = await loadCredentials(); expect(credentials).toMatchObject({ pdsUrl: "https://bsky.social" }); }); });