Files
buzz-sheet/lib/blocks/registry.test.ts
T

129 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { blockRegistry, resolveBlock, validatePageBlocks } from "./registry";
const id = "7d9be7bb-185f-43e8-a5c1-43a05acdebec";
describe("block registry", () => {
it("provides validation and migration for every schema", () => {
for (const definition of Object.values(blockRegistry)) {
expect(definition.currentVersion).toBe(1);
expect(definition.migrations[0]).toBeTypeOf("function");
}
});
it("migrates and validates a legacy block", () => {
const resolution = resolveBlock({
id,
type: "callout",
schemaVersion: 0,
sortOrder: 0,
config: { body: "จังหวะนี้ควรเก็บพลังงานไว้", tone: "tip" },
});
expect(resolution.kind).toBe("ready");
if (resolution.kind === "ready") {
expect(resolution.block.schemaVersion).toBe(1);
expect(resolution.block.responsiveLayout).toMatchObject({
width: "content",
});
}
});
it("keeps unknown and future blocks safe", () => {
expect(
resolveBlock({ id, type: "future-widget", schemaVersion: 1, config: {}, sortOrder: 0 }),
).toMatchObject({ kind: "unsupported", reason: "unknown-type" });
expect(
resolveBlock({ id, type: "callout", schemaVersion: 99, config: {}, sortOrder: 0 }),
).toMatchObject({ kind: "unsupported", reason: "future-version" });
});
it("rejects unsafe or malformed configuration without throwing", () => {
const resolution = resolveBlock({
id,
type: "links",
schemaVersion: 1,
sortOrder: 0,
config: {
links: [
{
id: "2b21ac85-eb39-4f4d-89ce-a26929417981",
label: "ไม่ปลอดภัย",
href: "javascript:alert(1)",
},
],
},
});
expect(resolution.kind).toBe("invalid");
});
it("enforces chart series and an immutable accessible table fallback", () => {
const base = {
id,
type: "comparison-chart",
schemaVersion: 1,
sortOrder: 0,
config: {
dataSourceId: "495248af-d20a-4e59-be25-a982398df917",
categoryField: "name",
series: [{ field: "damage", label: "ดาเมจ", color: "chart-1" }],
presentation: "horizontal-bar",
normalization: "raw",
sort: "authored",
showValues: true,
showLegend: false,
},
} as const;
const valid = resolveBlock(base);
expect(valid.kind).toBe("ready");
if (valid.kind === "ready") {
expect(valid.block.config.tableFallback).toBe(true);
}
expect(
resolveBlock({
...base,
config: { ...base.config, tableFallback: false },
}).kind,
).toBe("invalid");
expect(
resolveBlock({
...base,
config: {
...base.config,
series: Array.from({ length: 7 }, (_, index) => ({
field: `value_${index}`,
label: `Series ${index}`,
color: "chart-1",
})),
},
}).kind,
).toBe("invalid");
});
it("detects duplicate stable ids while preserving author order", () => {
const results = validatePageBlocks([
{
id,
type: "separator",
schemaVersion: 1,
config: {},
sortOrder: 2,
},
{
id,
type: "separator",
schemaVersion: 1,
config: {},
sortOrder: 1,
},
]);
expect(results[0].kind).toBe("ready");
expect(results[1].kind).toBe("invalid");
});
});