import { describe, expect, it, vi } from "vitest"; import { OpenBrainConfigError, OpenBrainHttpError } from "../src/errors.js"; import { OpenBrainClient } from "../src/openbrain-client.js"; function jsonResponse(body: unknown, init?: ResponseInit): Response { return new Response(JSON.stringify(body), { status: init?.status ?? 200, headers: { "content-type": "application/json", ...(init?.headers ?? {}), }, }); } describe("OpenBrainClient", () => { it("sends bearer auth and normalized URL for createThought", async () => { const fetchMock = vi.fn(async () => jsonResponse({ id: "thought-1", content: "hello", source: "openclaw:main", }), ); const client = new OpenBrainClient({ baseUrl: "https://brain.example.com/", apiKey: "secret", fetchImpl: fetchMock as unknown as typeof fetch, }); await client.createThought({ content: "hello", source: "openclaw:main", metadata: { sessionId: "session-1" }, }); expect(fetchMock).toHaveBeenCalledTimes(1); const firstCall = fetchMock.mock.calls[0]; expect(firstCall).toBeDefined(); if (firstCall === undefined) { throw new Error("Expected fetch call arguments"); } const [url, init] = firstCall as unknown as [string, RequestInit]; expect(url).toBe("https://brain.example.com/v1/thoughts"); expect(init.method).toBe("POST"); expect(init.headers).toMatchObject({ Authorization: "Bearer secret", "Content-Type": "application/json", }); }); it("throws OpenBrainHttpError on non-2xx responses", async () => { const fetchMock = vi.fn(async () => jsonResponse({ error: "unauthorized" }, { status: 401 }), ); const client = new OpenBrainClient({ baseUrl: "https://brain.example.com", apiKey: "secret", fetchImpl: fetchMock as unknown as typeof fetch, }); await expect(client.listRecent({ limit: 5, source: "openclaw:main" })).rejects.toBeInstanceOf( OpenBrainHttpError, ); await expect(client.listRecent({ limit: 5, source: "openclaw:main" })).rejects.toMatchObject({ status: 401, }); }); it("throws OpenBrainConfigError when initialized without baseUrl or apiKey", () => { expect( () => new OpenBrainClient({ baseUrl: "", apiKey: "secret", fetchImpl: fetch }), ).toThrow(OpenBrainConfigError); expect( () => new OpenBrainClient({ baseUrl: "https://brain.example.com", apiKey: "", fetchImpl: fetch }), ).toThrow(OpenBrainConfigError); }); });