import { afterEach, describe, expect, it, vi } from "vitest"; import { WrennClient } from "../src/client.js"; interface CapturedRequest { url: string; init: RequestInit; } function setupFetch(status = 200, body: unknown = { ok: true }) { const calls: CapturedRequest[] = []; const fetchMock = vi.fn( async (url: string | URL | Request, init?: RequestInit) => { calls.push({ url: String(url), init: init ?? {} }); if (status === 204) return new Response(null, { status }); return Response.json(body, { status }); }, ); vi.stubGlobal("fetch", fetchMock); return { calls, fetchMock }; } function expectLastCall( calls: CapturedRequest[], expected: { method: string; url: string; body?: unknown }, ) { const call = calls.at(-1); expect(call?.url).toBe(expected.url); expect(call?.init.method).toBe(expected.method); if (expected.body !== undefined) { expect(call?.init.body).toBe(JSON.stringify(expected.body)); } } describe("WrennClient", () => { afterEach(() => { vi.unstubAllGlobals(); vi.unstubAllEnvs(); }); it("initializes every resource with resolved auth headers", async () => { const { calls } = setupFetch(); const client = new WrennClient({ apiKey: "api-key", baseUrl: "https://api.example.com/", hostToken: "host-token", token: "jwt-token", }); await client.auth.login({ email: "a@example.com", password: "password" }); expect(client.account).toBeDefined(); expect(client.apiKeys).toBeDefined(); expect(client.users).toBeDefined(); expect(client.teams).toBeDefined(); expect(client.capsules).toBeDefined(); expect(client.files).toBeDefined(); expect(client.snapshots).toBeDefined(); expect(client.hosts).toBeDefined(); expect(client.channels).toBeDefined(); expect(calls.at(-1)?.init.headers).toMatchObject({ Accept: "application/json", Authorization: "Bearer jwt-token", "Content-Type": "application/json", "X-API-Key": "api-key", "X-Host-Token": "host-token", }); }); it("maps auth endpoints", async () => { const { calls } = setupFetch(); const client = new WrennClient({ baseUrl: "https://api.example.com" }); await client.auth.signup({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/auth/signup", }); await client.auth.activate({ token: "activation-token" }); expectLastCall(calls, { body: { token: "activation-token" }, method: "POST", url: "https://api.example.com/v1/auth/activate", }); await client.auth.login({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/auth/login", }); await client.auth.oauthRedirect("github", { redirect: "manual" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/auth/oauth/github", }); expect(calls.at(-1)?.init.redirect).toBe("manual"); await client.auth.oauthCallback("github", { code: "code", state: "state" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/auth/oauth/github/callback?code=code&state=state", }); await client.auth.switchTeam({ team_id: "team_1" }); expectLastCall(calls, { body: { team_id: "team_1" }, method: "POST", url: "https://api.example.com/v1/auth/switch-team", }); }); it("maps account, API key, user, and team endpoints", async () => { const { calls } = setupFetch(); const client = new WrennClient({ baseUrl: "https://api.example.com" }); await client.account.getMe(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/me", }); await client.account.updateName({ name: "New Name" }); expectLastCall(calls, { body: { name: "New Name" }, method: "PATCH", url: "https://api.example.com/v1/me", }); await client.account.deleteAccount({ confirmation: "a@example.com" }); expectLastCall(calls, { body: { confirmation: "a@example.com" }, method: "DELETE", url: "https://api.example.com/v1/me", }); await client.account.changePassword({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/me/password", }); await client.account.requestPasswordReset({ email: "a@example.com" }); expectLastCall(calls, { body: { email: "a@example.com" }, method: "POST", url: "https://api.example.com/v1/me/password/reset", }); await client.account.confirmPasswordReset({ new_password: "password", token: "token", }); expectLastCall(calls, { body: { new_password: "password", token: "token" }, method: "POST", url: "https://api.example.com/v1/me/password/reset/confirm", }); await client.account.connectProvider("github"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/me/providers/github/connect", }); await client.account.disconnectProvider("github"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/me/providers/github", }); await client.apiKeys.list(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/api-keys", }); await client.apiKeys.create({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/api-keys", }); await client.apiKeys.delete("key/1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/api-keys/key%2F1", }); await client.users.search({ email: "alice@" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/users/search?email=alice%40", }); await client.teams.list(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/teams", }); await client.teams.create({ name: "Team" }); expectLastCall(calls, { body: { name: "Team" }, method: "POST", url: "https://api.example.com/v1/teams", }); await client.teams.get("team/1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/teams/team%2F1", }); await client.teams.rename("team_1", { name: "New" }); expectLastCall(calls, { body: { name: "New" }, method: "PATCH", url: "https://api.example.com/v1/teams/team_1", }); await client.teams.delete("team_1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/teams/team_1", }); await client.teams.listMembers("team_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/teams/team_1/members", }); await client.teams.addMember("team_1", { email: "a@example.com" }); expectLastCall(calls, { body: { email: "a@example.com" }, method: "POST", url: "https://api.example.com/v1/teams/team_1/members", }); await client.teams.updateMemberRole("team_1", "user_1", { role: "admin" }); expectLastCall(calls, { body: { role: "admin" }, method: "PATCH", url: "https://api.example.com/v1/teams/team_1/members/user_1", }); await client.teams.removeMember("team_1", "user_1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/teams/team_1/members/user_1", }); await client.teams.leave("team_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/teams/team_1/leave", }); }); it("maps capsule, file, and snapshot endpoints", async () => { const { calls } = setupFetch(); const client = new WrennClient({ baseUrl: "https://api.example.com" }); await client.capsules.create({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules", }); await client.capsules.list(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules", }); await client.capsules.get("cap_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules/cap_1", }); await client.capsules.destroy("cap_1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/capsules/cap_1", }); await client.capsules.exec("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/exec", }); await client.capsules.listProcesses("cap_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules/cap_1/processes", }); await client.capsules.killProcess("cap_1", "pid/1", { signal: "SIGTERM" }); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/capsules/cap_1/processes/pid%2F1?signal=SIGTERM", }); await client.capsules.ping("cap_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/capsules/cap_1/ping", }); await client.capsules.metrics("cap_1", { range: "10m" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules/cap_1/metrics?range=10m", }); await client.capsules.pause("cap_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/capsules/cap_1/pause", }); await client.capsules.resume("cap_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/capsules/cap_1/resume", }); await client.capsules.stats({ range: "1h" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules/stats?range=1h", }); await client.capsules.usage({ from: "2026-01-01", to: "2026-01-02" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/capsules/usage?from=2026-01-01&to=2026-01-02", }); await client.files.upload("cap_1", { file: "hello", path: "/tmp/a.txt" }); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/write", }); expect(calls.at(-1)?.init.body).toBeInstanceOf(FormData); await client.files.download("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/read", }); await client.files.list("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/list", }); await client.files.mkdir("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/mkdir", }); await client.files.remove("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/remove", }); await client.files.streamUpload("cap_1", { file: "hello", path: "/tmp/a.txt", }); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/stream/write", }); await client.files.streamDownload("cap_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/capsules/cap_1/files/stream/read", }); await client.snapshots.create({} as never, { overwrite: "true" }); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/snapshots?overwrite=true", }); await client.snapshots.list({ type: "base" }); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/snapshots?type=base", }); await client.snapshots.delete("snap/1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/snapshots/snap%2F1", }); }); it("maps host and channel endpoints", async () => { const { calls } = setupFetch(); const client = new WrennClient({ baseUrl: "https://api.example.com" }); await client.hosts.create({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/hosts", }); await client.hosts.list(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/hosts", }); await client.hosts.get("host_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/hosts/host_1", }); await client.hosts.delete("host_1", { force: true }); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/hosts/host_1?force=true", }); await client.hosts.regenerateToken("host_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/hosts/host_1/token", }); await client.hosts.register({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/hosts/register", }); await client.hosts.heartbeat("host_1"); expectLastCall(calls, { method: "POST", url: "https://api.example.com/v1/hosts/host_1/heartbeat", }); await client.hosts.refreshToken({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/hosts/auth/refresh", }); await client.hosts.deletePreview("host_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/hosts/host_1/delete-preview", }); await client.hosts.listTags("host_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/hosts/host_1/tags", }); await client.hosts.addTag("host_1", {} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/hosts/host_1/tags", }); await client.hosts.removeTag("host_1", "gpu/a"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/hosts/host_1/tags/gpu%2Fa", }); await client.channels.create({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/channels", }); await client.channels.list(); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/channels", }); await client.channels.test({} as never); expectLastCall(calls, { body: {}, method: "POST", url: "https://api.example.com/v1/channels/test", }); await client.channels.get("channel_1"); expectLastCall(calls, { method: "GET", url: "https://api.example.com/v1/channels/channel_1", }); await client.channels.update("channel_1", {} as never); expectLastCall(calls, { body: {}, method: "PATCH", url: "https://api.example.com/v1/channels/channel_1", }); await client.channels.delete("channel_1"); expectLastCall(calls, { method: "DELETE", url: "https://api.example.com/v1/channels/channel_1", }); await client.channels.rotateConfig("channel_1", {} as never); expectLastCall(calls, { body: {}, method: "PUT", url: "https://api.example.com/v1/channels/channel_1/config", }); }); });