hyapp-admin-platform/ops-center/src/OpsCenterEntry.test.jsx

101 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { act, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, expect, test, vi } from "vitest";
import { AuthProvider } from "@/app/auth/AuthProvider.jsx";
import * as authApi from "@/features/auth/api";
import { setAccessToken, setRefreshHandler, setUnauthorizedHandler } from "@/shared/api/request";
import { AuthenticatedOpsCenter } from "./OpsCenterEntry.jsx";
vi.mock("@/features/auth/api", () => ({
getMe: vi.fn(),
login: vi.fn(),
logout: vi.fn(),
refreshSession: vi.fn(),
}));
vi.mock("./OpsCenterApp.jsx", () => ({
OpsCenterApp: ({ can }) => (
<div data-can-credit={String(can("lucky-gift:pool-credit"))} data-testid="ops-center-app" />
),
}));
beforeEach(() => {
vi.clearAllMocks();
setAccessToken("");
setRefreshHandler(null);
setUnauthorizedHandler(null);
});
test("does not mount the dashboard without a session and redirects to login with the full ops path", async () => {
authApi.refreshSession.mockRejectedValue(new Error("no session"));
const targetWindow = fakeWindow("/ops-center/", "?view=configs", "#dynamic_v3");
render(
<AuthProvider>
<AuthenticatedOpsCenter targetWindow={targetWindow} />
</AuthProvider>,
);
// refresh 尚未结束以及确定无用户后的跳转窗口都只展示骨架Dashboard 不会发出任何业务请求。
expect(screen.queryByTestId("ops-center-app")).toBeNull();
await waitFor(() => {
expect(targetWindow.location.replace).toHaveBeenCalledWith(
"/login?redirect=%2Fops-center%2F%3Fview%3Dconfigs%23dynamic_v3",
);
});
expect(screen.queryByTestId("ops-center-app")).toBeNull();
});
test("waits for stale-token refresh fallback before mounting the dashboard", async () => {
const refresh = deferred();
const me = deferred();
setAccessToken("stale-token");
authApi.refreshSession.mockReturnValue(refresh.promise);
authApi.getMe.mockReturnValue(me.promise);
const targetWindow = fakeWindow("/ops-center/", "?view=overview", "");
render(
<AuthProvider>
<AuthenticatedOpsCenter targetWindow={targetWindow} />
</AuthProvider>,
);
expect(screen.queryByTestId("ops-center-app")).toBeNull();
await act(async () => {
refresh.reject(new Error("refresh cookie expired"));
});
await waitFor(() => expect(authApi.getMe).toHaveBeenCalledTimes(1));
expect(screen.queryByTestId("ops-center-app")).toBeNull();
await act(async () => {
me.resolve({
accessToken: "fresh-token",
permissions: ["lucky-gift:pool-credit"],
user: { id: 1, username: "ops" },
});
});
expect(await screen.findByTestId("ops-center-app")).toHaveAttribute("data-can-credit", "true");
expect(targetWindow.location.replace).not.toHaveBeenCalled();
});
function fakeWindow(pathname, search, hash) {
return {
location: {
hash,
pathname,
replace: vi.fn(),
search,
},
};
}
function deferred() {
let resolve;
let reject;
const promise = new Promise((resolvePromise, rejectPromise) => {
resolve = resolvePromise;
reject = rejectPromise;
});
return { promise, reject, resolve };
}