import { act, renderHook } from "@testing-library/react"; import { afterEach, expect, it, vi } from "vitest"; import { useAgentConnection } from "./use-agent-connection"; afterEach(() => vi.useRealTimers()); it("rechecks an offline service, probes on focus and clears work on unmount", async () => { vi.useFakeTimers(); const getHealth = vi.fn().mockRejectedValueOnce(new Error("offline")).mockResolvedValue(undefined); const client = { getHealth }; const { result, unmount } = renderHook(() => useAgentConnection(client, "project-a")); await act(async () => {}); expect(result.current.connectionStatus).toBe("offline"); await act(async () => vi.advanceTimersByTimeAsync(1_000)); expect(result.current.connectionStatus).toBe("online"); expect(result.current.recoveryVersion).toBe(1); await act(async () => window.dispatchEvent(new Event("focus"))); expect(getHealth).toHaveBeenCalledTimes(3); unmount(); expect(vi.getTimerCount()).toBe(0); }); it("discards a late result from a previous client and scope", async () => { vi.useFakeTimers(); let finish!: () => void; let oldSignal!: AbortSignal; const oldClient = { getHealth: vi.fn((signal: AbortSignal) => { oldSignal = signal; return new Promise((resolve) => { finish = resolve; }); }) }; const nextClient = { getHealth: vi.fn(async () => { throw new Error("next service offline"); }) }; const { result, rerender, unmount } = renderHook(({ client, scope }) => useAgentConnection(client, scope), { initialProps: { client: oldClient, scope: "old" } }); await act(async () => {}); rerender({ client: nextClient, scope: "next" }); await act(async () => {}); expect(oldSignal.aborted).toBe(true); await act(async () => finish()); expect(result.current.connectionStatus).toBe("offline"); unmount(); }); it("aborts a stalled probe and recovers on the next retry", async () => { vi.useFakeTimers(); const getHealth = vi.fn().mockImplementationOnce((signal: AbortSignal) => new Promise((_resolve, reject) => { signal.addEventListener("abort", () => reject(new DOMException("timeout", "AbortError")), { once: true }); })).mockResolvedValue(undefined); const client = { getHealth }; const { result, unmount } = renderHook(() => useAgentConnection(client, "project")); await act(async () => vi.advanceTimersByTimeAsync(5_000)); expect(result.current.connectionStatus).toBe("offline"); await act(async () => vi.advanceTimersByTimeAsync(1_000)); expect(result.current.connectionStatus).toBe("online"); unmount(); });