import { afterEach, describe, expect, it, vi } from "vitest"; import { act, renderHook, waitFor } from "@testing-library/react"; import { useGameProfile } from "@/hooks/use-game-profile"; import { profileFixture } from "@/test/fixtures"; afterEach(() => { vi.unstubAllGlobals(); vi.restoreAllMocks(); }); describe("useGameProfile", () => { it("loads a profile and derives view state", async () => { vi.stubGlobal( "fetch", vi.fn(async () => ({ ok: true, json: async () => profileFixture() }) as Response), ); const { result } = renderHook(() => useGameProfile("1", "en", 0)); await waitFor(() => expect(result.current.profile?.name).toBe("Test Game")); expect(result.current.failed).toBe(false); expect(result.current.localeTag).toBe("en-US"); expect(result.current.hasDetails).toBe(true); }); it("flags failure when the API errors", async () => { vi.stubGlobal( "fetch", vi.fn(async () => ({ ok: false, status: 500 }) as Response), ); const { result } = renderHook(() => useGameProfile("1", "en", 0)); await waitFor(() => expect(result.current.failed).toBe(true)); expect(result.current.profile).toBeNull(); }); it("retries on demand", async () => { let calls = 0; vi.stubGlobal( "fetch", vi.fn(async () => { calls += 1; return { ok: false, status: 500 } as Response; }), ); const { result } = renderHook(() => useGameProfile("1", "en", 0)); await waitFor(() => expect(result.current.failed).toBe(true)); expect(result.current.canRetry).toBe(true); result.current.retry(); await waitFor(() => expect(calls).toBeGreaterThan(1)); }); it("blocks double retry during cooldown and restores on reset", async () => { let calls = 0; vi.stubGlobal( "fetch", vi.fn(async () => { calls += 1; return { ok: false, status: 500 } as Response; }), ); const { result } = renderHook(() => useGameProfile("1", "en", 0)); await waitFor(() => expect(result.current.failed).toBe(true)); act(() => { result.current.retry(); }); expect(result.current.canRetry).toBe(false); const afterFirstRetry = calls; act(() => { result.current.retry(); }); expect(calls).toBe(afterFirstRetry); act(() => { result.current.reset(); }); expect(result.current.canRetry).toBe(true); }); });