feat(frontend): multiselect/artifact-gate/artifact widgets + linkage + no-limbo

This commit is contained in:
2026-06-28 12:36:13 +02:00
parent 2b55e96608
commit be9e761e0a
8 changed files with 389 additions and 1 deletions
@@ -0,0 +1,101 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MultiselectWidget } from "./MultiselectWidget";
test("confirms the checked ids including initially selected", async () => {
const onRespond = vi.fn();
render(
<MultiselectWidget
descriptor={{
id: "u1",
widget: "multiselect",
options: [
{ id: "t1", label: "t1", selected: true },
{ id: "t2", label: "t2" },
],
}}
onRespond={onRespond}
/>
);
await userEvent.click(screen.getByRole("checkbox", { name: /t2/ }));
await userEvent.click(screen.getByRole("button", { name: /conferma/i }));
expect(onRespond).toHaveBeenCalledWith({ id: "u1", kind: "multiselect", choices: ["t1", "t2"] });
});
test("select-all checks all options", async () => {
const onRespond = vi.fn();
render(
<MultiselectWidget
descriptor={{
id: "u1",
widget: "multiselect",
options: [
{ id: "a", label: "Alpha" },
{ id: "b", label: "Beta" },
],
}}
onRespond={onRespond}
/>
);
await userEvent.click(screen.getByRole("button", { name: /seleziona tutti/i }));
await userEvent.click(screen.getByRole("button", { name: /conferma/i }));
expect(onRespond).toHaveBeenCalledWith({ id: "u1", kind: "multiselect", choices: ["a", "b"] });
});
test("deselect-all unchecks all options", async () => {
const onRespond = vi.fn();
render(
<MultiselectWidget
descriptor={{
id: "u1",
widget: "multiselect",
options: [
{ id: "a", label: "Alpha", selected: true },
{ id: "b", label: "Beta", selected: true },
],
}}
onRespond={onRespond}
/>
);
await userEvent.click(screen.getByRole("button", { name: /deseleziona tutti/i }));
await userEvent.click(screen.getByRole("button", { name: /conferma/i }));
expect(onRespond).toHaveBeenCalledWith({ id: "u1", kind: "multiselect", choices: [] });
});
test("confirm is disabled when nothing checked and allow_empty is false", async () => {
const onRespond = vi.fn();
render(
<MultiselectWidget
descriptor={{
id: "u1",
widget: "multiselect",
allow_empty: false,
options: [{ id: "x", label: "X" }],
}}
onRespond={onRespond}
/>
);
const btn = screen.getByRole("button", { name: /conferma/i });
expect(btn).toBeDisabled();
await userEvent.click(btn);
expect(onRespond).not.toHaveBeenCalled();
});
test("confirm is enabled when allow_empty is false but something is checked", async () => {
const onRespond = vi.fn();
render(
<MultiselectWidget
descriptor={{
id: "u1",
widget: "multiselect",
allow_empty: false,
options: [{ id: "x", label: "X", selected: true }],
}}
onRespond={onRespond}
/>
);
const btn = screen.getByRole("button", { name: /conferma/i });
expect(btn).not.toBeDisabled();
await userEvent.click(btn);
expect(onRespond).toHaveBeenCalledWith({ id: "u1", kind: "multiselect", choices: ["x"] });
});