Files
community-rule/tests/unit/methodCardWizardPrefill.test.ts
T
adilalloandCursor 20ea4a2f30 Give MultiSelect chips accessible names and start creation fields empty.
Catalog chips now announce Select or Deselect so they are named for assistive tech. Method and value modals open blank; Generate draft inserts the catalog copy that used to be prefilled, and Customize still keeps the section headings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 15:59:00 -06:00

342 lines
9.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
buildMethodCardWizardInitialValues,
coreValueDetailsFromWizardFieldBlocks,
facetDetailsToWizardFieldBlocks,
overlayFacetPrefillValues,
} from "../../lib/create/methodCardWizardPrefill";
import type { CustomMethodCardFieldBlock } from "../../lib/create/customMethodCardFieldBlocks";
const cardId = "signal";
const blocks: CustomMethodCardFieldBlock[] = [
{ kind: "text", id: "b1", blockTitle: "Notes", placeholderText: "…" },
];
const commHeadings = {
corePrinciple: "Core Principle & Scope",
logisticsAdmin: "Logistics, Admin & Norms",
codeOfConduct: "Code of Conduct",
};
describe("buildMethodCardWizardInitialValues", () => {
it("uses fallback title and description when meta is missing", () => {
expect(
buildMethodCardWizardInitialValues({
cardId,
fallbackTitle: "Signal",
fallbackDescription: "Encrypted messaging.",
meta: {},
persistedBlocks: {},
draftFieldBlocks: null,
}),
).toEqual({
title: "Signal",
description: "Encrypted messaging.",
fieldBlocks: [],
});
});
it("maps facet body fields onto wizard blocks when none exist yet", () => {
expect(
buildMethodCardWizardInitialValues({
cardId,
fallbackTitle: "Signal",
fallbackDescription: "Encrypted messaging.",
meta: {},
persistedBlocks: {},
draftFieldBlocks: null,
facetPrefill: {
group: "communication",
draft: {
corePrinciple: "Privacy first.",
logisticsAdmin: "Admins steward access.",
codeOfConduct: "No leaks.",
},
headings: commHeadings,
},
}).fieldBlocks,
).toEqual([
{
kind: "text",
id: "facet-corePrinciple",
blockTitle: "Core Principle & Scope",
placeholderText: "Privacy first.",
},
{
kind: "text",
id: "facet-logisticsAdmin",
blockTitle: "Logistics, Admin & Norms",
placeholderText: "Admins steward access.",
},
{
kind: "text",
id: "facet-codeOfConduct",
blockTitle: "Code of Conduct",
placeholderText: "No leaks.",
},
]);
});
it("prefers persisted meta title and description over fallbacks", () => {
expect(
buildMethodCardWizardInitialValues({
cardId,
fallbackTitle: "Signal",
fallbackDescription: "Encrypted messaging.",
meta: {
[cardId]: { label: "Our Signal", supportText: "Private ops." },
},
persistedBlocks: { [cardId]: blocks },
draftFieldBlocks: null,
}),
).toEqual({
title: "Our Signal",
description: "Private ops.",
fieldBlocks: blocks,
});
});
it("overlays current facet field values onto matching persisted blocks", () => {
const persisted: CustomMethodCardFieldBlock[] = [
{
kind: "text",
id: "facet-corePrinciple",
blockTitle: "Core Principle & Scope",
placeholderText: "Stale principle",
},
{
kind: "text",
id: "extra-notes",
blockTitle: "Notes",
placeholderText: "keep",
},
];
expect(
buildMethodCardWizardInitialValues({
cardId,
fallbackTitle: "Signal",
fallbackDescription: "Encrypted messaging.",
meta: {},
persistedBlocks: { [cardId]: persisted },
draftFieldBlocks: null,
facetPrefill: {
group: "communication",
draft: {
corePrinciple: "Updated principle",
logisticsAdmin: "Updated logistics",
codeOfConduct: "Updated coc",
},
headings: commHeadings,
},
}).fieldBlocks,
).toEqual([
{
kind: "text",
id: "facet-corePrinciple",
blockTitle: "Core Principle & Scope",
placeholderText: "Updated principle",
},
{
kind: "text",
id: "extra-notes",
blockTitle: "Notes",
placeholderText: "keep",
},
{
kind: "text",
id: "facet-logisticsAdmin",
blockTitle: "Logistics, Admin & Norms",
placeholderText: "Updated logistics",
},
{
kind: "text",
id: "facet-codeOfConduct",
blockTitle: "Code of Conduct",
placeholderText: "Updated coc",
},
]);
});
it("prefers in-modal field-block drafts over persisted blocks", () => {
const draft: CustomMethodCardFieldBlock[] = [
{ kind: "proportion", id: "p1", blockTitle: "Share", defaultPercent: 40 },
];
expect(
buildMethodCardWizardInitialValues({
cardId,
fallbackTitle: "Signal",
fallbackDescription: "Encrypted messaging.",
meta: {
[cardId]: { label: "Our Signal", supportText: "Private ops." },
},
persistedBlocks: { [cardId]: blocks },
draftFieldBlocks: draft,
}).fieldBlocks,
).toEqual(draft);
});
});
describe("facetDetailsToWizardFieldBlocks", () => {
it("keeps catalog field headings when facet copy is empty", () => {
expect(
facetDetailsToWizardFieldBlocks({
group: "communication",
draft: {
corePrinciple: " ",
logisticsAdmin: "",
codeOfConduct: "",
},
headings: commHeadings,
}),
).toEqual([
{
kind: "text",
id: "facet-corePrinciple",
blockTitle: "Core Principle & Scope",
placeholderText: " ",
},
{
kind: "text",
id: "facet-logisticsAdmin",
blockTitle: "Logistics, Admin & Norms",
placeholderText: "",
},
{
kind: "text",
id: "facet-codeOfConduct",
blockTitle: "Code of Conduct",
placeholderText: "",
},
]);
});
it("maps decision scope chips to a badge block", () => {
const blocksOut = facetDetailsToWizardFieldBlocks({
group: "decisionApproaches",
draft: {
corePrinciple: "Momentum.",
applicableScope: ["Daily Operations"],
selectedApplicableScope: [],
stepByStepInstructions: "Post a deadline.",
consensusLevel: 100,
objectionsDeadlocks: "Any member can block.",
},
headings: {
corePrinciple: "Core Principle",
applicableScope: "Applicable Scope",
stepByStepInstructions: "Step-by-Step Instructions",
consensusLevel: "Consensus Level",
objectionsDeadlocks: "Objections & Deadlocks",
},
});
expect(blocksOut.find((b) => b.kind === "badges")).toMatchObject({
kind: "badges",
blockTitle: "Applicable Scope",
options: ["Daily Operations"],
});
expect(blocksOut.find((b) => b.kind === "proportion")).toMatchObject({
defaultPercent: 100,
});
});
it("omits a consensus proportion when the draft has no consensus level", () => {
const blocksOut = facetDetailsToWizardFieldBlocks({
group: "decisionApproaches",
draft: {
corePrinciple: "Momentum.",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "Post a deadline.",
objectionsDeadlocks: "",
},
headings: {
corePrinciple: "Core Principle",
applicableScope: "Applicable Scope",
stepByStepInstructions: "Step-by-Step Instructions",
consensusLevel: "Consensus Level",
objectionsDeadlocks: "Objections & Deadlocks",
},
});
expect(blocksOut.find((b) => b.kind === "proportion")).toBeUndefined();
});
it("does not inject a seeded 75% proportion onto empty custom drafts", () => {
const next = overlayFacetPrefillValues([], {
group: "decisionApproaches",
draft: {
corePrinciple: "",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "",
consensusLevel: 75,
objectionsDeadlocks: "",
},
headings: {
corePrinciple: "Core Principle",
applicableScope: "Applicable Scope",
stepByStepInstructions: "Step-by-Step Instructions",
consensusLevel: "Consensus Level",
objectionsDeadlocks: "Objections & Deadlocks",
},
});
expect(next).toEqual([]);
});
it("maps core value meaning and signals onto text blocks", () => {
expect(
facetDetailsToWizardFieldBlocks({
group: "coreValues",
draft: {
meaning: "Everyone can join.",
signals: "Inaccessible venues.",
},
headings: {
meaning: "What does this value mean to your group?",
signals: "Signals of Violation",
},
}),
).toEqual([
{
kind: "text",
id: "facet-meaning",
blockTitle: "What does this value mean to your group?",
placeholderText: "Everyone can join.",
},
{
kind: "text",
id: "facet-signals",
blockTitle: "Signals of Violation",
placeholderText: "Inaccessible venues.",
},
]);
});
});
describe("coreValueDetailsFromWizardFieldBlocks", () => {
it("reads meaning and signals from facet block ids", () => {
expect(
coreValueDetailsFromWizardFieldBlocks(
[
{
kind: "text",
id: "facet-meaning",
blockTitle: "Meaning",
placeholderText: "Updated meaning",
},
{
kind: "text",
id: "facet-signals",
blockTitle: "Signals",
placeholderText: "Updated signals",
},
],
{ meaning: "old m", signals: "old s", supportText: "keep" },
),
).toEqual({
meaning: "Updated meaning",
signals: "Updated signals",
supportText: "keep",
});
});
});