import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { RemoteCloudTooltip } from "./remote-cloud-tooltip"; const mocks = vi.hoisted(() => ({ getKubernetesTaskSession: vi.fn(), wsRequest: vi.fn(), touch: false, })); const STATUS_TRIGGER_ID = "remote-executor-status-trigger"; const EAGER_TASK_ID = "task-eager"; const EAGER_SESSION_ID = "session-eager"; vi.mock("@/lib/api/domains/kubernetes-api", () => ({ getKubernetesTaskSession: mocks.getKubernetesTaskSession, })); vi.mock("@/lib/ws/connection", () => ({ getWebSocketClient: () => ({ request: mocks.wsRequest }), })); beforeEach(() => { mocks.getKubernetesTaskSession.mockReset(); mocks.wsRequest.mockReset(); mocks.touch = false; }); afterEach(() => cleanup()); vi.mock("@kandev/ui/tooltip", () => ({ Tooltip: ({ children }: { children: React.ReactNode }) => <>{children}, TooltipTrigger: ({ children }: { children: React.ReactNode }) => <>{children}, TooltipContent: ({ children, ...props }: React.HTMLAttributes) => (
{children}
), })); vi.mock("@/hooks/use-compact-task-chrome", () => ({ useTouchDrawer: () => mocks.touch, })); vi.mock("@kandev/ui/drawer", () => ({ Drawer: ({ children }: { children: React.ReactNode }) => <>{children}, DrawerTrigger: ({ children }: { children: React.ReactNode }) => <>{children}, DrawerContent: ({ children, ...props }: React.HTMLAttributes) => (
{children}
), DrawerHeader: ({ children, ...props }: React.HTMLAttributes) => (
{children}
), DrawerTitle: ({ children, ...props }: React.HTMLAttributes) => (

{children}

), DrawerDescription: ({ children, ...props }: React.HTMLAttributes) => (

{children}

), DrawerClose: ({ children }: { children: React.ReactNode }) => <>{children}, })); function openTooltip() { fireEvent.pointerEnter(screen.getByTestId(STATUS_TRIGGER_ID), { pointerType: "mouse", }); } function reopenTooltip() { fireEvent.pointerLeave(screen.getByTestId(STATUS_TRIGGER_ID), { pointerType: "mouse", }); openTooltip(); } describe("RemoteCloudTooltip executor icon", () => { it("shows a container icon for Docker executors", () => { render( , ); expect(screen.getByTestId("executor-status-container-icon")).toBeTruthy(); expect(screen.queryByTestId("executor-status-cloud-icon")).toBeNull(); }); it("keeps the cloud icon for Sprites executors", () => { render( , ); expect(screen.getByTestId("executor-status-cloud-icon")).toBeTruthy(); }); it("uses a keyboard-focusable semantic status trigger", () => { render( , ); const trigger = screen.getByTestId(STATUS_TRIGGER_ID); expect(trigger.getAttribute("role")).toBe("img"); expect(trigger.getAttribute("tabindex")).toBe("0"); expect(trigger.getAttribute("aria-label")).toContain("Cluster executor"); }); }); describe("RemoteCloudTooltip relative timestamps", () => { it("renders created and last-check times as relative values", () => { const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(); const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString(); render( , ); expect(screen.getByTestId("remote-executor-status-created").textContent).toContain("2h ago"); expect(screen.getByTestId("remote-executor-status-checked").textContent).toContain("5m ago"); }); }); describe("RemoteCloudTooltip live status", () => { it("eagerly uses exact Kubernetes status and refetches after each reopen", async () => { mocks.getKubernetesTaskSession .mockResolvedValueOnce({ task_id: EAGER_TASK_ID, session_id: EAGER_SESSION_ID, pod_name: "pod-1", pod_phase: "Running", restarts: 0, failure_reason: "Unauthorized", }) .mockResolvedValueOnce({ task_id: EAGER_TASK_ID, session_id: EAGER_SESSION_ID, pod_name: "pod-1", pod_phase: "Running", restarts: 0, }) .mockResolvedValueOnce({ task_id: EAGER_TASK_ID, session_id: EAGER_SESSION_ID, pod_name: "pod-1", pod_phase: "Running", restarts: 0, }); render( , ); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledWith( "executor-eager", EAGER_TASK_ID, EAGER_SESSION_ID, ), ); expect((await screen.findByTestId("remote-executor-status-error")).textContent).toContain( "Unauthorized", ); expect(mocks.wsRequest).not.toHaveBeenCalled(); openTooltip(); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(2)); await waitFor(() => expect(screen.queryByTestId("remote-executor-status-error")).toBeNull()); expect(screen.getByTestId("remote-executor-status-state").textContent).toContain("Running"); reopenTooltip(); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(3)); }); it("keeps the newest exact Kubernetes response when scope changes", async () => { let resolveFirst: ((value: unknown) => void) | undefined; mocks.getKubernetesTaskSession .mockImplementationOnce( () => new Promise((resolve) => { resolveFirst = resolve; }), ) .mockResolvedValueOnce({ task_id: "task-new", session_id: "session-new", pod_name: "new-pod", pod_phase: "Running", restarts: 0, }); const { rerender } = render( , ); openTooltip(); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(1)); rerender( , ); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(2)); expect(await screen.findByText("new-pod")).toBeTruthy(); resolveFirst?.({ task_id: "task-1", session_id: "session-1", pod_name: "stale-pod", pod_phase: "Failed", restarts: 0, }); await waitFor(() => expect(screen.queryByText("stale-pod")).toBeNull()); expect(screen.getByText("new-pod")).toBeTruthy(); }); }); describe("RemoteCloudTooltip shared status presentation", () => { it("uses the pending tone for a waiting Kubernetes container", () => { render( , ); const row = screen.getByTestId("remote-executor-status-state"); expect(row.querySelector("dd")?.className).toContain("text-amber-600"); }); it("shares one eager request across duplicate exact-scope consumers", async () => { mocks.getKubernetesTaskSession.mockResolvedValue({ task_id: "task-duplicate", session_id: "session-duplicate", pod_name: "pod-1", pod_phase: "Running", restarts: 0, }); render( <> , ); await waitFor(() => expect(screen.getAllByText("pod-1")).toHaveLength(2)); expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(1); }); it("renders a structured Kubernetes task status summary", async () => { mocks.getKubernetesTaskSession.mockResolvedValue({ task_id: "task-structured", session_id: "session-structured", pod_name: "pod-structured", pod_phase: "Running", container_state: "running", restarts: 4, workspace_kind: "managed_pvc", created_at: "2026-09-01T09:00:00Z", }); render( , ); const summary = await screen.findByTestId("remote-executor-status-summary"); expect(summary.className).toContain("w-full"); expect(screen.getByTestId("remote-executor-status-identity").textContent).toBe( "pod-structured", ); expect(screen.getByTestId("remote-executor-status-state").textContent).toContain("running"); expect(screen.getByTestId("remote-executor-status-restarts").textContent).toContain("4"); expect(screen.getByTestId("remote-executor-status-workspace").textContent).toContain( "managed_pvc", ); }); }); describe("RemoteCloudTooltip compatibility status", () => { it("keeps WebSocket status for other remote executors", async () => { mocks.wsRequest.mockResolvedValue({ remote_name: "sprite-1", remote_state: "running", remote_checked_at: new Date().toISOString(), }); render( , ); openTooltip(); await waitFor(() => expect(mocks.wsRequest).toHaveBeenCalledTimes(1)); expect(mocks.getKubernetesTaskSession).not.toHaveBeenCalled(); reopenTooltip(); await waitFor(() => expect(mocks.wsRequest).toHaveBeenCalledTimes(2)); }); }); describe("RemoteCloudTooltip coarse-pointer disclosure", () => { it("opens the shared summary from a 44px task-safe Drawer trigger", () => { mocks.touch = true; const onParentClick = vi.fn(); render(
, ); const trigger = screen.getByTestId(STATUS_TRIGGER_ID); expect(trigger.getAttribute("role")).toBe("button"); expect(trigger.getAttribute("aria-haspopup")).toBe("dialog"); expect(trigger.className).toContain("after:size-11"); fireEvent.click(trigger); expect(onParentClick).not.toHaveBeenCalled(); expect(screen.getByTestId("remote-executor-status-drawer")).toBeTruthy(); expect(screen.getByTestId("remote-executor-status-workspace").textContent).toContain( "empty_dir", ); fireEvent.click(screen.getByRole("button", { name: "Close" })); expect(onParentClick).not.toHaveBeenCalled(); }); it("does not refresh repeatedly for auto-repeated activation keys", async () => { mocks.touch = true; mocks.getKubernetesTaskSession.mockResolvedValue({ task_id: "task-touch-repeat", session_id: "session-touch-repeat", pod_name: "pod-touch", pod_phase: "Running", restarts: 0, }); render( , ); await waitFor(() => expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(1)); const trigger = screen.getByTestId(STATUS_TRIGGER_ID); fireEvent.keyDown(trigger, { key: "Enter", repeat: true }); expect(mocks.getKubernetesTaskSession).toHaveBeenCalledTimes(1); }); });