import { describe, expect, it, vi, beforeEach } from "vitest"; import { renderHook, waitFor } from "@testing-library/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import React from "react"; import { useGitUser } from "#/hooks/query/use-git-user"; import { useLogout } from "#/hooks/mutation/use-logout"; import UserService from "#/api/user-service/user-service.api"; import * as useShouldShowGitFeaturesModule from "#/hooks/use-should-show-git-features"; import * as useConfigModule from "#/hooks/query/use-config"; import { AxiosError } from "axios"; vi.mock("#/hooks/use-should-show-git-features"); vi.mock("#/hooks/query/use-config"); vi.mock("#/hooks/mutation/use-logout"); vi.mock("#/api/user-service/user-service.api"); vi.mock("posthog-js/react", () => ({ usePostHog: vi.fn(() => ({ identify: vi.fn(), })), })); describe("useGitUser", () => { let mockLogout: ReturnType; beforeEach(() => { vi.clearAllMocks(); mockLogout = { mutate: vi.fn(), mutateAsync: vi.fn(), data: undefined, error: null, isPending: false, isSuccess: false, isError: false, isIdle: true, reset: vi.fn(), status: "idle", } as unknown as ReturnType; vi.mocked(useShouldShowGitFeaturesModule.useShouldShowGitFeatures).mockReturnValue(true); vi.mocked(useConfigModule.useConfig).mockReturnValue({ data: { app_mode: "saas" }, isLoading: false, error: null, } as any); vi.mocked(useLogout).mockReturnValue(mockLogout); }); const createWrapper = () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); return ({ children }: { children: React.ReactNode }) => ( {children} ); }; it("should call logout when receiving a 401 error", async () => { // Mock the user service to throw a 401 error const mockError = new AxiosError("Unauthorized", "401", undefined, undefined, { status: 401, data: { message: "Unauthorized" }, } as any); vi.mocked(UserService.getUser).mockRejectedValue(mockError); const { result } = renderHook(() => useGitUser(), { wrapper: createWrapper(), }); // Wait for the query to fail (status becomes 'error') await waitFor(() => { expect(result.current.status).toBe("error"); }); // Wait for the useEffect to trigger logout await waitFor(() => { expect(mockLogout.mutate).toHaveBeenCalled(); }); }); it("should not call logout for non-401 errors", async () => { // Mock the user service to throw a 500 error const mockError = new AxiosError("Server Error", "500", undefined, undefined, { status: 500, data: { message: "Internal Server Error" }, } as any); vi.mocked(UserService.getUser).mockRejectedValue(mockError); const { result } = renderHook(() => useGitUser(), { wrapper: createWrapper(), }); // Wait for the query to fail (status becomes 'error') await waitFor(() => { expect(result.current.status).toBe("error"); }); // Wait a bit to ensure logout is not called await waitFor(() => { expect(mockLogout.mutate).not.toHaveBeenCalled(); }); }); });