Files
PacketStation/frontend/src/screens/stall/StallHome.test.tsx
T

98 lines
4.2 KiB
TypeScript
Raw Normal View History

import { fireEvent, screen, waitFor, within } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ShopCard, StallAnswer, StationOption } from "../../api/shop";
import { DEPARTMENTS, makeMe, renderApp } from "../../test/auth";
import { mockFetch } from "../../test/fetchMock";
import { makeCard } from "../../test/packets";
import { memoryStorage } from "../supervisor/memoryStorage";
import { NO_STATION, STALL_KEY } from "./StallHome";
const ANDY = makeMe({ roles: ["shop:03:worker"], screens: ["stall"], user: { sam_account: "weld.andy", display_name: "Andy Welder" } });
const STATIONS: StationOption[] = [
{ dept_code: "03", dept_name: "Weld Parts", id: 1, name: "Stall 1" },
{ dept_code: "03", dept_name: "Weld Parts", id: 2, name: "Stall 2" },
];
function shopCard(id: number, over: Partial<ShopCard> = {}): ShopCard {
const { open_cos: _ignored, ...base } = makeCard({ id, unit: { id: 100 + id, number: `L66200${id}` }, holder: "Stall 1" });
return { ...base, open_cos: [], ...over };
}
function stall(id: number): StallAnswer {
const st = STATIONS.find((s) => s.id === id) as StationOption;
return {
station: { id, name: st.name, dept_code: "03", dept_name: "Weld Parts" },
mine:
id === 1
? [shopCard(1, { status: "in_progress", station: { id: 1, name: "Stall 1" }, clock: { elapsed_ms: 3_600_000, running: false }, target_hrs: 4.5 })]
: [],
submitted: id === 1 ? [shopCard(2, { status: "review", station: { id: 1, name: "Stall 1" } })] : [],
};
}
function base(stations: StationOption[] = STATIONS) {
return {
"/api/auth/me": { body: ANDY },
"/api/departments": { body: DEPARTMENTS },
"/api/shop/stations": { body: stations },
"/api/shop/stall?station_id=1": { body: stall(1) },
"/api/shop/stall?station_id=2": { body: stall(2) },
};
}
const column = (title: string) => screen.getByRole("heading", { name: new RegExp(`^${title}`) }).closest("section") as HTMLElement;
beforeEach(() => {
vi.stubGlobal("localStorage", memoryStorage());
});
describe("StallHome", () => {
it("shows the hero, the picker and the two boards", async () => {
mockFetch(base());
renderApp("/stall");
expect(await screen.findByText("STALL 1")).toBeInTheDocument();
expect(screen.getByText("03 Weld Parts")).toHaveClass("eyebrow");
expect(screen.getByText("Packets your supervisor sends to this station appear here.")).toBeInTheDocument();
expect(screen.getByRole("combobox", { name: "Station" })).toHaveValue("1");
const mine = await waitFor(() => column("My packets"));
const card = within(mine).getByRole("link", { name: /^L662001/ });
expect(card).toHaveTextContent("01:00:00 paused · target 4.5 h");
expect(card).toHaveTextContent("Working");
expect(within(column("Submitted, waiting on supervisor")).getByRole("link", { name: /^L662002/ })).toBeInTheDocument();
});
it("switches station and remembers it", async () => {
const fetch = mockFetch(base());
renderApp("/stall");
const pick = await screen.findByRole("combobox", { name: "Station" });
fireEvent.change(pick, { target: { value: "2" } });
expect(await screen.findByText("STALL 2")).toBeInTheDocument();
await waitFor(() => expect(fetch.mock.calls.some(([u]) => String(u) === "/api/shop/stall?station_id=2")).toBe(true));
expect(window.localStorage.getItem(STALL_KEY)).toBe("2");
expect(await screen.findByText("No work assigned to this stall right now.")).toBeInTheDocument();
expect(screen.getByText("Nothing waiting.")).toBeInTheDocument();
});
it("starts on the remembered station", async () => {
window.localStorage.setItem(STALL_KEY, "2");
mockFetch(base());
renderApp("/stall");
expect(await screen.findByText("STALL 2")).toBeInTheDocument();
});
it("hides the picker with one station", async () => {
mockFetch(base([STATIONS[0] as StationOption]));
renderApp("/stall");
expect(await screen.findByText("STALL 1")).toBeInTheDocument();
expect(screen.queryByRole("combobox", { name: "Station" })).not.toBeInTheDocument();
});
it("says so when the user has no station", async () => {
mockFetch(base([]));
renderApp("/stall");
expect(await screen.findByText(NO_STATION)).toBeInTheDocument();
});
});