// @vitest-environment jsdom // // The non-drag reorder (WCAG 2.5.7): the four menu rows and the four buttons, one rule — a move that // would go nowhere is shown off, and the rest report the index the item lands on. import { describe, it, expect, vi, afterEach } from "vitest"; import { render, renderHook, screen, fireEvent, cleanup } from "@testing-library/react"; vi.mock("react-i18next", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, useTranslation: () => ({ t: (key: string, o?: { pos?: number; total?: number }) => o?.pos !== undefined ? `${key}:${o.pos}/${o.total}` : key, }), }; }); import { OrderButtons } from "./OrderButtons"; import { useOrderItems } from "./useOrderItems"; afterEach(cleanup); describe("useOrderItems", () => { const rows = (...a: Parameters>) => renderHook(() => useOrderItems()).result.current(...a); it("offers top, up, down and bottom, each reporting where the item lands", () => { const onMove = vi.fn(); const items = rows(2, 5, onMove); expect(items.map((i) => i.id)).toEqual(["order-top", "order-up", "order-down", "order-bottom"]); expect(items.map((i) => i.label)).toEqual([ "common.order.top", "common.order.up", "common.order.down", "common.order.bottom", ]); expect(items[0]!.separatorBefore).toBe(true); items.forEach((i) => i.onSelect!()); expect(onMove.mock.calls.map((c) => c[0])).toEqual([0, 1, 3, 4]); }); it("turns off the moves that go nowhere: the first item up, the last down", () => { expect(rows(0, 3, vi.fn()).map((i) => !!i.disabled)).toEqual([true, true, false, false]); expect(rows(2, 3, vi.fn()).map((i) => !!i.disabled)).toEqual([false, false, true, true]); }); it("turns all four off with the reason under the first row only", () => { const items = rows(1, 3, vi.fn(), { reason: "sorted" }); expect(items.every((i) => i.disabled)).toBe(true); expect(items.map((i) => ("note" in i ? i.note : undefined))).toEqual([ "sorted", undefined, undefined, undefined, ]); }); }); describe("OrderButtons", () => { it("shows the item's place, moves it, and holds the moves that go nowhere off", () => { const onMove = vi.fn(); render(); expect(screen.getByRole("group").getAttribute("aria-label")).toBe( "common.order.label common.order.place:1/3", ); const btn = (name: string) => screen.getByRole("button", { name }) as HTMLButtonElement; expect(btn("common.order.top").disabled).toBe(true); expect(btn("common.order.up").disabled).toBe(true); fireEvent.click(btn("common.order.down")); fireEvent.click(btn("common.order.bottom")); expect(onMove.mock.calls.map((c) => c[0])).toEqual([1, 2]); }); });