import { createTheme, ThemeProvider } from "@mui/material/styles";
import { act, fireEvent, render, screen } from "@testing-library/react";
import { signIn } from "next-auth/react";
import { useAuthStore } from "@/store/authStore";
import { SessionExpiryDialog } from "./SessionExpiryDialog";
jest.mock("next-auth/react", () => ({
signIn: jest.fn(),
}));
describe("SessionExpiryDialog", () => {
beforeEach(() => {
jest.useFakeTimers();
jest.mocked(signIn).mockReset().mockResolvedValue(undefined);
useAuthStore.setState({
accessToken: null,
sessionExpired: true,
sessionExpiryReason: "unauthorized",
});
});
afterEach(() => {
act(() => useAuthStore.getState().clearSessionExpired());
jest.useRealTimers();
});
it("renders above every regular application overlay", () => {
const theme = createTheme();
render(
,
);
const dialogRoot = screen.getByRole("dialog").closest(".MuiModal-root");
expect(dialogRoot).not.toBeNull();
expect(dialogRoot).toHaveStyle({
zIndex: theme.zIndex.tooltip + 1,
});
});
it("shows the expired state before automatically starting login", () => {
window.history.replaceState({}, "", "/network-simulation?tab=history");
render();
expect(screen.getByText("登录已过期")).toBeInTheDocument();
expect(screen.getByText("即将自动跳转到登录页面。"))
.toBeInTheDocument();
expect(signIn).not.toHaveBeenCalled();
act(() => {
jest.advanceTimersByTime(2_000);
});
expect(signIn).toHaveBeenCalledTimes(1);
expect(signIn).toHaveBeenCalledWith("keycloak", {
callbackUrl: "/network-simulation?tab=history",
redirect: true,
});
});
it("allows a retry when starting automatic login fails", async () => {
jest.mocked(signIn)
.mockRejectedValueOnce(new Error("network unavailable"))
.mockResolvedValueOnce(undefined);
render();
await act(async () => {
jest.advanceTimersByTime(2_000);
});
fireEvent.click(screen.getByRole("button", { name: "重新认证" }));
expect(signIn).toHaveBeenCalledTimes(2);
});
});