fix(registry): carousel cards fall back to their sample image inside the assets folder (#4543)

* fix(registry): carousel cards fall back to their sample image inside the assets folder

When an image variable resolves to nothing, the 25 carousel blocks loaded the
sample card by bare file name, which 404s beside the block and draws a white
card. The fallback now keeps assets/carousel-images/, the folder every card
image is installed into. A guard test fails on any block with a bare fallback.

* test(registry): the carousel fallback guard covers every block that uses it

The guard now picks each block that reads an image variable and fails when its
fallback no longer matches, instead of silently skipping it, and ignores stray
files in the blocks folder.
This commit is contained in:
Miguel Ángel
2026-09-26 15:26:19 +00:00
committed by GitHub
parent 36db44d9b7
commit 8798e40da8
26 changed files with 84 additions and 25 deletions
+34
View File
@@ -0,0 +1,34 @@
import { describe, expect, it } from "vitest";
import { readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
const blocksDir = join(import.meta.dirname, "..", "..", "registry", "blocks");
// The carousels draw each card from its image variable, or from the block's own
// sample image when the variable resolves to nothing.
const FALLBACK = /varUrl\(V\[id\]\)\s*\|\|\s*([^\n]*)DATA\.cards\[i % DATA\.cards\.length\]\.file/g;
function carousels(): Array<{ block: string; prefixes: string[] }> {
return readdirSync(blocksDir, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map(({ name }) => ({
block: name,
html: readFileSync(join(blocksDir, name, `${name}.html`), "utf8"),
}))
.filter(({ html }) => html.includes("varUrl(V[id])"))
.map(({ block, html }) => ({
block,
prefixes: [...html.matchAll(FALLBACK)].map((match) => match[1] ?? ""),
}));
}
describe("carousel image fallback", () => {
it("loads the sample image from the block's assets folder, not a bare file name", () => {
const found = carousels();
expect(found.length).toBeGreaterThan(0);
for (const { block, prefixes } of found) {
expect(prefixes.length, block).toBeGreaterThan(0);
for (const prefix of prefixes) expect(prefix, block).toContain('"assets/carousel-images/" +');
}
});
});