refactor(remote): extract shared registerWithCloud() helper

Registration HTTP logic was duplicated three times across listen.ts
(initial + re-register) and listen.tsx. Extracted into
listen-register.ts with proper error handling for non-JSON responses,
response shape validation, and 5 focused tests. Removes ~110 lines
of duplication.

🐛 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>
This commit is contained in:
cpacker
2026-03-01 11:52:42 -08:00
parent b4910cd410
commit 393ab7bddf
4 changed files with 203 additions and 110 deletions

View File

@@ -0,0 +1,99 @@
import { beforeEach, describe, expect, it, mock } from "bun:test";
import { registerWithCloud } from "../../websocket/listen-register";
const defaultOpts = {
serverUrl: "https://api.example.com",
apiKey: "sk-test-key",
deviceId: "device-123",
connectionName: "test-machine",
};
const mockFetch = mock(() => {
throw new Error("fetch not mocked for this test");
});
beforeEach(() => {
mockFetch.mockReset();
globalThis.fetch = mockFetch as unknown as typeof globalThis.fetch;
});
describe("registerWithCloud", () => {
it("returns connectionId and wsUrl on successful JSON response", async () => {
mockFetch.mockResolvedValueOnce(
new Response(
JSON.stringify({ connectionId: "conn-1", wsUrl: "wss://example.com" }),
{ status: 200, headers: { "Content-Type": "application/json" } },
),
);
const result = await registerWithCloud(defaultOpts);
expect(result).toEqual({
connectionId: "conn-1",
wsUrl: "wss://example.com",
});
expect(mockFetch).toHaveBeenCalledTimes(1);
const [url, init] = mockFetch.mock.calls[0] as unknown as [
string,
RequestInit,
];
expect(url).toBe("https://api.example.com/v1/environments/register");
expect(init.method).toBe("POST");
expect((init.headers as Record<string, string>).Authorization).toBe(
"Bearer sk-test-key",
);
expect((init.headers as Record<string, string>)["X-Letta-Source"]).toBe(
"letta-code",
);
const body = JSON.parse(init.body as string);
expect(body).toEqual({
deviceId: "device-123",
connectionName: "test-machine",
});
});
it("throws with body message on non-OK response with JSON error", async () => {
mockFetch.mockResolvedValueOnce(
new Response(JSON.stringify({ message: "Unauthorized" }), {
status: 401,
headers: { "Content-Type": "application/json" },
}),
);
await expect(registerWithCloud(defaultOpts)).rejects.toThrow(
"Unauthorized",
);
});
it("throws with HTTP status and truncated body on non-OK non-JSON response", async () => {
mockFetch.mockResolvedValueOnce(
new Response("<html>Bad Gateway</html>", { status: 502 }),
);
await expect(registerWithCloud(defaultOpts)).rejects.toThrow(
"HTTP 502: <html>Bad Gateway</html>",
);
});
it("throws actionable message on 200 with non-JSON body", async () => {
mockFetch.mockResolvedValueOnce(new Response("OK", { status: 200 }));
await expect(registerWithCloud(defaultOpts)).rejects.toThrow(
"is the server running?",
);
});
it("throws on unexpected response shape (missing fields)", async () => {
mockFetch.mockResolvedValueOnce(
new Response(JSON.stringify({ connectionId: "conn-1" }), {
status: 200,
headers: { "Content-Type": "application/json" },
}),
);
await expect(registerWithCloud(defaultOpts)).rejects.toThrow(
"missing connectionId or wsUrl",
);
});
});