import { fireEvent, render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { frames, inlineCatalog, part } from "@/lib/hive/test-utils"; import type { HiveState } from "@/lib/hive/types"; import { HiveFocusBar, focusChips } from "./hive-focus-bar"; const catalog = inlineCatalog(); const state: HiveState = { schemaVersion: 1, stack: [ part("f", "floor", { inserts: [part("fi", "floor-insert")] }), part("b1", "box", { frames: frames(10).map((frame) => (frame.slot <= 2 ? { ...frame, type: "NONE" as const } : frame)) }), part("fe", "feeder", { state: { syrupLiters: 2.5, fondantKg: 1 } }), part("lid", "inner-lid", { state: { feedHole: "CLOSED" } }), ], }; function renderBar(extra: Partial[0]> = {}) { const props = { focusedId: "fe", name: "Futterzarge", chips: focusChips(state, catalog, "fe"), canEdit: true, onEdit: vi.fn(), onBack: vi.fn(), ...extra, }; render(); return props; } describe("focusChips", () => { it("lists levels with their maximum and choices with their German text", () => { expect(focusChips(state, catalog, "fe").map((chip) => chip.text)).toEqual([ "Flüssigfutter 2,5 l von 3 l", "Futterteig 1 kg von 2,5 kg", ]); expect(focusChips(state, catalog, "lid").map((chip) => chip.text)).toEqual(["Futterloch: zu"]); }); it("counts the frames of a box and says whether the floor holds a Bausperre", () => { expect(focusChips(state, catalog, "b1")[0].text).toBe("8 Rähmchen"); expect(focusChips(state, catalog, "f").at(-1)!.text).toBe("Bausperre drin"); }); it("finds inserts and returns nothing for unknown ids", () => { expect(focusChips(state, catalog, "fi")).toEqual([]); expect(focusChips(state, catalog, "nope")).toEqual([]); }); }); describe("HiveFocusBar", () => { it("renders nothing outside focus mode", () => { const { container } = render( , ); expect(container).toBeEmptyDOMElement(); }); it("shows „Zurück“, the name, the state chips and „Ändern“", () => { const props = renderBar(); expect(screen.getByText("Futterzarge")).toBeInTheDocument(); expect(screen.getByText("Flüssigfutter 2,5 l von 3 l")).toBeInTheDocument(); fireEvent.click(screen.getByRole("button", { name: "Zurück" })); expect(props.onBack).toHaveBeenCalled(); fireEvent.click(screen.getByRole("button", { name: "Ändern" })); expect(props.onEdit).toHaveBeenCalled(); }); it("hides „Ändern“ for readers", () => { renderBar({ canEdit: false }); expect(screen.queryByRole("button", { name: "Ändern" })).toBeNull(); }); it("leaves focus mode on Esc", () => { const props = renderBar(); fireEvent.keyDown(window, { key: "Escape" }); expect(props.onBack).toHaveBeenCalledTimes(1); }); it("leaves Esc to an open sheet", () => { const props = renderBar(); const dialog = document.createElement("div"); dialog.setAttribute("role", "dialog"); const input = document.createElement("input"); dialog.appendChild(input); document.body.appendChild(dialog); fireEvent.keyDown(input, { key: "Escape" }); expect(props.onBack).not.toHaveBeenCalled(); dialog.remove(); }); });