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 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("sk-");
});
it("keeps unavailable overview modules visible instead of claiming an empty healthy state", () => {
const html = renderToStaticMarkup(
);
expect(html).toContain("4 个模块不可用");
expect(html).toContain("资源指标不可用");
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("在线");
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("submits declared runtime profiles and logical bindings from the create workflow", () => {
expect(serversPageSource).toContain(" {
expect(serversPageSource).toContain('aria-haspopup="menu"');
expect(serversPageSource).toContain("createPortal");
expect(serversPageSource).toContain("runtime-action-popover");
expect(serversPageSource).not.toContain("runtime-action-menu");
expect(serversPageSource).not.toContain(" {
const deleteHandlerSource = serversPageSource.split("async function handleDeleteServer")[1]?.split("function openRunTargetSelection")[0] ?? "";
expect(serversPageSource).toContain("deleteServerInstance(deleteConfirmation.serverInstanceId, { password: deletePassword })");
expect(serversPageSource).toContain("serverDeleteConfirmation(card.instance)");
expect(serversPageSource).toContain("serverDeleteDisabledReason(session, card.instance)");
expect(serversPageSource).toContain("危险操作");
expect(serversPageSource).toContain("删除服务器");
expect(serversPageSource).toContain("请输入当前登录密码");
expect(serversPageSource).toContain("canOpenActions");
expect(deleteHandlerSource).toContain("await refresh();");
expect(deleteHandlerSource).not.toContain("onNavigate");
expect(serverDetailPageSource).not.toContain("deleteServerInstance");
expect(serverDetailPageSource).not.toContain("serverDeleteConfirmation");
});
it("surfaces runtime actions through progress dialogs with build stages", () => {
const generateRunSource = serversPageSource.split("async function generateRunForTarget")[1]?.split("async function handleQuickRuntimeAction")[0] ?? "";
expect(serversPageSource).toContain("RuntimeTaskProgressDialog");
expect(serversPageSource).toContain("选择生成平台");
expect(serversPageSource).toContain("runTargetSelection");
expect(serversPageSource).toContain("runtimeRunBuildStages");
expect(serversPageSource).toContain("requireQuickRuntimeActionAvailable(instance.id, action)");
expect(serversPageSource).toContain("该操作不可用");
expect(generateRunSource.indexOf("runtimeTask.runTrackedTask")).toBeLessThan(generateRunSource.indexOf('await requireQuickRuntimeActionAvailable(instance.id, "generate-run")'));
expect(serverDetailPageSource).toContain("RuntimeTaskProgressDialog");
expect(serverDetailPageSource).toContain("runtimeRunBuildStages");
expect(runtimeTaskProgressSource).toContain("runtimeBuildStages");
expect(runtimeTaskProgressSource).toContain("runtimeRunBuildStages");
expect(runtimeTaskProgressSource).toContain("进度展示");
expect(runtimeTaskProgressSource).toContain("activeStepLabel");
expect(runtimeTaskProgressSource).toContain("平台正在执行当前阶段");
expect(runtimeTaskProgressSource).toContain("拉取 run 更新");
expect(runtimeTaskProgressSource).toContain("检测构建环境");
expect(runtimeTaskProgressSource).toContain("构建中");
expect(runtimeTaskProgressSource).toContain("构建完成");
expect(runtimeTaskProgressSource).toContain("拉取代码");
expect(runtimeTaskProgressSource).toContain("安装环境");
expect(runtimeTaskProgressSource).toContain("编译构建");
expect(runtimeTaskProgressSource).toContain("打包成功");
expect(runtimeTaskProgressSource).toContain("构建成功");
});
it("renders server detail sections for daily operations", () => {
const html = renderToStaticMarkup();
expect(html).toContain("返回列表");
expect(html).toContain("概览");
expect(html).toContain("日志");
expect(html).toContain("配置");
expect(html).toContain("插件控制");
expect(html).toContain("AI 助手");
expect(html).toContain("操作历史");
});
it("renders plugin catalog bridge readiness", () => {
const html = renderToStaticMarkup();
expect(html).toContain("插件市场");
expect(html).toContain("平台 API");
expect(html).toContain("正在加载插件市场");
expect(html).not.toContain("billing");
});
it("renders user access review context", () => {
const html = renderToStaticMarkup();
expect(html).toContain("用户管理");
expect(html).toContain("Plugin Reviewer");
expect(html).toContain("needs approval");
expect(html).toContain("本地开发样例 / 仅查看");
});
it("renders maintenance triage entry points", () => {
const html = renderToStaticMarkup();
expect(html).toContain("系统维护");
expect(html).toContain("维护排障入口");
expect(html).toContain("节点详情");
expect(html).toContain("最近失败任务");
expect(html).toContain("审计异常");
});
it("renders profile settings as a full page", () => {
const html = renderToStaticMarkup();
expect(html).toContain("个人设置");
expect(html).toContain("个人资料");
expect(html).toContain("界面偏好");
expect(html).not.toContain("role=\"dialog\"");
});
it("keeps profile background controls focused on custom uploads", () => {
const originalWindow = globalThis.window;
Object.defineProperty(globalThis, "window", {
configurable: true,
value: {
localStorage: {
getItem: (key: string) => {
if (key === "platform-web.theme.palette") {
return "magical-girl";
}
if (key === "platform-web.theme.backgroundPreset") {
return "mecha-grid";
}
if (key === "platform-web.theme.background") {
return "data:image/png;base64,custom";
}
return null;
}
}
}
});
try {
const html = renderToStaticMarkup();
expect(html).toContain("自定义背景");
expect(html).toContain("上传背景");
expect(html).toContain("移除背景");
expect(html).toContain("当前显示自定义上传背景;移除后回到主题配色背景。");
expect(html).not.toContain("机甲格纳库");
expect(html).not.toContain("粉月魔法阵");
expect(html).not.toContain("备用");
} finally {
Object.defineProperty(globalThis, "window", {
configurable: true,
value: originalWindow
});
}
});
});