x
This commit is contained in:
1 parent
0341b30b6d
commit
bd8f5882e0
9 files changed
+1410
-25
No files matched your search
@@ -0,0 +1,136 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
getPageBlockSchema,
|
||||
handleSectionTool,
|
||||
validatePayloadAgainstMetadata,
|
||||
} from "./section-toolkit";
|
||||
|
||||
const websiteBlockTypes = [
|
||||
"HERO",
|
||||
"ANNOUNCEMENT_BAR",
|
||||
"NEWSLETTER",
|
||||
"EDITORIAL_TILE",
|
||||
"EDITORIAL_CAROUSEL",
|
||||
"PRODUCTS",
|
||||
"CATEGORIES",
|
||||
"TEXT",
|
||||
"BANNER",
|
||||
"HERO_ARTICLE",
|
||||
"RICH_TEXT",
|
||||
"SCENT_NOTES_BREAKDOWN",
|
||||
"QUOTE_CALLOUT",
|
||||
"PRODUCT_CAROUSEL",
|
||||
"ACCORDION",
|
||||
"CONTACT_INFO",
|
||||
"CONTACT_FORM",
|
||||
"HERO_V2",
|
||||
"USP_BAR",
|
||||
"CUSTOM",
|
||||
] as const;
|
||||
|
||||
describe("Page Builder block contracts", () => {
|
||||
for (const type of websiteBlockTypes) {
|
||||
test(`${type} exposes a valid recommended payload`, () => {
|
||||
const schema = getPageBlockSchema(type);
|
||||
|
||||
expect(schema.renderability.websitePageRenderable).toBe(true);
|
||||
expect(schema.recommendedPayload).not.toBeNull();
|
||||
expect(validatePayloadAgainstMetadata(type, schema.recommendedPayload).valid).toBe(true);
|
||||
});
|
||||
}
|
||||
|
||||
test("HERO_V2 rejects the legacy empty payload before backend writes", () => {
|
||||
const result = validatePayloadAgainstMetadata("HERO_V2", {});
|
||||
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.missingFields).toEqual(["title", "imageUrl"]);
|
||||
});
|
||||
|
||||
test("USP_BAR rejects an empty payload because the website renders nothing", () => {
|
||||
const result = validatePayloadAgainstMetadata("USP_BAR", {});
|
||||
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.missingFields).toContain("items");
|
||||
});
|
||||
|
||||
test("CUSTOM rejects component IDs missing from the website registry", () => {
|
||||
const result = validatePayloadAgainstMetadata("CUSTOM", {
|
||||
componentId: "UnknownComponent",
|
||||
props: {},
|
||||
});
|
||||
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.validationIssues).toContainEqual({
|
||||
path: "componentId",
|
||||
message: "Unsupported website custom component. Use BakeryCategories or StoryFeatureMosaic.",
|
||||
code: "custom",
|
||||
});
|
||||
});
|
||||
|
||||
test("create_page_with_section rejects invalid payloads without calling backend", async () => {
|
||||
let postCalls = 0;
|
||||
const api = {
|
||||
post: async () => {
|
||||
postCalls += 1;
|
||||
throw new Error("Backend must not be called");
|
||||
},
|
||||
} as any;
|
||||
|
||||
const result = await handleSectionTool(api, "create_page_with_section", {
|
||||
title: "Invalid Hero",
|
||||
slug: "invalid-hero",
|
||||
type: "HERO_V2",
|
||||
payload: {},
|
||||
});
|
||||
|
||||
expect(result && "isError" in result ? result.isError : false).toBe(true);
|
||||
expect(postCalls).toBe(0);
|
||||
});
|
||||
|
||||
test("create_page_with_section uses one atomic backend call and returns compact output", async () => {
|
||||
const calls: Array<{ url: string; payload: unknown }> = [];
|
||||
const api = {
|
||||
post: async (url: string, payload: unknown) => {
|
||||
calls.push({ url, payload });
|
||||
return {
|
||||
data: {
|
||||
success: true,
|
||||
pageId: 50,
|
||||
sectionId: 120,
|
||||
page: { id: 50, slug: "hero-v2" },
|
||||
section: { id: 120, type: "HERO_V2" },
|
||||
},
|
||||
};
|
||||
},
|
||||
} as any;
|
||||
const payload = getPageBlockSchema("HERO_V2").recommendedPayload;
|
||||
|
||||
const result = await handleSectionTool(api, "create_page_with_section", {
|
||||
title: "Hero V2",
|
||||
slug: "hero-v2",
|
||||
type: "HERO_V2",
|
||||
payload,
|
||||
isPublished: false,
|
||||
});
|
||||
const response = JSON.parse(result?.content[0]?.text ?? "{}");
|
||||
|
||||
expect(calls).toHaveLength(1);
|
||||
expect(calls[0]?.url).toBe("/pages/with-section");
|
||||
expect(response).toEqual({
|
||||
success: true,
|
||||
tool: "create_page_with_section",
|
||||
pageId: 50,
|
||||
pageSlug: "hero-v2",
|
||||
sectionId: 120,
|
||||
type: "HERO_V2",
|
||||
preview: {
|
||||
lang: "th",
|
||||
previewPath: "/th/hero-v2",
|
||||
previewUrl: "/th/hero-v2",
|
||||
},
|
||||
warnings: [
|
||||
"contentAlignment must be left, center, or right. Use an image URL allowed by apps/website.",
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user