import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { server } from "../../mocks/server"; import { errorHandlers, resetCasesAttempts } from "../../mocks/handlers"; import { CaseSelector } from "../CaseSelector"; describe("CaseSelector", () => { const mockOnSelectCase = vi.fn(); beforeEach(() => { mockOnSelectCase.mockClear(); resetCasesAttempts(); }); it("shows loading state initially", () => { render( , ); expect(screen.getByText(/loading/i)).toBeInTheDocument(); }); it("renders select after loading", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }); }); it("displays all cases as options", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }); expect( screen.getByRole("option", { name: /sub-stroke0001/i }), ).toBeInTheDocument(); expect( screen.getByRole("option", { name: /sub-stroke0002/i }), ).toBeInTheDocument(); expect( screen.getByRole("option", { name: /sub-stroke0003/i }), ).toBeInTheDocument(); }); it("has placeholder option", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }); expect( screen.getByRole("option", { name: /choose a case/i }), ).toBeInTheDocument(); }); it("calls onSelectCase when case selected", async () => { const user = userEvent.setup(); render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }); await user.selectOptions(screen.getByRole("combobox"), "sub-stroke0001"); expect(mockOnSelectCase).toHaveBeenCalledWith("sub-stroke0001"); }); it("shows selected case value", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toHaveValue("sub-stroke0002"); }); }); it("shows error state on API failure", async () => { server.use(errorHandlers.casesServerError); render( , ); await waitFor(() => { expect(screen.getByText(/failed to load/i)).toBeInTheDocument(); }); }); it("applies correct styling", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }); const container = screen.getByRole("combobox").closest("div"); expect(container).toHaveClass("bg-gray-800"); }); it("retries on 503 cold-start and succeeds", async () => { server.use(errorHandlers.casesColdStart); render( , ); // Should show waking up message during retry await waitFor( () => { expect(screen.getByText(/waking up/i)).toBeInTheDocument(); }, { timeout: 3000 }, ); // Should eventually succeed and show cases await waitFor( () => { expect(screen.getByRole("combobox")).toBeInTheDocument(); }, { timeout: 5000 }, ); expect( screen.getByRole("option", { name: /sub-stroke0001/i }), ).toBeInTheDocument(); }); });