import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { apiFetch } from "@/lib/apiFetch"; import { SystemAdminPanel } from "./SystemAdminPanel"; const openNotification = jest.fn(); jest.mock("@refinedev/core", () => ({ useNotification: () => ({ open: openNotification }), })); jest.mock("@config/config", () => ({ config: { BACKEND_URL: "https://server.example.com" }, })); jest.mock("@/lib/apiFetch", () => ({ apiFetch: jest.fn(), })); jest.mock("@/lib/sessionRecoveryDraft", () => ({ useSessionRecoveryDraft: jest.fn(), })); jest.mock("@/store/projectStore", () => ({ useProjectStore: (selector: (state: { currentProjectId: null }) => unknown) => selector({ currentProjectId: null }), })); const jsonResponse = (body: unknown) => ({ ok: true, status: 200, json: async () => body, text: async () => JSON.stringify(body), }) as Response; describe("SystemAdminPanel Keycloak synchronization", () => { beforeEach(() => { jest.clearAllMocks(); (apiFetch as jest.Mock).mockImplementation((input: string) => { if (input.endsWith("/api/v1/admin/users/me")) { return Promise.resolve( jsonResponse({ id: "admin-id", keycloak_id: "admin-keycloak-id", username: "admin", email: "admin@example.com", role: "admin", is_active: true, is_superuser: true, }), ); } if (input.endsWith("/api/v1/admin/keycloak-user-syncs")) { return Promise.resolve( jsonResponse({ scanned: 3, created: 1, updated: 1, skipped: 1, issues: [{ username: "no-email", reason: "missing_email" }], }), ); } return Promise.resolve(jsonResponse([])); }); }); it("syncs the Keycloak directory and shows the result", async () => { render(); fireEvent.click(await screen.findByRole("tab", { name: "系统用户" })); fireEvent.click( screen.getByRole("button", { name: "同步 Keycloak 用户" }), ); await waitFor(() => { expect(apiFetch).toHaveBeenCalledWith( "https://server.example.com/api/v1/admin/keycloak-user-syncs", expect.objectContaining({ method: "POST" }), ); }); expect(await screen.findByRole("alert")).toHaveTextContent( "已扫描 3 个 Keycloak 身份,新增 1 个,更新 1 个,跳过 1 个。", ); }); });