Files
next-tjwater-frontend/src/features/agent/hooks/use-agent-connection.test.tsx
T

52 lines
2.5 KiB
TypeScript

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<void>((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<void>((_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();
});