import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, act } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { AppShell } from "@/components/AppShell"; import { useNavStore } from "@/stores/nav-store"; import { useFocusStore } from "@/stores/focus-store"; import { useCaptureStore } from "@/stores/capture-store"; import { useInboxStore } from "@/stores/inbox-store"; import { simulateEvent, resetMocks } from "../mocks/tauri-api"; import { makeFocusItem } from "../helpers/fixtures"; function renderWithProviders(ui: React.ReactElement) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); return render( {ui} ); } describe("AppShell", () => { beforeEach(() => { useNavStore.setState({ activeView: "focus" }); useFocusStore.setState({ current: null, queue: [], isLoading: false, error: null, }); useCaptureStore.setState({ isOpen: false, isSubmitting: false, lastCapturedId: null, error: null, }); useInboxStore.setState({ items: [], }); resetMocks(); }); it("renders navigation tabs", () => { renderWithProviders(); expect(screen.getByText("Focus")).toBeInTheDocument(); expect(screen.getByText("Queue")).toBeInTheDocument(); expect(screen.getByText("Inbox")).toBeInTheDocument(); expect(screen.getByText("Debug")).toBeInTheDocument(); }); it("shows Focus view by default", () => { renderWithProviders(); expect(screen.getByText(/all clear/i)).toBeInTheDocument(); }); it("switches to Queue view when Queue tab is clicked", async () => { const user = userEvent.setup(); renderWithProviders(); await user.click(screen.getByText("Queue")); expect(await screen.findByText(/no items/i)).toBeInTheDocument(); }); it("switches to Inbox view and shows inbox zero", async () => { const user = userEvent.setup(); renderWithProviders(); await user.click(screen.getByText("Inbox")); // When inbox is empty, shows "Inbox Zero" / "All caught up!" expect(await screen.findByText(/inbox zero/i)).toBeInTheDocument(); }); it("switches to Debug view when Debug tab is clicked", async () => { const user = userEvent.setup(); renderWithProviders(); await user.click(screen.getByText("Debug")); expect(await screen.findByText(/lore debug/i)).toBeInTheDocument(); }); it("shows queue count badge when items exist", () => { useFocusStore.setState({ current: makeFocusItem({ id: "a" }), queue: [makeFocusItem({ id: "b" }), makeFocusItem({ id: "c" })], }); renderWithProviders(); expect(screen.getByTestId("queue-badge")).toHaveTextContent("3"); }); it("opens quick capture overlay on global shortcut event", async () => { renderWithProviders(); act(() => { simulateEvent("global-shortcut-triggered", "quick-capture"); }); expect(useCaptureStore.getState().isOpen).toBe(true); expect(screen.getByPlaceholderText("Capture a thought...")).toBeInTheDocument(); }); it("clicking queue item sets focus and switches to focus view", async () => { const user = userEvent.setup(); useFocusStore.setState({ current: makeFocusItem({ id: "current", title: "Current" }), queue: [ makeFocusItem({ id: "target", type: "issue", title: "Target item", }), ], }); renderWithProviders(); // Navigate to queue and wait for transition await user.click(screen.getByText("Queue")); const targetItem = await screen.findByText("Target item"); // Click on the target item await user.click(targetItem); // Should switch back to focus view with the target as current expect(useFocusStore.getState().current?.id).toBe("target"); expect(useNavStore.getState().activeView).toBe("focus"); }); });