import { expect } from "bun:test" import { Effect } from "effect" import { it } from "../../core/test/lib/effect" import { ServerFetch } from "../src/fetch" const options = { app: { version: "test-version" }, database: { path: ":memory:" }, fs: { filewatcher: false }, } as const it.live("serves the HttpApi and enforces Basic auth like the Node server", () => Effect.gen(function* () { const handler = yield* ServerFetch.make({ ...options, password: "secret" }) const denied = yield* Effect.promise(() => handler(new Request("http://opencode.local/api/health"))) expect(denied.status).toBe(401) const response = yield* Effect.promise(() => handler( new Request("http://opencode.local/api/health", { headers: { authorization: `Basic ${btoa("opencode:secret")}` }, }), ), ) expect(response.status).toBe(200) const body: unknown = yield* Effect.promise(() => response.json()) if (typeof body !== "object" || body === null) throw new Error("Expected a health response object") expect((body as Record)["healthy"]).toBe(true) }).pipe(Effect.scoped), ) it.live("serves unauthenticated and answers CORS preflight when no password is configured", () => Effect.gen(function* () { const handler = yield* ServerFetch.make(options) const response = yield* Effect.promise(() => handler(new Request("http://opencode.local/api/health"))) expect(response.status).toBe(200) const preflight = yield* Effect.promise(() => handler( new Request("http://opencode.local/api/health", { method: "OPTIONS", headers: { origin: "http://localhost:3000", "access-control-request-method": "GET", }, }), ), ) expect(preflight.headers.get("access-control-allow-origin")).toBe("http://localhost:3000") }).pipe(Effect.scoped), ) // Pins the eager-boot guarantee: the application layer is built before the handler returns, so // an aborted first request cannot interrupt layer construction and wedge every later request // (the Effect-TS/effect#6319 failure class that lazy first-request builds are prone to). it.live("stays serviceable when the first request aborts", () => Effect.gen(function* () { const handler = yield* ServerFetch.make(options) const aborted = yield* Effect.promise(() => { const controller = new AbortController() const first = handler(new Request("http://opencode.local/api/health", { signal: controller.signal })) controller.abort() return first.then( () => "resolved" as const, () => "rejected" as const, ) }) expect(["resolved", "rejected"]).toContain(aborted) const second = yield* Effect.promise(() => handler(new Request("http://opencode.local/api/health"))) expect(second.status).toBe(200) }).pipe(Effect.scoped), )