* test: switch integration project to folder-based manifest (#1314) Replace the `integrationTests` enumeration in vite.config.ts with a folder glob (`src/test/integration/**/*.test.ts`). Files under that folder run in the integration vitest project (node env, 30s timeouts); everything else runs in the unit project (happy-dom). This removes the silent misclassification trap from #1307: a new integration-style test no longer falls into the unit project (and happy-dom) just because someone forgot to add it to the array. The 13 ported v1.5 tests + their helpers move under src/test/integration/ in a strict mirror of core/ source layout (mcp/, auth/, auth/node/, storage/). Renames use git mv so history is preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: address PR review on #1318 (glob extensions + AGENTS doc) - vite.config.ts: widen integrationGlob from `*.test.ts` to `*.test.{ts,tsx}` so the integration folder fully owns its contents. Without this, a `.test.tsx` placed under src/test/integration/ would match the unit project's `{ts,tsx}` include, fail the unit `.ts`-only exclude, and silently land under happy-dom — the exact misclassification trap this PR set out to close. - AGENTS.md: update the line describing where integration tests live; it still pointed at the old `src/test/core/` location and the removed `integrationTests` enumeration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
02182e3b6c
commit
8bb389c8e3
1 changed files with 18 additions and 27 deletions
195
clients/web/src/test/integration/mcp/node/transport.test.ts
Normal file
195
clients/web/src/test/integration/mcp/node/transport.test.ts
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { getServerType } from "@inspector/core/mcp/config.js";
|
||||
import { createTransportNode } from "@inspector/core/mcp/node/transport.js";
|
||||
import type {
|
||||
MCPServerConfig,
|
||||
FetchRequestEntryBase,
|
||||
} from "@inspector/core/mcp/types.js";
|
||||
import {
|
||||
createTestServerHttp,
|
||||
createEchoTool,
|
||||
createTestServerInfo,
|
||||
} from "@modelcontextprotocol/inspector-test-server";
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
|
||||
describe("Transport", () => {
|
||||
describe("getServerType", () => {
|
||||
it("should return stdio for stdio config", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "stdio",
|
||||
command: "echo",
|
||||
args: ["hello"],
|
||||
};
|
||||
expect(getServerType(config)).toBe("stdio");
|
||||
});
|
||||
|
||||
it("should return sse for sse config", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "sse",
|
||||
url: "http://localhost:3000/sse",
|
||||
};
|
||||
expect(getServerType(config)).toBe("sse");
|
||||
});
|
||||
|
||||
it("should return streamable-http for streamable-http config", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "streamable-http",
|
||||
url: "http://localhost:3000/mcp",
|
||||
};
|
||||
expect(getServerType(config)).toBe("streamable-http");
|
||||
});
|
||||
|
||||
it("should default to stdio when type is not present", () => {
|
||||
const config: MCPServerConfig = {
|
||||
command: "echo",
|
||||
args: ["hello"],
|
||||
};
|
||||
expect(getServerType(config)).toBe("stdio");
|
||||
});
|
||||
|
||||
it("should throw error for invalid type", () => {
|
||||
const config = {
|
||||
type: "invalid",
|
||||
command: "echo",
|
||||
} as unknown as MCPServerConfig;
|
||||
expect(() => getServerType(config)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("createTransport", () => {
|
||||
it("should create stdio transport", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "stdio",
|
||||
command: "echo",
|
||||
args: ["hello"],
|
||||
};
|
||||
const result = createTransportNode(config);
|
||||
expect(result.transport).toBeDefined();
|
||||
});
|
||||
|
||||
it("should create SSE transport", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "sse",
|
||||
url: "http://localhost:3000/sse",
|
||||
};
|
||||
const result = createTransportNode(config);
|
||||
expect(result.transport).toBeDefined();
|
||||
});
|
||||
|
||||
it("should create streamable-http transport", () => {
|
||||
const config: MCPServerConfig = {
|
||||
type: "streamable-http",
|
||||
url: "http://localhost:3000/mcp",
|
||||
};
|
||||
const result = createTransportNode(config);
|
||||
expect(result.transport).toBeDefined();
|
||||
});
|
||||
|
||||
it("should call onFetchRequest callback for SSE transport", async () => {
|
||||
const server = createTestServerHttp({
|
||||
serverInfo: createTestServerInfo(),
|
||||
tools: [createEchoTool()],
|
||||
serverType: "sse",
|
||||
});
|
||||
|
||||
try {
|
||||
await server.start();
|
||||
|
||||
const config: MCPServerConfig = {
|
||||
type: "sse",
|
||||
url: server.url,
|
||||
};
|
||||
|
||||
const fetchRequests: FetchRequestEntryBase[] = [];
|
||||
const result = createTransportNode(config, {
|
||||
onFetchRequest: (entry) => {
|
||||
fetchRequests.push(entry);
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.transport).toBeDefined();
|
||||
|
||||
// Actually connect and make a request to verify fetch tracking works
|
||||
const client = new Client(
|
||||
{
|
||||
name: "test-client",
|
||||
version: "1.0.0",
|
||||
},
|
||||
{
|
||||
capabilities: {},
|
||||
},
|
||||
);
|
||||
|
||||
await client.connect(result.transport);
|
||||
await client.listTools();
|
||||
await client.close();
|
||||
|
||||
// Verify fetch requests were tracked
|
||||
expect(fetchRequests.length).toBeGreaterThan(0);
|
||||
// SSE uses GET for the initial connection
|
||||
const getRequest = fetchRequests.find((r) => r.method === "GET");
|
||||
expect(getRequest).toBeDefined();
|
||||
if (getRequest) {
|
||||
expect(getRequest.url).toContain("/sse");
|
||||
expect(getRequest.requestHeaders).toBeDefined();
|
||||
}
|
||||
} finally {
|
||||
await server.stop();
|
||||
}
|
||||
});
|
||||
|
||||
it("should call onFetchRequest callback for streamable-http transport", async () => {
|
||||
const server = createTestServerHttp({
|
||||
serverInfo: createTestServerInfo(),
|
||||
tools: [createEchoTool()],
|
||||
serverType: "streamable-http",
|
||||
});
|
||||
|
||||
try {
|
||||
await server.start();
|
||||
|
||||
const config: MCPServerConfig = {
|
||||
type: "streamable-http",
|
||||
url: server.url,
|
||||
};
|
||||
|
||||
const fetchRequests: FetchRequestEntryBase[] = [];
|
||||
const result = createTransportNode(config, {
|
||||
onFetchRequest: (entry) => {
|
||||
fetchRequests.push(entry);
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.transport).toBeDefined();
|
||||
|
||||
// Actually connect and make a request to verify fetch tracking works
|
||||
const client = new Client(
|
||||
{
|
||||
name: "test-client",
|
||||
version: "1.0.0",
|
||||
},
|
||||
{
|
||||
capabilities: {},
|
||||
},
|
||||
);
|
||||
|
||||
await client.connect(result.transport);
|
||||
await client.listTools();
|
||||
await client.close();
|
||||
|
||||
// Verify fetch requests were tracked
|
||||
expect(fetchRequests.length).toBeGreaterThan(0);
|
||||
const request = fetchRequests[0];
|
||||
expect(request).toBeDefined();
|
||||
expect(request.url).toContain("/mcp");
|
||||
expect(request.method).toBe("POST");
|
||||
expect(request.requestHeaders).toBeDefined();
|
||||
expect(request.responseStatus).toBeDefined();
|
||||
expect(request.responseHeaders).toBeDefined();
|
||||
expect(request.duration).toBeDefined();
|
||||
} finally {
|
||||
await server.stop();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue