import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it } from "vitest"; import { HomePage } from "./HomePage"; import { MaintenancePage } from "./MaintenancePage"; import { PluginsPage } from "./PluginsPage"; import { ProfileSettingsPage } from "./ProfileSettingsPage"; import { ServerDetailPage } from "./ServerDetailPage"; import { ServersPage } from "./ServersPage"; import { UsersPage } from "./UsersPage"; import runtimeTaskProgressSource from "../components/RuntimeTaskProgress.tsx?raw"; import serverDeploymentWorkflowSource from "../components/ServerDeploymentWorkflow.tsx?raw"; import serverManagementTerminalSource from "../components/ServerManagementTerminalDrawer.tsx?raw"; import serverCreateSchemaSource from "../schemas/serverManagement.ts?raw"; import serversPageSource from "./ServersPage.tsx?raw"; import serverDetailPageSource from "./ServerDetailPage.tsx?raw"; import type { PageComponentProps } from "../contracts/page"; import { capabilitiesForRoles, type CurrentUserView } from "../contracts/workspace"; import type { OperationTracker } from "../stores/operations"; import type { UserResponse } from "../api/types"; const adminUser: CurrentUserView = { id: "user-admin", displayName: "Operator", status: "active", roles: ["platformAdmin"], capabilities: capabilitiesForRoles(["platformAdmin"]), profile: {}, source: "local" }; const noopOperations: OperationTracker = { operations: [], begin: () => "op-test", update: () => undefined, succeed: () => undefined, fail: () => undefined, isPending: () => false }; const reviewUser: UserResponse = { id: "user-reviewer", displayName: "Plugin Reviewer", email: "reviewer@example.test", status: "pending", roles: ["server-admin"], profile: { contactNote: "needs approval" }, createdAt: "2026-07-03T00:00:00Z", updatedAt: "2026-07-03T00:00:00Z" }; function pageProps(params: PageComponentProps["params"] = {}): PageComponentProps { return { session: adminUser, params, operations: noopOperations, onNavigate: () => undefined, onLogout: async () => undefined, onProfileSave: async () => adminUser, onThemePreferenceSave: async () => ({ userId: adminUser.id, paletteId: "mecha-black", backgroundPresetId: "mecha-grid", persistence: "api", updatedAt: "2026-07-03T00:00:00Z" }) }; } describe("first-party console pages", () => { it("renders the platform overview with first-screen health modules", () => { const html = renderToStaticMarkup(); expect(html).toContain("平台概览"); expect(html).toContain("资源负载"); expect(html).toContain("游戏类型分布"); expect(html).toContain("最近运营信号"); expect(html).not.toContain("任务脉冲"); expect(html).not.toContain("sk-"); }); it("keeps unavailable overview modules visible instead of claiming an empty healthy state", () => { const html = renderToStaticMarkup( ); expect(html).toContain("3 个模块不可用"); expect(html).toContain("资源指标不可用"); expect(html).toContain("AI 提供商信号不可用"); expect(html).toContain("server.lifecycle.start"); expect(html).not.toContain("暂无异常信号"); }); it("explains read-only overview access when the session cannot create servers", () => { const readOnlySession: CurrentUserView = { ...adminUser, roles: ["serverAdmin"], capabilities: ["platform.overview.read", "servers.read"] }; const html = renderToStaticMarkup( ); expect(html).toContain("没有创建服务器的权限"); expect(html).toContain("前往服务器管理"); }); it("renders the server list workspace with search and status filters", () => { const html = renderToStaticMarkup(); expect(html).toContain("服务器管理"); expect(html).toContain("搜索服务器"); expect(html).toContain("autoComplete=\"off\""); expect(html).toContain("data-1p-ignore=\"true\""); expect(html).toContain("data-lpignore=\"true\""); expect(html).toContain("在线"); expect(html).toContain("离线"); expect(html).not.toContain("run socket"); expect(html).not.toContain("/Users/"); }); it("keeps server metrics unavailable and runtime commands permission-gated", () => { expect(serversPageSource).toContain("metricsUnavailable"); expect(serversPageSource).toContain("指标不可用"); expect(serversPageSource).toContain("canManageServers"); expect(serversPageSource).toContain("当前账号没有运行操作权限"); expect(serversPageSource).toContain("failedJobs"); expect(serversPageSource).toContain("refreshMetrics"); expect(serversPageSource).toContain("onClick={() => void refreshMetrics()}"); }); it("exposes run key reset from the compact server list danger menu", () => { expect(serversPageSource).toContain("reset-run-key"); expect(serversPageSource).toContain("重置 run 密钥"); expect(serversPageSource).toContain("runtimeKeyResetStages"); expect(serversPageSource).toContain("platformApiClient.resetRunKey"); expect(serversPageSource).toContain("旧 run 会话已失效"); }); it("keeps deployment startup inputs in the create wizard without exposing protected values", () => { expect(serversPageSource).toContain(" { expect(serversPageSource).not.toContain("ServerLiveLogDrawer"); expect(serversPageSource).not.toContain("ServerManagementTerminalDrawer"); expect(serversPageSource).not.toContain("live-logs"); expect(serversPageSource).not.toContain("historical-logs"); expect(serversPageSource).not.toContain("requestLogBackfill"); expect(serversPageSource).not.toContain("管理终端"); expect(serverDetailPageSource).toContain("ServerManagementTerminalDrawer"); expect(serverDetailPageSource).not.toContain("SourceRCONCommandPanel"); expect(serverDetailPageSource).not.toContain("ServerLiveLogDrawer"); expect(serverDetailPageSource).not.toContain('实时日志'); expect(serverDetailPageSource).not.toContain("previewServerConfigDiff"); expect(serverDetailPageSource).not.toContain("approveServerConfigWrite"); expect(serverDetailPageSource).not.toContain("操作历史"); expect(serverDetailPageSource).toContain("打开终端"); expect(serverManagementTerminalSource).toContain("openServerLogEvents"); expect(serverManagementTerminalSource).toContain("dispatchSourceRCONCommand"); expect(serverManagementTerminalSource).toContain("terminalQuickCommandCatalog"); expect(serverManagementTerminalSource).not.toContain("password"); expect(serverManagementTerminalSource).not.toContain("direct socket"); expect(serverDetailPageSource).toContain("runtimeObservationFreshness"); expect(serverDetailPageSource).toContain("Run 未验证"); expect(serverDetailPageSource).toContain("PluginPageSection"); expect(serverDetailPageSource).toContain("AI 配置助手"); }); it("keeps create target and profile controls out while preserving deployment steps", () => { expect(serverDeploymentWorkflowSource).not.toContain('name="deploymentTargetId"'); expect(serverDeploymentWorkflowSource).not.toContain("请选择部署目标"); expect(serverDeploymentWorkflowSource).not.toContain("saveAsDraft"); expect(serverDeploymentWorkflowSource).not.toContain("暂不指定部署目标"); expect(serverDeploymentWorkflowSource).toContain('if (step === pluginStep) return Boolean(form.pluginId) && Boolean(form.name.trim());'); expect(serverDeploymentWorkflowSource).toContain("await onSubmit(form)"); expect(serverDeploymentWorkflowSource).not.toContain('kind === "create" &&