|
|
@@ -1,6 +1,6 @@
|
|
|
-import { test, expect, mock, beforeEach } from "bun:test"
|
|
|
+import { describe, expect, mock, beforeEach } from "bun:test"
|
|
|
import { Effect } from "effect"
|
|
|
-import type { MCP as MCPNS } from "../../src/mcp/index"
|
|
|
+import { testEffect } from "../lib/effect"
|
|
|
|
|
|
// Track what options were passed to each transport constructor
|
|
|
const transportCalls: Array<{
|
|
|
@@ -46,53 +46,22 @@ beforeEach(() => {
|
|
|
|
|
|
// Import MCP after mocking
|
|
|
const { MCP } = await import("../../src/mcp/index")
|
|
|
-const { AppRuntime } = await import("../../src/effect/app-runtime")
|
|
|
-const { Instance } = await import("../../src/project/instance")
|
|
|
-const { WithInstance } = await import("../../src/project/with-instance")
|
|
|
-const { tmpdir } = await import("../fixture/fixture")
|
|
|
-const service = MCP.Service as unknown as Effect.Effect<MCPNS.Interface, never, never>
|
|
|
-
|
|
|
-test("headers are passed to transports when oauth is enabled (default)", async () => {
|
|
|
- await using tmp = await tmpdir({
|
|
|
- init: async (dir) => {
|
|
|
- await Bun.write(
|
|
|
- `${dir}/opencode.json`,
|
|
|
- JSON.stringify({
|
|
|
- $schema: "https://opencode.ai/config.json",
|
|
|
- mcp: {
|
|
|
- "test-server": {
|
|
|
- type: "remote",
|
|
|
- url: "https://example.com/mcp",
|
|
|
- headers: {
|
|
|
- Authorization: "Bearer test-token",
|
|
|
- "X-Custom-Header": "custom-value",
|
|
|
- },
|
|
|
- },
|
|
|
+const it = testEffect(MCP.defaultLayer)
|
|
|
+
|
|
|
+describe("mcp.headers", () => {
|
|
|
+ it.instance("headers are passed to transports when oauth is enabled (default)", () =>
|
|
|
+ Effect.gen(function* () {
|
|
|
+ const mcp = yield* MCP.Service
|
|
|
+ yield* mcp
|
|
|
+ .add("test-server", {
|
|
|
+ type: "remote",
|
|
|
+ url: "https://example.com/mcp",
|
|
|
+ headers: {
|
|
|
+ Authorization: "Bearer test-token",
|
|
|
+ "X-Custom-Header": "custom-value",
|
|
|
},
|
|
|
- }),
|
|
|
- )
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
- await WithInstance.provide({
|
|
|
- directory: tmp.path,
|
|
|
- fn: async () => {
|
|
|
- // Trigger MCP initialization - it will fail to connect but we can check the transport options
|
|
|
- await AppRuntime.runPromise(
|
|
|
- Effect.gen(function* () {
|
|
|
- const mcp = yield* service
|
|
|
- yield* mcp
|
|
|
- .add("test-server", {
|
|
|
- type: "remote",
|
|
|
- url: "https://example.com/mcp",
|
|
|
- headers: {
|
|
|
- Authorization: "Bearer test-token",
|
|
|
- "X-Custom-Header": "custom-value",
|
|
|
- },
|
|
|
- })
|
|
|
- .pipe(Effect.catch(() => Effect.void))
|
|
|
- }),
|
|
|
- )
|
|
|
+ })
|
|
|
+ .pipe(Effect.catch(() => Effect.void))
|
|
|
|
|
|
// Both transports should have been created with headers
|
|
|
expect(transportCalls.length).toBeGreaterThanOrEqual(1)
|
|
|
@@ -106,33 +75,22 @@ test("headers are passed to transports when oauth is enabled (default)", async (
|
|
|
// OAuth should be enabled by default, so authProvider should exist
|
|
|
expect(call.options.authProvider).toBeDefined()
|
|
|
}
|
|
|
- },
|
|
|
- })
|
|
|
-})
|
|
|
-
|
|
|
-test("headers are passed to transports when oauth is explicitly disabled", async () => {
|
|
|
- await using tmp = await tmpdir()
|
|
|
-
|
|
|
- await WithInstance.provide({
|
|
|
- directory: tmp.path,
|
|
|
- fn: async () => {
|
|
|
- transportCalls.length = 0
|
|
|
-
|
|
|
- await AppRuntime.runPromise(
|
|
|
- Effect.gen(function* () {
|
|
|
- const mcp = yield* service
|
|
|
- yield* mcp
|
|
|
- .add("test-server-no-oauth", {
|
|
|
- type: "remote",
|
|
|
- url: "https://example.com/mcp",
|
|
|
- oauth: false,
|
|
|
- headers: {
|
|
|
- Authorization: "Bearer test-token",
|
|
|
- },
|
|
|
- })
|
|
|
- .pipe(Effect.catch(() => Effect.void))
|
|
|
- }),
|
|
|
- )
|
|
|
+ }),
|
|
|
+ )
|
|
|
+
|
|
|
+ it.instance("headers are passed to transports when oauth is explicitly disabled", () =>
|
|
|
+ Effect.gen(function* () {
|
|
|
+ const mcp = yield* MCP.Service
|
|
|
+ yield* mcp
|
|
|
+ .add("test-server-no-oauth", {
|
|
|
+ type: "remote",
|
|
|
+ url: "https://example.com/mcp",
|
|
|
+ oauth: false,
|
|
|
+ headers: {
|
|
|
+ Authorization: "Bearer test-token",
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .pipe(Effect.catch(() => Effect.void))
|
|
|
|
|
|
expect(transportCalls.length).toBeGreaterThanOrEqual(1)
|
|
|
|
|
|
@@ -144,29 +102,18 @@ test("headers are passed to transports when oauth is explicitly disabled", async
|
|
|
// OAuth is disabled, so no authProvider
|
|
|
expect(call.options.authProvider).toBeUndefined()
|
|
|
}
|
|
|
- },
|
|
|
- })
|
|
|
-})
|
|
|
-
|
|
|
-test("no requestInit when headers are not provided", async () => {
|
|
|
- await using tmp = await tmpdir()
|
|
|
-
|
|
|
- await WithInstance.provide({
|
|
|
- directory: tmp.path,
|
|
|
- fn: async () => {
|
|
|
- transportCalls.length = 0
|
|
|
-
|
|
|
- await AppRuntime.runPromise(
|
|
|
- Effect.gen(function* () {
|
|
|
- const mcp = yield* service
|
|
|
- yield* mcp
|
|
|
- .add("test-server-no-headers", {
|
|
|
- type: "remote",
|
|
|
- url: "https://example.com/mcp",
|
|
|
- })
|
|
|
- .pipe(Effect.catch(() => Effect.void))
|
|
|
- }),
|
|
|
- )
|
|
|
+ }),
|
|
|
+ )
|
|
|
+
|
|
|
+ it.instance("no requestInit when headers are not provided", () =>
|
|
|
+ Effect.gen(function* () {
|
|
|
+ const mcp = yield* MCP.Service
|
|
|
+ yield* mcp
|
|
|
+ .add("test-server-no-headers", {
|
|
|
+ type: "remote",
|
|
|
+ url: "https://example.com/mcp",
|
|
|
+ })
|
|
|
+ .pipe(Effect.catch(() => Effect.void))
|
|
|
|
|
|
expect(transportCalls.length).toBeGreaterThanOrEqual(1)
|
|
|
|
|
|
@@ -174,6 +121,6 @@ test("no requestInit when headers are not provided", async () => {
|
|
|
// No headers means requestInit should be undefined
|
|
|
expect(call.options.requestInit).toBeUndefined()
|
|
|
}
|
|
|
- },
|
|
|
- })
|
|
|
+ }),
|
|
|
+ )
|
|
|
})
|