mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-10-29 08:07:48 +09:00
## Summary Fixes the reproducible MCP regressions reported today: - validate font upload metadata locally instead of surfacing an HTTP 500 - replace only the addressed child when `insertIndex` is supplied - support cross-parent duplication - bind data-variable assignments in actions - reject string-valued `style` bindings - include descriptions for every advertised MCP tool - preserve resource data-source exposure on full updates - render mixed expression/element children in the Builder canvas - preserve explicit outer Collection references in nested scopes - reject unsupported `update-page-settings` fields instead of dropping them - reject unavailable asset-query variables and log server error details Closes #6390 Closes #6391 Closes #6392 Closes #6393 Closes #6394 Closes #6395 Closes #6398 Closes #6399 Closes #6401 Closes #6404 Closes #6405 ## Verification - 484 project-build tests - 62 CLI tests - 35 Builder browser tests - 25 SDK tests - project-build, Builder, CLI, and SDK type checks - root lint and generated runtime contracts
79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import { ROOT_INSTANCE_ID, type Instances } from "@webstudio-is/sdk";
|
|
import {
|
|
isRepeatedContentBlockOccurrence,
|
|
parseContentBlockRenderScope,
|
|
resolveContentBlockOccurrenceAssetId,
|
|
} from "./content-block-source-utils";
|
|
|
|
const selector = ["block", "collection[item]", "collection", "body"];
|
|
|
|
describe("Content Block occurrence source", () => {
|
|
test("parses only instance selectors", () => {
|
|
expect(parseContentBlockRenderScope(JSON.stringify(selector))).toEqual(
|
|
selector
|
|
);
|
|
expect(parseContentBlockRenderScope("{}")).toBeUndefined();
|
|
expect(parseContentBlockRenderScope('["block",1]')).toBeUndefined();
|
|
});
|
|
|
|
test("resolves a root-qualified variable scope", () => {
|
|
const values = new Map([["asset", "article"]]);
|
|
const rootQualified = new Map([
|
|
[JSON.stringify([...selector, ROOT_INSTANCE_ID]), values],
|
|
]);
|
|
expect(
|
|
resolveContentBlockOccurrenceAssetId({
|
|
source: { type: "expression", value: "asset" },
|
|
instanceSelector: selector,
|
|
variableValuesByRenderScope: rootQualified,
|
|
})
|
|
).toBe("article");
|
|
});
|
|
|
|
test("resolves each bound Collection occurrence independently", () => {
|
|
const first = ["block", "collection[first]", "collection", "body"];
|
|
const second = ["block", "collection[second]", "collection", "body"];
|
|
const values = new Map([
|
|
[JSON.stringify(first), new Map([["asset", "a.mdx"]])],
|
|
[JSON.stringify(second), new Map([["asset", "b.mdx"]])],
|
|
]);
|
|
|
|
expect(
|
|
[first, second].map((instanceSelector) =>
|
|
resolveContentBlockOccurrenceAssetId({
|
|
source: { type: "expression", value: "asset" },
|
|
instanceSelector,
|
|
variableValuesByRenderScope: values,
|
|
})
|
|
)
|
|
).toEqual(["a.mdx", "b.mdx"]);
|
|
});
|
|
|
|
test("detects repeated selectors consistently", () => {
|
|
const instances = new Map(
|
|
["block", "collection", "body"].map((id) => [
|
|
id,
|
|
{
|
|
type: "instance" as const,
|
|
id,
|
|
component: "Box",
|
|
children: [],
|
|
},
|
|
])
|
|
) as Instances;
|
|
expect(
|
|
isRepeatedContentBlockOccurrence({
|
|
instanceSelector: selector,
|
|
instances,
|
|
})
|
|
).toBe(true);
|
|
expect(
|
|
isRepeatedContentBlockOccurrence({
|
|
instanceSelector: ["block", "collection", "body"],
|
|
instances,
|
|
})
|
|
).toBe(false);
|
|
});
|
|
});
|