diff --git a/packages/chess/src/ui/visual-builder/preview/BoardDiagramView.test.tsx b/packages/chess/src/ui/visual-builder/preview/BoardDiagramView.test.tsx
new file mode 100644
index 0000000..dd620e5
--- /dev/null
+++ b/packages/chess/src/ui/visual-builder/preview/BoardDiagramView.test.tsx
@@ -0,0 +1,118 @@
+/**
+ * BoardDiagramView test suite — validates board diagram rendering for
+ * effect primitives: square highlighting (on-moved-onto-square),
+ * aura rendering (add-aura), and the empty state placeholder.
+ *
+ * Rendering approach: React SSR (`renderToStaticMarkup`) — no DOM mount,
+ * purely the declarative tree. Assertions check for data-testid attributes
+ * and expected HTML structure.
+ */
+import { describe, it, expect } from "vitest";
+import { renderToStaticMarkup } from "react-dom/server";
+import "../../../modifiers/primitives/index.js";
+import type { CustomModifierDescriptor } from "../../../modifiers/custom/types.js";
+import type { EffectPrimitiveNode } from "../../../modifiers/primitives/types.js";
+import { BoardDiagramView } from "./BoardDiagramView.js";
+
+/**
+ * Factory: minimal valid descriptor for testing.
+ */
+function createSampleDescriptor(
+ primitives: readonly EffectPrimitiveNode[] = []
+): CustomModifierDescriptor {
+ return {
+ type: "data",
+ id: "test-board-1" as unknown as CustomModifierDescriptor["id"],
+ name: "Test Board Modifier",
+ description: "A test modifier for board effects",
+ version: 1,
+ primitives,
+ targetAttrs: [],
+ uiForm: "primitive-composer",
+ source: "custom",
+ };
+}
+
+describe("BoardDiagramView", () => {
+ it("empty descriptor renders 'No board effect' placeholder", () => {
+ const descriptor = createSampleDescriptor([]);
+ const html = renderToStaticMarkup(
+
+ );
+
+ expect(html).toContain("No board effect");
+ // Should NOT render SVG when there's no board effect
+ expect(html).not.toContain("