x
This commit is contained in:
1 parent
9237c0eded
commit
f5893c3fad
16 files changed
+1230
-114
No files matched your search
@@ -0,0 +1,86 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { join } from "node:path";
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
||||
|
||||
async function connectMcp(baseUrl: string) {
|
||||
const env = { ...process.env, MCP_BACKEND_URL: baseUrl } as Record<string, string>;
|
||||
delete env.ADMIN_USERNAME;
|
||||
delete env.ADMIN_PASSWORD;
|
||||
delete env.MCP_ADMIN_USERNAME;
|
||||
delete env.MCP_ADMIN_PASSWORD;
|
||||
env.MCP_ADMIN_USERNAME = "contract-test";
|
||||
env.MCP_ADMIN_PASSWORD = "contract-test";
|
||||
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [join(import.meta.dir, "index.ts")],
|
||||
cwd: import.meta.dir,
|
||||
env,
|
||||
stderr: "pipe",
|
||||
});
|
||||
const client = new Client({ name: "mcp-contract-test", version: "1.0.0" });
|
||||
await client.connect(transport);
|
||||
return client;
|
||||
}
|
||||
|
||||
test("settings writes send only supported fields and simple product fields are advertised", async () => {
|
||||
const writes: unknown[] = [];
|
||||
let getSettingsCount = 0;
|
||||
const backend = Bun.serve({
|
||||
port: 0,
|
||||
fetch: async (request) => {
|
||||
const path = new URL(request.url).pathname;
|
||||
if (path === "/api/auth/login") return Response.json({ token: "contract-token" });
|
||||
if (path === "/api/settings/footer-layout" && request.method === "GET") {
|
||||
return Response.json({ version: "2026-10-11T00:00:00.000Z", layout: { columns: ["brand", "explore"] } });
|
||||
}
|
||||
if (path === "/api/settings" && request.method === "GET") {
|
||||
getSettingsCount++;
|
||||
return Response.json({ brandName: "Old", footerLayout: { columns: [] }, themeTokens: { brandAccent: "#123" } });
|
||||
}
|
||||
if (path === "/api/settings" && request.method === "PUT") {
|
||||
const body = await request.json();
|
||||
writes.push(body);
|
||||
return Response.json({ ...(body as object), themeTokens: { brandAccent: "#123", ...((body as any).themeTokens ?? {}) } });
|
||||
}
|
||||
return new Response("Not found", { status: 404 });
|
||||
},
|
||||
});
|
||||
let client: Client | undefined;
|
||||
try {
|
||||
client = await connectMcp(`http://localhost:${backend.port}/api`);
|
||||
const tools = (await client.listTools()).tools;
|
||||
expect(tools).toHaveLength(113);
|
||||
expect(tools.find((item) => item.name === "get_footer_layout")?.annotations?.readOnlyHint).toBe(true);
|
||||
expect(tools.find((item) => item.name === "delete_category_section")?.annotations?.destructiveHint).toBe(true);
|
||||
const footerLayout = await client.callTool({ name: "get_footer_layout", arguments: {} });
|
||||
expect(footerLayout.isError).toBeFalsy();
|
||||
expect(footerLayout.structuredContent).toEqual({ version: "2026-10-11T00:00:00.000Z", layout: { columns: ["brand", "explore"] } });
|
||||
for (const name of ["create_product", "bulk_create_products"]) {
|
||||
const tool = tools.find((item) => item.name === name);
|
||||
expect(tool).toBeDefined();
|
||||
const properties = name === "create_product"
|
||||
? tool!.inputSchema.properties
|
||||
: (tool!.inputSchema.properties?.products as any).items.properties;
|
||||
for (const field of ["price", "stock", "sku", "barcode"]) {
|
||||
expect(properties?.[field]).toBeDefined();
|
||||
}
|
||||
}
|
||||
|
||||
expect((await client.callTool({ name: "update_theme_tokens", arguments: { brandPrimary: "#456" } })).isError).toBeFalsy();
|
||||
expect((await client.callTool({ name: "update_brand_name", arguments: { brandName: "New" } })).isError).toBeFalsy();
|
||||
expect((await client.callTool({ name: "update_footer_content", arguments: { brandDescription: "New footer", socialLinks: { facebookUrl: "https://example.com" } } })).isError).toBeFalsy();
|
||||
|
||||
expect(getSettingsCount).toBe(0);
|
||||
expect(writes).toEqual([
|
||||
{ themeTokens: { brandPrimary: "#456" } },
|
||||
{ brandName: "New" },
|
||||
{ footerDescription: "New footer", facebookUrl: "https://example.com" },
|
||||
]);
|
||||
} finally {
|
||||
await client?.close();
|
||||
backend.stop();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user