104 lines
4.8 KiB
TypeScript
104 lines
4.8 KiB
TypeScript
import React, { useState } from "react";
|
|
import "@testing-library/jest-dom";
|
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
|
|
import { moveItem } from "./cvBuilder";
|
|
import { useDragReorder } from "./hooks/useDragReorder";
|
|
|
|
function EntryList({ section }: { section: string }) {
|
|
const [items, setItems] = useState([`${section}1`, `${section}2`]);
|
|
const drag = useDragReorder((from, to) => setItems(current => moveItem(current, from, to)));
|
|
return <div>
|
|
<output aria-label={`${section} item order`}>{items.join(",")}</output>
|
|
{items.map((item, index) => <div key={item} data-testid={item} {...drag.getItemProps(index)}>
|
|
{item}<input aria-label={`${item} title`} defaultValue={item} />
|
|
</div>)}
|
|
</div>;
|
|
}
|
|
|
|
function NestedLists({ onOuterEnd = () => {} }: { onOuterEnd?: React.DragEventHandler }) {
|
|
const [sections, setSections] = useState(["A", "B"]);
|
|
const drag = useDragReorder((from, to) => setSections(current => moveItem(current, from, to)));
|
|
return <div onDragEnd={onOuterEnd}>
|
|
<output aria-label="Section order">{sections.join(",")}</output>
|
|
{sections.map((section, index) => <div key={section} data-testid={`section-${section}`} {...drag.getItemProps(index)}>
|
|
<EntryList section={section} />
|
|
</div>)}
|
|
</div>;
|
|
}
|
|
|
|
function dataTransfer() {
|
|
return { effectAllowed: "", dropEffect: "", setData: jest.fn() };
|
|
}
|
|
|
|
test("[P5-14 PRES-C07] nested item drag reorders only the owning item list", () => {
|
|
render(<NestedLists />);
|
|
const source = screen.getByTestId("A2");
|
|
const target = screen.getByTestId("A1");
|
|
const transfer = dataTransfer();
|
|
fireEvent.dragStart(source, { dataTransfer: transfer });
|
|
expect(transfer.setData).toHaveBeenCalledWith("text/plain", "1");
|
|
fireEvent.dragOver(target, { dataTransfer: transfer });
|
|
fireEvent.drop(target, { dataTransfer: transfer });
|
|
fireEvent.dragEnd(source, { dataTransfer: transfer });
|
|
expect(screen.getByLabelText("A item order")).toHaveTextContent("A2,A1");
|
|
expect(screen.getByLabelText("B item order")).toHaveTextContent("B1,B2");
|
|
expect(screen.getByLabelText("Section order")).toHaveTextContent("A,B");
|
|
});
|
|
|
|
test("[P5-14 PRES-C07] unsupported cross-section item drop cannot reorder sections", () => {
|
|
render(<NestedLists />);
|
|
const source = screen.getByTestId("A2");
|
|
const target = screen.getByLabelText("B1 title");
|
|
const transfer = dataTransfer();
|
|
fireEvent.dragStart(source, { dataTransfer: transfer });
|
|
fireEvent.dragOver(target, { dataTransfer: transfer });
|
|
expect(fireEvent.drop(target, { dataTransfer: transfer })).toBe(false);
|
|
fireEvent.dragEnd(source, { dataTransfer: transfer });
|
|
expect(screen.getByLabelText("Section order")).toHaveTextContent("A,B");
|
|
expect(screen.getByLabelText("A item order")).toHaveTextContent("A1,A2");
|
|
expect(screen.getByLabelText("B item order")).toHaveTextContent("B1,B2");
|
|
});
|
|
|
|
test("[P5-14 PRES-C07] section drag over an inactive nested item reaches the section owner", () => {
|
|
render(<NestedLists />);
|
|
const source = screen.getByTestId("section-A");
|
|
const target = screen.getByTestId("B1");
|
|
const transfer = dataTransfer();
|
|
fireEvent.dragStart(source, { dataTransfer: transfer });
|
|
fireEvent.dragOver(target, { dataTransfer: transfer });
|
|
fireEvent.drop(target, { dataTransfer: transfer });
|
|
fireEvent.dragEnd(source, { dataTransfer: transfer });
|
|
expect(screen.getByLabelText("Section order")).toHaveTextContent("B,A");
|
|
expect(screen.getByLabelText("A item order")).toHaveTextContent("A1,A2");
|
|
expect(screen.getByLabelText("B item order")).toHaveTextContent("B1,B2");
|
|
});
|
|
|
|
test("[P5-14 PRES-C07] source dragend retains ownership after drop resets state and clears a cancelled gesture", () => {
|
|
const outerEnd = jest.fn();
|
|
render(<NestedLists onOuterEnd={outerEnd} />);
|
|
const source = screen.getByTestId("A2");
|
|
const target = screen.getByTestId("A1");
|
|
const transfer = dataTransfer();
|
|
fireEvent.dragStart(source, { dataTransfer: transfer });
|
|
fireEvent.dragOver(target, { dataTransfer: transfer });
|
|
fireEvent.drop(target, { dataTransfer: transfer });
|
|
fireEvent.dragEnd(source, { dataTransfer: transfer });
|
|
expect(outerEnd).not.toHaveBeenCalled();
|
|
|
|
fireEvent.dragStart(target, { dataTransfer: transfer });
|
|
fireEvent.dragOver(source, { dataTransfer: transfer });
|
|
fireEvent.dragEnd(target, { dataTransfer: transfer });
|
|
expect(outerEnd).not.toHaveBeenCalled();
|
|
fireEvent.drop(source, { dataTransfer: transfer });
|
|
expect(screen.getByLabelText("A item order")).toHaveTextContent("A2,A1");
|
|
|
|
fireEvent.dragStart(target, { dataTransfer: transfer });
|
|
fireEvent.dragOver(source, { dataTransfer: transfer });
|
|
fireEvent.drop(source, { dataTransfer: transfer });
|
|
fireEvent.dragEnd(target, { dataTransfer: transfer });
|
|
expect(screen.getByLabelText("A item order")).toHaveTextContent("A1,A2");
|
|
expect(screen.getByLabelText("Section order")).toHaveTextContent("A,B");
|
|
expect(outerEnd).not.toHaveBeenCalled();
|
|
});
|