x
This commit is contained in:
1 parent
9237c0eded
commit
f5893c3fad
16 files changed
+1230
-114
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import type { AxiosInstance } from "axios";
|
||||
import { handleStorefrontTool, STOREFRONT_TOOL_DEFINITIONS } from "./storefront-toolkit";
|
||||
|
||||
function fakeApi(sections: any[] = []) {
|
||||
const calls: Array<{ method: string; path: string; body?: unknown }> = [];
|
||||
const api = {
|
||||
get: async (path: string) => {
|
||||
calls.push({ method: "GET", path });
|
||||
return { data: path === "/settings/footer-layout" ? { version: "v1", layout: {} } : sections };
|
||||
},
|
||||
patch: async (path: string, body: unknown) => { calls.push({ method: "PATCH", path, body }); return { data: { success: true } }; },
|
||||
post: async (path: string, body?: unknown) => { calls.push({ method: "POST", path, body }); return { data: { success: true } }; },
|
||||
put: async (path: string, body: unknown) => { calls.push({ method: "PUT", path, body }); return { data: { success: true } }; },
|
||||
delete: async (path: string) => { calls.push({ method: "DELETE", path }); return { data: { success: true } }; },
|
||||
} as unknown as AxiosInstance;
|
||||
return { api, calls };
|
||||
}
|
||||
|
||||
const value = (response: any) => JSON.parse(response.content[0].text);
|
||||
|
||||
describe("storefront MCP tools", () => {
|
||||
test("definitions expose the complete new workflow", () => {
|
||||
expect(STOREFRONT_TOOL_DEFINITIONS.map((tool) => tool.name)).toEqual([
|
||||
"get_footer_layout", "patch_footer_layout", "get_category_sections", "seed_category_sections",
|
||||
"add_category_section", "update_category_section", "reorder_category_sections", "delete_category_section",
|
||||
]);
|
||||
});
|
||||
|
||||
test("footer write requires version and forwards backend dry run", async () => {
|
||||
const { api, calls } = fakeApi();
|
||||
const missing = await handleStorefrontTool(api, "patch_footer_layout", { columns: ["brand"] });
|
||||
expect(value(missing).code).toBe("VERSION_REQUIRED");
|
||||
expect(calls).toHaveLength(0);
|
||||
const preview = await handleStorefrontTool(api, "patch_footer_layout", { columns: ["brand"], dryRun: true });
|
||||
expect(preview?.isError).toBeUndefined();
|
||||
expect(calls[0]).toEqual({ method: "PATCH", path: "/settings/footer-layout", body: { columns: ["brand"], dryRun: true } });
|
||||
await handleStorefrontTool(api, "patch_footer_layout", { finale: { enabled: true }, expectedVersion: "v1" });
|
||||
expect(calls[1]?.body).toEqual({ finale: { enabled: true }, expectedVersion: "v1" });
|
||||
});
|
||||
|
||||
test("footer validation returns field paths without a request", async () => {
|
||||
const { api, calls } = fakeApi();
|
||||
const response = await handleStorefrontTool(api, "patch_footer_layout", { columns: ["brand", "brand"], dryRun: true });
|
||||
expect(value(response).code).toBe("INVALID_INPUT");
|
||||
expect(calls).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("category dry run reads but never writes", async () => {
|
||||
const { api, calls } = fakeApi();
|
||||
const response = await handleStorefrontTool(api, "seed_category_sections", { categoryId: 9, dryRun: true });
|
||||
expect(value(response).dryRun).toBe(true);
|
||||
expect(calls).toEqual([{ method: "GET", path: "/categories/9/sections" }]);
|
||||
});
|
||||
|
||||
test("category update rejects wrong ownership and locked changes", async () => {
|
||||
const { api, calls } = fakeApi([{ id: 7, type: "CATEGORY_HEADER", isLocked: true }]);
|
||||
expect(value(await handleStorefrontTool(api, "update_category_section", { categoryId: 9, sectionId: 8, isActive: false })).code).toBe("NOT_FOUND");
|
||||
expect(value(await handleStorefrontTool(api, "update_category_section", { categoryId: 9, sectionId: 7, isActive: false })).code).toBe("CONFLICT");
|
||||
expect(calls.every((call) => call.method === "GET")).toBe(true);
|
||||
});
|
||||
|
||||
test("reorder rejects missing IDs before backend write", async () => {
|
||||
const { api, calls } = fakeApi([{ id: 1 }, { id: 2 }]);
|
||||
const response = await handleStorefrontTool(api, "reorder_category_sections", { categoryId: 9, sections: [{ id: 1, order: 1 }] });
|
||||
expect(value(response).code).toBe("INVALID_INPUT");
|
||||
expect(calls.every((call) => call.method === "GET")).toBe(true);
|
||||
});
|
||||
|
||||
test("backend conflict includes current version", async () => {
|
||||
const { api } = fakeApi();
|
||||
api.patch = async () => { throw { response: { status: 409, data: { code: "VERSION_CONFLICT", error: "Changed", currentVersion: "v2" } } }; };
|
||||
const response = await handleStorefrontTool(api, "patch_footer_layout", { columns: ["brand"], expectedVersion: "v1" });
|
||||
expect(value(response)).toMatchObject({ code: "VERSION_CONFLICT", message: "Changed", details: { status: 409, currentVersion: "v2" } });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user