summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/opencode/test/server/httpapi-sdk.test.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/packages/opencode/test/server/httpapi-sdk.test.ts b/packages/opencode/test/server/httpapi-sdk.test.ts
new file mode 100644
index 000000000..d02285946
--- /dev/null
+++ b/packages/opencode/test/server/httpapi-sdk.test.ts
@@ -0,0 +1,84 @@
+import { afterEach, describe, expect, test } from "bun:test"
+import { Flag } from "@opencode-ai/core/flag/flag"
+import { createOpencodeClient } from "@opencode-ai/sdk/v2"
+import { ExperimentalHttpApiServer } from "../../src/server/routes/instance/httpapi/server"
+import path from "path"
+import { resetDatabase } from "../fixture/db"
+import { tmpdir } from "../fixture/fixture"
+
+const original = Flag.OPENCODE_EXPERIMENTAL_HTTPAPI
+
+function client(directory?: string) {
+ Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = true
+ const handler = ExperimentalHttpApiServer.webHandler().handler
+ const fetch = Object.assign(
+ (request: RequestInfo | URL, init?: RequestInit) =>
+ handler(new Request(request, init), ExperimentalHttpApiServer.context),
+ { preconnect: globalThis.fetch.preconnect },
+ ) satisfies typeof globalThis.fetch
+ return createOpencodeClient({
+ baseUrl: "http://localhost",
+ directory,
+ fetch,
+ })
+}
+
+async function expectStatus(result: Promise<{ response: Response }>, status: number) {
+ expect((await result).response.status).toBe(status)
+}
+
+afterEach(async () => {
+ Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
+ await resetDatabase()
+})
+
+describe("HttpApi SDK", () => {
+ test("uses the generated SDK for global and control routes", async () => {
+ const sdk = client()
+ const health = await sdk.global.health()
+
+ expect(health.response.status).toBe(200)
+ expect(health.data).toMatchObject({ healthy: true })
+
+ const events = await sdk.global.event({ signal: AbortSignal.timeout(1_000) })
+ try {
+ const first = await events.stream.next()
+ expect(first.value).toMatchObject({ payload: { type: "server.connected" } })
+ } finally {
+ await events.stream.return(undefined)
+ }
+
+ const log = await sdk.app.log({ service: "httpapi-sdk-test", level: "info", message: "hello" })
+ expect(log.response.status).toBe(200)
+ expect(log.data).toBe(true)
+
+ await expectStatus(sdk.auth.set({ providerID: "test" }), 400)
+ })
+
+ test("uses the generated SDK for safe instance routes", async () => {
+ await using tmp = await tmpdir({
+ config: { formatter: false, lsp: false },
+ init: (dir) => Bun.write(path.join(dir, "hello.txt"), "hello"),
+ })
+ const sdk = client(tmp.path)
+
+ const file = await sdk.file.read({ path: "hello.txt" })
+ expect(file.response.status).toBe(200)
+ expect(file.data).toMatchObject({ content: "hello" })
+
+ const session = await sdk.session.create({ title: "sdk" })
+ expect(session.response.status).toBe(200)
+ expect(session.data).toMatchObject({ title: "sdk" })
+
+ const listed = await sdk.session.list({ roots: true, limit: 10 })
+ expect(listed.response.status).toBe(200)
+ expect(listed.data?.map((item) => item.id)).toContain(session.data?.id)
+
+ await Promise.all([
+ expectStatus(sdk.project.current(), 200),
+ expectStatus(sdk.config.get(), 200),
+ expectStatus(sdk.config.providers(), 200),
+ expectStatus(sdk.find.files({ query: "hello", limit: 10 }), 200),
+ ])
+ })
+})