80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
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(
|
|
<ThemeProvider theme={theme}>
|
|
<SessionExpiryDialog />
|
|
</ThemeProvider>,
|
|
);
|
|
|
|
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(<SessionExpiryDialog />);
|
|
|
|
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(<SessionExpiryDialog />);
|
|
|
|
await act(async () => {
|
|
jest.advanceTimersByTime(2_000);
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: "重新认证" }));
|
|
|
|
expect(signIn).toHaveBeenCalledTimes(2);
|
|
});
|
|
});
|