Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions packages/opencode/test/server/httpapi-sdk.test.ts
Original file line number Diff line number Diff line change
@@ -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),
])
})
})
Loading