/** * Tests for Inbox component. * * TDD: These tests define the expected behavior before implementation. */ import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { Inbox } from "@/components/Inbox"; import type { InboxItem, TriageAction, DeferDuration } from "@/lib/types"; const mockNewItems: InboxItem[] = [ { id: "1", type: "mention", title: "You were mentioned in #312", triaged: false, createdAt: "2026-02-26T10:00:00Z", snippet: "@user can you look at this?", actor: "alice", }, { id: "2", type: "mr_feedback", title: "Comment on MR !847", triaged: false, createdAt: "2026-02-26T09:00:00Z", snippet: "This needs some refactoring", actor: "bob", }, ]; describe("Inbox", () => { beforeEach(() => { vi.clearAllMocks(); }); it("shows only untriaged items", () => { const items: InboxItem[] = [ ...mockNewItems, { id: "3", type: "mention", title: "Already triaged", triaged: true, createdAt: "2026-02-26T08:00:00Z", }, ]; render(); const inboxItems = screen.getAllByTestId("inbox-item"); expect(inboxItems).toHaveLength(2); }); it("shows inbox zero state when empty", () => { render(); expect(screen.getByText(/Inbox Zero/i)).toBeInTheDocument(); expect(screen.getByText(/All caught up/i)).toBeInTheDocument(); }); it("shows inbox zero when all items are triaged", () => { const items: InboxItem[] = [ { id: "1", type: "mention", title: "Triaged item", triaged: true, createdAt: "2026-02-26T10:00:00Z", }, ]; render(); expect(screen.getByText(/Inbox Zero/i)).toBeInTheDocument(); }); it("accept moves item to queue", async () => { const user = userEvent.setup(); const onTriage = vi.fn(); render(); const acceptButtons = screen.getAllByRole("button", { name: /accept/i }); await user.click(acceptButtons[0]); expect(onTriage).toHaveBeenCalledWith("1", "accept", undefined); }); it("defer shows duration picker", async () => { const user = userEvent.setup(); render(); const deferButtons = screen.getAllByRole("button", { name: /defer/i }); await user.click(deferButtons[0]); // Defer picker should show duration options expect(screen.getByText("1 hour")).toBeInTheDocument(); expect(screen.getByText("Tomorrow")).toBeInTheDocument(); }); it("defer with duration calls onTriage", async () => { const user = userEvent.setup(); const onTriage = vi.fn(); render(); const deferButtons = screen.getAllByRole("button", { name: /defer/i }); await user.click(deferButtons[0]); await user.click(screen.getByText("1 hour")); expect(onTriage).toHaveBeenCalledWith("1", "defer", "1h"); }); it("archive removes item from view", async () => { const user = userEvent.setup(); const onTriage = vi.fn(); render(); const archiveButtons = screen.getAllByRole("button", { name: /archive/i }); await user.click(archiveButtons[0]); expect(onTriage).toHaveBeenCalledWith("1", "archive", undefined); }); it("displays item metadata", () => { render(); expect(screen.getByText("You were mentioned in #312")).toBeInTheDocument(); expect(screen.getByText("@user can you look at this?")).toBeInTheDocument(); expect(screen.getByText("alice")).toBeInTheDocument(); }); it("displays item count in header", () => { render(); expect(screen.getByText(/Inbox \(2\)/)).toBeInTheDocument(); }); describe("keyboard shortcuts", () => { it("pressing 'a' on focused item triggers accept", async () => { const user = userEvent.setup(); const onTriage = vi.fn(); render(); // Focus the first inbox item const firstItem = screen.getAllByTestId("inbox-item")[0]; firstItem.focus(); await user.keyboard("a"); expect(onTriage).toHaveBeenCalledWith("1", "accept", undefined); }); it("pressing 'd' on focused item opens defer picker", async () => { const user = userEvent.setup(); render(); // Focus the first inbox item const firstItem = screen.getAllByTestId("inbox-item")[0]; firstItem.focus(); await user.keyboard("d"); expect(screen.getByText("1 hour")).toBeInTheDocument(); }); it("pressing 'x' on focused item triggers archive", async () => { const user = userEvent.setup(); const onTriage = vi.fn(); render(); // Focus the first inbox item const firstItem = screen.getAllByTestId("inbox-item")[0]; firstItem.focus(); await user.keyboard("x"); expect(onTriage).toHaveBeenCalledWith("1", "archive", undefined); }); }); });