52 lines
2.5 KiB
TypeScript
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();
|
|
});
|