Files
jobtrackingapp/job-tracker-ui/src/use-drag-reorder.test.tsx
T

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();
});