124 lines
3.9 KiB
TypeScript
124 lines
3.9 KiB
TypeScript
import { fireEvent, render } from "@testing-library/vue";
|
|
import { describe, expect, it } from "vitest";
|
|
import DsLogicTree from "../src/components/data/DsLogicTree.vue";
|
|
import DsSortableList from "../src/components/data/DsSortableList.vue";
|
|
import type { DsLogicGroup, DsSortableItem } from "../src/types";
|
|
|
|
const sortableItems: DsSortableItem[] = [
|
|
{ id: "one", label: "Primero" },
|
|
{ id: "two", label: "Segundo" },
|
|
{ id: "three", label: "Tercero" },
|
|
];
|
|
|
|
const emptyTree: DsLogicGroup = {
|
|
id: "root",
|
|
type: "group",
|
|
operator: "and",
|
|
children: [],
|
|
};
|
|
|
|
const fields = [
|
|
{ label: "Estado", value: "status" },
|
|
{ label: "Plan", value: "plan" },
|
|
];
|
|
|
|
describe("data tools", () => {
|
|
it("reorders items with drag-and-drop and emits the movement", async () => {
|
|
const view = render(DsSortableList, {
|
|
props: { modelValue: sortableItems, label: "Prioridades" },
|
|
});
|
|
const items = view.getAllByRole("listitem");
|
|
|
|
await fireEvent.dragStart(items[0] as HTMLElement);
|
|
await fireEvent.dragOver(items[2] as HTMLElement);
|
|
await fireEvent.drop(items[2] as HTMLElement);
|
|
|
|
const updates = view.emitted()["update:modelValue"] as
|
|
unknown[][] | undefined;
|
|
const reordered = updates?.at(-1)?.[0] as DsSortableItem[] | undefined;
|
|
expect(reordered?.map((item) => item.id)).toEqual(["two", "three", "one"]);
|
|
expect(view.emitted().reorder?.at(-1)).toEqual([
|
|
expect.objectContaining({ from: 0, to: 2 }),
|
|
]);
|
|
});
|
|
|
|
it("offers buttons as an accessible alternative to dragging", async () => {
|
|
const view = render(DsSortableList, {
|
|
props: { modelValue: sortableItems, label: "Prioridades" },
|
|
});
|
|
|
|
await fireEvent.click(
|
|
view.getByRole("button", { name: "Mover abajo: Primero" }),
|
|
);
|
|
|
|
const updates = view.emitted()["update:modelValue"] as
|
|
unknown[][] | undefined;
|
|
const reordered = updates?.at(-1)?.[0] as DsSortableItem[] | undefined;
|
|
expect(reordered?.map((item) => item.id)).toEqual(["two", "one", "three"]);
|
|
expect(view.getByRole("status").textContent).toContain(
|
|
"Primero, movido a la posición 2 de 3.",
|
|
);
|
|
});
|
|
|
|
it("adds a serializable condition to a logic tree", async () => {
|
|
const view = render(DsLogicTree, {
|
|
props: { modelValue: emptyTree, fields },
|
|
});
|
|
|
|
await fireEvent.click(
|
|
view.getByRole("button", { name: "Añadir condición" }),
|
|
);
|
|
|
|
const updates = view.emitted()["update:modelValue"] as
|
|
unknown[][] | undefined;
|
|
const tree = updates?.at(-1)?.[0] as DsLogicGroup | undefined;
|
|
expect(tree?.children).toHaveLength(1);
|
|
expect(tree?.children[0]).toEqual(
|
|
expect.objectContaining({
|
|
type: "condition",
|
|
field: "status",
|
|
comparison: "equals",
|
|
value: "",
|
|
}),
|
|
);
|
|
expect(view.emitted().change?.at(-1)).toEqual([tree]);
|
|
});
|
|
|
|
it("updates operators and removes nested rules", async () => {
|
|
const tree: DsLogicGroup = {
|
|
...emptyTree,
|
|
children: [
|
|
{
|
|
id: "status",
|
|
type: "condition",
|
|
field: "status",
|
|
comparison: "equals",
|
|
value: "active",
|
|
},
|
|
],
|
|
};
|
|
const operatorView = render(DsLogicTree, {
|
|
props: { modelValue: tree, fields },
|
|
});
|
|
await fireEvent.update(
|
|
operatorView.getByLabelText("Operador lógico"),
|
|
"or",
|
|
);
|
|
const operatorUpdates = operatorView.emitted()["update:modelValue"] as
|
|
unknown[][] | undefined;
|
|
expect(
|
|
(operatorUpdates?.at(-1)?.[0] as DsLogicGroup | undefined)?.operator,
|
|
).toBe("or");
|
|
operatorView.unmount();
|
|
|
|
const removeView = render(DsLogicTree, {
|
|
props: { modelValue: tree, fields },
|
|
});
|
|
await fireEvent.click(removeView.getByRole("button", { name: "Eliminar" }));
|
|
const removeUpdates = removeView.emitted()["update:modelValue"] as
|
|
unknown[][] | undefined;
|
|
const updated = removeUpdates?.at(-1)?.[0] as DsLogicGroup | undefined;
|
|
expect(updated?.children).toEqual([]);
|
|
});
|
|
});
|