import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { type ReactNode } from "react";
import { beforeEach, describe, expect, it, vi } from "vitest";
const authState = vi.hoisted(() => ({ hasToken: false }));
const clients = vi.hoisted(() => ({
getCurrentUser: vi.fn(),
listUserSettings: vi.fn(),
}));
vi.mock("@/auth-state", () => ({
clearAccessToken: vi.fn(),
getAccessToken: () => (authState.hasToken ? "token" : undefined),
}));
vi.mock("@/connect", () => ({
authServiceClient: {
getCurrentUser: clients.getCurrentUser,
signOut: vi.fn(),
},
refreshAccessToken: vi.fn(async () => undefined),
userServiceClient: {
listUserSettings: clients.listUserSettings,
},
}));
import { AuthProvider, useAuth } from "@/contexts/AuthContext";
const Probe = () => {
const { currentUser, initialize, isInitialized, isUserSettingsInitialized } = useAuth();
return (
{isInitialized ? "yes" : "no"}
{isUserSettingsInitialized ? "yes" : "no"}
{currentUser?.name ?? "none"}
);
};
const wrapper = ({ children }: { children: ReactNode }) => (
{children}
);
describe("AuthProvider initialization", () => {
beforeEach(() => {
authState.hasToken = false;
clients.getCurrentUser.mockReset();
clients.listUserSettings.mockReset();
});
it("resets full readiness while post-sign-in settings are pending", async () => {
let resolveSettings!: (value: { settings: [] }) => void;
clients.getCurrentUser.mockResolvedValue({ user: { name: "users/alice", username: "alice" } });
clients.listUserSettings.mockImplementation(
() => new Promise<{ settings: [] }>((resolve) => (resolveSettings = resolve)),
);
render(, { wrapper });
// Settle the initial unauthenticated pass; this reproduces the state from
// which PasswordSignInForm and AuthCallback invoke initialize again.
fireEvent.click(screen.getByRole("button", { name: "initialize" }));
await waitFor(() => expect(screen.getByTestId("initialized")).toHaveTextContent("yes"));
authState.hasToken = true;
fireEvent.click(screen.getByRole("button", { name: "initialize" }));
await waitFor(() => expect(screen.getByTestId("user")).toHaveTextContent("users/alice"));
expect(screen.getByTestId("initialized")).toHaveTextContent("no");
expect(screen.getByTestId("user-settings-initialized")).toHaveTextContent("no");
resolveSettings({ settings: [] });
await waitFor(() => expect(screen.getByTestId("user-settings-initialized")).toHaveTextContent("yes"));
expect(screen.getByTestId("initialized")).toHaveTextContent("yes");
});
});