// @vitest-environment jsdom import { act } from "react"; import type { ComponentProps } from "react"; import { createRoot } from "react-dom/client"; import type { Issue } from "@paperclipai/shared"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { FailedRunInboxRow, InboxIssueMetaLeading } from "./Inbox"; vi.mock("@/lib/router", () => ({ Link: ({ children, className, ...props }: ComponentProps<"a">) => ( {children} ), useLocation: () => ({ pathname: "/", search: "", hash: "" }), useNavigate: () => () => {}, })); // eslint-disable-next-line @typescript-eslint/no-explicit-any (globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; function createIssue(overrides: Partial = {}): Issue { return { id: "issue-1", identifier: "PAP-904", companyId: "company-1", projectId: null, projectWorkspaceId: null, goalId: null, parentId: null, title: "Inbox item", description: null, status: "todo", priority: "medium", assigneeAgentId: null, assigneeUserId: null, createdByAgentId: null, createdByUserId: null, issueNumber: 904, requestDepth: 0, billingCode: null, assigneeAdapterOverrides: null, executionWorkspaceId: null, executionWorkspacePreference: null, executionWorkspaceSettings: null, checkoutRunId: null, executionRunId: null, executionAgentNameKey: null, executionLockedAt: null, startedAt: null, completedAt: null, cancelledAt: null, hiddenAt: null, createdAt: new Date("2026-03-11T00:00:00.000Z"), updatedAt: new Date("2026-03-11T00:00:00.000Z"), labels: [], labelIds: [], myLastTouchAt: null, lastExternalCommentAt: null, isUnreadForMe: false, ...overrides, }; } describe("FailedRunInboxRow", () => { let container: HTMLDivElement; beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { container.remove(); }); it("suppresses accent hover styling when selected", () => { const root = createRoot(container); const run = { id: "run-1", companyId: "company-1", agentId: "agent-1", invocationSource: "assignment", triggerDetail: null, status: "failed", error: "boom", wakeupRequestId: null, exitCode: null, signal: null, usageJson: null, resultJson: null, sessionIdBefore: null, sessionIdAfter: null, logStore: null, logRef: null, logBytes: null, logSha256: null, logCompressed: false, errorCode: null, externalRunId: null, processPid: null, processStartedAt: null, retryOfRunId: null, processLossRetryCount: 0, stdoutExcerpt: null, stderrExcerpt: null, contextSnapshot: null, startedAt: new Date("2026-03-11T00:00:00.000Z"), finishedAt: null, createdAt: new Date("2026-03-11T00:00:00.000Z"), updatedAt: new Date("2026-03-11T00:00:00.000Z"), } as const; act(() => { root.render( {}} onRetry={() => {}} isRetrying={false} selected />, ); }); const link = container.querySelector("a"); expect(link).not.toBeNull(); expect(link?.className).toContain("hover:bg-transparent"); expect(link?.className).not.toContain("hover:bg-accent/50"); act(() => { root.unmount(); }); }); }); describe("InboxIssueMetaLeading", () => { let container: HTMLDivElement; beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { container.remove(); }); it("neutralizes selected status and live accents", () => { const root = createRoot(container); act(() => { root.render(); }); const statusIcon = container.querySelector('span[class*="border-muted-foreground"]'); const liveBadge = container.querySelector('span[class*="px-1.5"][class*="bg-muted"]'); const liveBadgeLabel = Array.from(container.querySelectorAll("span")).find( (node) => node.textContent === "Live" && node.className.includes("text-"), ); const liveDot = container.querySelector('span[class*="bg-muted-foreground/70"]'); const pulseRing = container.querySelector('span[class*="animate-pulse"]'); expect(statusIcon).not.toBeNull(); expect(statusIcon?.className).toContain("!border-muted-foreground"); expect(statusIcon?.className).toContain("!text-muted-foreground"); expect(liveBadge).not.toBeNull(); expect(liveBadge?.className).toContain("bg-muted"); expect(liveBadgeLabel).not.toBeNull(); expect(liveBadgeLabel?.className).toContain("text-muted-foreground"); expect(liveBadgeLabel?.className).not.toContain("text-blue-600"); expect(liveDot).not.toBeNull(); expect(pulseRing).toBeNull(); act(() => { root.unmount(); }); }); });