import { render, screen } from "@testing-library/react"; import { afterEach, beforeEach, expect, test, vi } from "vitest"; import { MemoryRouter } from "react-router-dom"; import App from "@/app/App.jsx"; import { AppProviders } from "@/app/providers.jsx"; import { adminRoutes } from "@/app/router/routeConfig"; import { setAccessToken } from "@/shared/api/request"; beforeEach(() => { window.localStorage.clear(); vi.stubGlobal( "fetch", vi.fn(async () => new Response(JSON.stringify({ code: 401, message: "unauthorized" }), { status: 401 })) ); }); afterEach(() => { vi.unstubAllGlobals(); }); test("renders login route", async () => { renderWithRoute("/login"); expect(await screen.findByText("HYApp 管理平台")).toBeInTheDocument(); }); test("redirects protected route to login when unauthenticated", async () => { renderWithRoute("/system/users"); expect(await screen.findByText("HYApp 管理平台")).toBeInTheDocument(); }); test("renders resource list route with an authenticated session", async () => { setAccessToken("test-token"); vi.mocked(fetch).mockImplementation(async (input) => { const url = String(input); if (url.includes("/v1/auth/refresh") || url.includes("/v1/auth/me")) { return jsonResponse({ accessToken: "test-token", permissions: ["resource:view"], user: { userId: 1, username: "admin" }, }); } if (url.includes("/v1/admin/apps")) { return jsonResponse({ items: [{ appCode: "lalu", name: "Lalu" }], total: 1 }); } if (url.includes("/v1/admin/navigation/menus")) { return jsonResponse([]); } if (url.includes("/v1/admin/resources")) { return jsonResponse({ items: [], page: 1, pageSize: 50, total: 0 }); } return jsonResponse(null); }); renderWithRoute("/resources"); expect(await screen.findByText("资源")).toBeInTheDocument(); }); test("renders cp config route with an authenticated session", async () => { setAccessToken("test-token"); vi.mocked(fetch).mockImplementation(async (input) => { const url = String(input); if (url.includes("/v1/auth/refresh") || url.includes("/v1/auth/me")) { return jsonResponse({ accessToken: "test-token", permissions: ["cp-config:view"], user: { userId: 1, username: "admin" }, }); } if (url.includes("/v1/admin/apps")) { return jsonResponse({ items: [{ appCode: "lalu", name: "Lalu" }], total: 1 }); } if (url.includes("/v1/admin/navigation/menus")) { return jsonResponse([]); } if (url.includes("/v1/admin/activity/cp/config")) { return jsonResponse({ appCode: "lalu", relations: [ cpRelationFixture("cp", "CP", 1), cpRelationFixture("brother", "兄弟", 5), cpRelationFixture("sister", "姐妹", 5), ], }); } return jsonResponse(null); }); renderWithRoute("/activities/cp-config"); expect((await screen.findAllByText("CP配置")).length).toBeGreaterThan(0); expect(await screen.findByText("兄弟上限")).toBeInTheDocument(); }); test("admin routes declare menu code and permission", () => { expect(adminRoutes.length).toBeGreaterThan(0); expect(adminRoutes.every((route) => route.menuCode && route.permission)).toBe(true); }); function renderWithRoute(route) { return render( ); } function jsonResponse(data) { return new Response(JSON.stringify({ code: 0, data }), { status: 200 }); } function cpRelationFixture(relationType, displayName, maxCountPerUser) { return { relationType, displayName, maxCountPerUser, applicationExpireHours: 24, status: "active", levels: Array.from({ length: 5 }, (_, index) => ({ level: index + 1, intimacyThreshold: index * 10000, rewardResourceGroupId: 0, levelIconUrl: "", status: "active", })), }; }