Route kebab Customize through the prefilled policy wizard so existing methods and values can be renamed, reordered, and kept in that field order on the card after Finalize.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,6 +13,12 @@ describe("CoreValuesSelectScreen", () => {
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Discard" }));
|
||||
}
|
||||
|
||||
async function editMeaningInOpenDialog(next: string) {
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
const fields = within(dialog).getAllByRole("textbox");
|
||||
fireEvent.change(fields[0], { target: { value: next } });
|
||||
}
|
||||
|
||||
it("opens core value detail modal when a preset chip is clicked", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
@@ -20,20 +26,36 @@ describe("CoreValuesSelectScreen", () => {
|
||||
expect(
|
||||
within(dialog).getByRole("button", { name: "Add Value" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByRole("menuitem", { name: "Customize" }),
|
||||
).not.toBeInTheDocument();
|
||||
fireEvent.click(within(dialog).getByRole("button", { name: "More options" }));
|
||||
expect(
|
||||
screen.queryByRole("menuitem", { name: "Customize" }),
|
||||
screen.getByRole("menuitem", { name: "Customize" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("menuitem", { name: "Duplicate" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByRole("menuitem", { name: "Remove" }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("asks to discard when closing a pending value, then unselects on Discard", async () => {
|
||||
it("closes a pending value without confirm when fields are unchanged", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
await screen.findByRole("dialog");
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Keep editing" }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("asks to discard when closing a pending value after an edit", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
await editMeaningInOpenDialog("Changed meaning");
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
expect(
|
||||
await screen.findByRole("button", { name: "Keep editing" }),
|
||||
).toBeInTheDocument();
|
||||
@@ -46,7 +68,7 @@ describe("CoreValuesSelectScreen", () => {
|
||||
it("keeps the pending value modal open when Keep editing is chosen", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
await screen.findByRole("dialog");
|
||||
await editMeaningInOpenDialog("Changed meaning");
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Keep editing" }));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
@@ -78,6 +100,162 @@ describe("CoreValuesSelectScreen", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("shows Remove only after the value has been added", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const pending = await screen.findByRole("dialog");
|
||||
fireEvent.click(within(pending).getByRole("button", { name: "Add Value" }));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const editing = await screen.findByRole("dialog");
|
||||
fireEvent.click(
|
||||
within(editing).getByRole("button", { name: "More options" }),
|
||||
);
|
||||
expect(screen.getByRole("menuitem", { name: "Remove" })).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("menuitem", { name: "Customize" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("menuitem", { name: "Duplicate" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("Customize walks name and description before policy details", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
fireEvent.click(
|
||||
within(dialog).getByRole("button", { name: "More options" }),
|
||||
);
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Customize" }));
|
||||
|
||||
expect(await screen.findByPlaceholderText("Policy name")).toHaveValue(
|
||||
"Accessibility",
|
||||
);
|
||||
expect(screen.queryByText("Custom policy details")).not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole("button", { name: "Next" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Next" }));
|
||||
expect(
|
||||
await screen.findByText("Custom policy details"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", {
|
||||
name: "What does this value mean to your group?",
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("Customize shows meaning saved from the value modal", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const pending = await screen.findByRole("dialog");
|
||||
const fields = within(pending).getAllByRole("textbox");
|
||||
fireEvent.change(fields[0], {
|
||||
target: { value: "Edited meaning from value modal" },
|
||||
});
|
||||
fireEvent.click(within(pending).getByRole("button", { name: "Add Value" }));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const editing = await screen.findByRole("dialog");
|
||||
fireEvent.click(
|
||||
within(editing).getByRole("button", { name: "More options" }),
|
||||
);
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Customize" }));
|
||||
expect(await screen.findByPlaceholderText("Policy name")).toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole("button", { name: "Next" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Next" }));
|
||||
fireEvent.click(
|
||||
await screen.findByRole("button", {
|
||||
name: "What does this value mean to your group?",
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
screen.getByDisplayValue("Edited meaning from value modal"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("closing Customize without Finalize returns to the value modal", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
fireEvent.click(
|
||||
within(dialog).getByRole("button", { name: "More options" }),
|
||||
);
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Customize" }));
|
||||
expect(
|
||||
await screen.findByPlaceholderText("Policy name"),
|
||||
).toBeInTheDocument();
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.queryByPlaceholderText("Policy name"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
const valueDialog = screen.getByRole("dialog");
|
||||
expect(
|
||||
within(valueDialog).getByRole("button", { name: "Add Value" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("Customize Finalize shows reordered fields in the value modal", async () => {
|
||||
renderWithProviders(<CoreValuesSelectScreen />);
|
||||
fireEvent.click(screen.getByText("Accessibility"));
|
||||
const dialog = await screen.findByRole("dialog");
|
||||
fireEvent.click(
|
||||
within(dialog).getByRole("button", { name: "More options" }),
|
||||
);
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Customize" }));
|
||||
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Next" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Next" }));
|
||||
expect(
|
||||
await screen.findByText("Custom policy details"),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const handles = screen.getAllByRole("button", {
|
||||
name: "Drag to reorder this field",
|
||||
});
|
||||
const rows = screen.getAllByRole("listitem");
|
||||
const store: Record<string, string> = {};
|
||||
const dataTransfer = {
|
||||
effectAllowed: "all",
|
||||
dropEffect: "move",
|
||||
setData(type: string, value: string) {
|
||||
store[type] = value;
|
||||
},
|
||||
getData(type: string) {
|
||||
return store[type] ?? "";
|
||||
},
|
||||
};
|
||||
fireEvent.pointerDown(handles[0]);
|
||||
fireEvent.dragStart(rows[0], { dataTransfer });
|
||||
fireEvent.drop(rows[1], { dataTransfer });
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Finalize" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.queryByPlaceholderText("Policy name"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
const result = screen.getByRole("dialog");
|
||||
const labels = within(result)
|
||||
.getAllByRole("textbox")
|
||||
.map((el) => {
|
||||
const labelledby = el.getAttribute("aria-labelledby");
|
||||
return labelledby
|
||||
? (document.getElementById(labelledby)?.textContent ?? "").trim()
|
||||
: "";
|
||||
});
|
||||
expect(labels[0]).toMatch(/Signals of Violation/);
|
||||
expect(labels[1]).toMatch(/What does this value mean to your group/);
|
||||
});
|
||||
|
||||
// The "Add value" → custom-chip → modal flow uses a `customPending`
|
||||
// session: dismissing the modal must drop the brand-new chip entirely
|
||||
// (not just unselect it), because the user never confirmed it via
|
||||
@@ -118,7 +296,6 @@ describe("CoreValuesSelectScreen", () => {
|
||||
expect(countCustomChips(CUSTOM_LABEL)).toBe(1);
|
||||
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Discard" }));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user