Remove manual runtime controls from server detail
This commit is contained in:
@@ -199,9 +199,9 @@ describe("first-party console pages", () => {
|
||||
expect(serverDeploymentWorkflowSource).toContain("当前平台尚未提供 SCUM 服务端的受控升级任务");
|
||||
expect(serverDeploymentWorkflowSource).toContain("已绑定服务器编辑时会直接进入相关配置");
|
||||
expect(serverDeploymentWorkflowSource).toContain("可在此调整部署方式;不会重复要求选择已绑定的运行节点");
|
||||
expect(serversPageSource).toContain('onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" })');
|
||||
expect(serverDetailPageSource).toContain("运行配置绑定");
|
||||
expect(serverDetailPageSource).toContain('type={field.sensitive ? "password" : "text"}');
|
||||
expect(serversPageSource).toContain('onNavigate("serverDetail", { serverId: result.instance.id })');
|
||||
expect(serverDetailPageSource).not.toContain("运行配置绑定");
|
||||
expect(serverDetailPageSource).not.toContain('type={field.sensitive ? "password" : "text"}');
|
||||
expect(serverDeploymentWorkflowSource).toContain("显示已保存配置");
|
||||
expect(serverDeploymentWorkflowSource).toContain("revealSavedInputs");
|
||||
expect(serversPageSource).toContain("revealServerDeployment");
|
||||
@@ -286,8 +286,8 @@ describe("first-party console pages", () => {
|
||||
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(serverDetailPageSource).not.toContain("RuntimeTaskProgressDialog");
|
||||
expect(serverDetailPageSource).not.toContain("runtimeRunBuildStages");
|
||||
expect(runtimeTaskProgressSource).toContain("runtimeBuildStages");
|
||||
expect(runtimeTaskProgressSource).toContain("runtimeRunBuildStages");
|
||||
expect(runtimeTaskProgressSource).toContain("进度展示");
|
||||
@@ -311,9 +311,9 @@ describe("first-party console pages", () => {
|
||||
expect(html).not.toContain("概览");
|
||||
expect(html).toContain("日志");
|
||||
expect(html).toContain("管理终端");
|
||||
expect(html).toContain("运行操作");
|
||||
expect(html).toContain("配置");
|
||||
expect(html).toContain("插件控制");
|
||||
expect(html).not.toContain("运行操作");
|
||||
expect(html).not.toContain("插件控制");
|
||||
expect(html).toContain("AI 助手");
|
||||
expect(html).toContain("操作历史");
|
||||
});
|
||||
@@ -353,7 +353,6 @@ describe("first-party console pages", () => {
|
||||
|
||||
it("uses declared SCUM log source keys for log backfill defaults", () => {
|
||||
expect(serversPageSource).toContain("scum-server-events");
|
||||
expect(serverDetailPageSource).toContain("scum-server-events");
|
||||
expect(serversPageSource).not.toContain("server-log");
|
||||
expect(serverDetailPageSource).not.toContain("server-log");
|
||||
});
|
||||
|
||||
@@ -2,8 +2,6 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import { configDiffViewFromPreview } from "./ServerDetailPage";
|
||||
import serverDetailPageSource from "./ServerDetailPage.tsx?raw";
|
||||
import clientManagerLifecyclePanelSource from "../components/ClientManagerLifecyclePanel.tsx?raw";
|
||||
import runtimeDLLExtensionsPanelSource from "../components/RuntimeDLLExtensionsPanel.tsx?raw";
|
||||
import sourceRCONCommandPanelSource from "../components/SourceRCONCommandPanel.tsx?raw";
|
||||
import artifactTransferSource from "../utils/artifactTransfer.ts?raw";
|
||||
import type { ServerConfigDiffPreviewResponse } from "../api/types";
|
||||
@@ -67,39 +65,21 @@ describe("ServerDetailPage config write approval", () => {
|
||||
it("uses platform-mediated artifact download and bridge references without backend internals", () => {
|
||||
expect(serverDetailPageSource).toContain("openArtifactDownload");
|
||||
expect(serverDetailPageSource).toContain("readArtifactContent");
|
||||
expect(serverDetailPageSource).toContain("parsePluginArtifactReference");
|
||||
expect(serverDetailPageSource).toContain("浏览器制品传输");
|
||||
expect(serverDetailPageSource).not.toContain("storage://");
|
||||
expect(serverDetailPageSource).not.toContain("unix://");
|
||||
expect(serverDetailPageSource).not.toContain("Bearer ");
|
||||
});
|
||||
|
||||
it("surfaces run distribution and client-manager workflows through platform-mediated APIs", () => {
|
||||
expect(serverDetailPageSource).toContain('params.routeKey !== "run-builder"');
|
||||
expect(serverDetailPageSource).toContain('id="run-builder"');
|
||||
expect(serverDetailPageSource).toContain("scrollIntoView");
|
||||
expect(serverDetailPageSource).toContain("getServerRuntimeActions");
|
||||
expect(serverDetailPageSource).toContain("generateRunDistribution");
|
||||
expect(serverDetailPageSource).toContain("downloadLatestRunDistribution");
|
||||
expect(serverDetailPageSource).toContain("pushRunUpdate");
|
||||
expect(serverDetailPageSource).toContain("generateClientManager");
|
||||
expect(serverDetailPageSource).toContain("resetClientManagerKey");
|
||||
expect(serverDetailPageSource).toContain("checkDependencies");
|
||||
expect(serverDetailPageSource).toContain("installDependencies");
|
||||
it("keeps run distribution and client-manager workflows out of server detail tabs", () => {
|
||||
expect(serverDetailPageSource).not.toContain('id="run-builder"');
|
||||
expect(serverDetailPageSource).not.toContain("getServerRuntimeActions");
|
||||
expect(serverDetailPageSource).not.toContain("generateRunDistribution");
|
||||
expect(serverDetailPageSource).not.toContain("downloadLatestRunDistribution");
|
||||
expect(serverDetailPageSource).not.toContain("pushRunUpdate");
|
||||
expect(serverDetailPageSource).not.toContain("generateClientManager");
|
||||
expect(serverDetailPageSource).not.toContain("ClientManagerLifecyclePanel");
|
||||
expect(serverDetailPageSource).toContain("openServerLogEvents");
|
||||
expect(serverDetailPageSource).toContain("requestLogBackfill");
|
||||
expect(serverDetailPageSource).toContain("ClientManagerLifecyclePanel");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("listClientManagerLifecycles");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("deployClientManager");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("controlClientManager");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("updateClientManager");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("retryClientManagerLifecycle");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("revokeClientManagerSession");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("uninstallClientManager");
|
||||
expect(clientManagerLifecyclePanelSource).toContain("expectedDeploymentGeneration");
|
||||
expect(clientManagerLifecyclePanelSource).not.toContain("secretRef");
|
||||
expect(clientManagerLifecyclePanelSource).not.toContain("hostPath");
|
||||
expect(clientManagerLifecyclePanelSource).not.toContain("process.pid");
|
||||
expect(serverDetailPageSource).not.toContain("authKey");
|
||||
expect(serverDetailPageSource).not.toContain("password=");
|
||||
expect(serverDetailPageSource).not.toContain("unix://");
|
||||
@@ -108,15 +88,11 @@ describe("ServerDetailPage config write approval", () => {
|
||||
expect(serverDetailPageSource).not.toContain("sqlite://");
|
||||
});
|
||||
|
||||
it("renders declared UE4SS DLL update policy without local paths or RCON secrets", () => {
|
||||
expect(serverDetailPageSource).toContain("RuntimeDLLExtensionsPanel");
|
||||
expect(runtimeDLLExtensionsPanelSource).toContain("启动前自动校验和更新");
|
||||
expect(runtimeDLLExtensionsPanelSource).toContain("运行:SCUM 服务器受监管启动");
|
||||
expect(runtimeDLLExtensionsPanelSource).toContain("由 UE4SS 正常加载");
|
||||
expect(runtimeDLLExtensionsPanelSource).toContain("Linux 启动前拒绝");
|
||||
for (const forbidden of ["dllRef", "targetKey", "rconPort", "password="]) {
|
||||
expect(runtimeDLLExtensionsPanelSource).not.toContain(forbidden);
|
||||
}
|
||||
it("does not expose manual runtime configuration surfaces", () => {
|
||||
expect(serverDetailPageSource).not.toContain("getServerRuntimeBinding");
|
||||
expect(serverDetailPageSource).not.toContain("updateServerRuntimeBinding");
|
||||
expect(serverDetailPageSource).not.toContain("运行配置绑定");
|
||||
expect(serverDetailPageSource).not.toContain("RuntimeDLLExtensionsPanel");
|
||||
});
|
||||
|
||||
it("adds SCUM announcements and raw commands through protected RCON bridge jobs", () => {
|
||||
@@ -132,33 +108,15 @@ describe("ServerDetailPage config write approval", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("loads the dependency catalog only after runtime actions expose dependency operations", () => {
|
||||
const runtimeDistributionSectionSource = serverDetailPageSource.split("function RuntimeDistributionSection")[1]?.split("function RuntimeBindingFields")[0] ?? "";
|
||||
expect(runtimeDistributionSectionSource).toContain('action.key === "dependencies-check" || action.key === "dependencies-install"');
|
||||
expect(runtimeDistributionSectionSource).toContain("dependencyActions.some((action) => action.available)");
|
||||
expect(runtimeDistributionSectionSource).toContain("getDependencyCatalog(instance.id)");
|
||||
});
|
||||
|
||||
it("reviews and updates only redacted runtime binding metadata", () => {
|
||||
const runtimeBindingSectionSource = serverDetailPageSource.split("function RuntimeBindingSection")[1]?.split("function RuntimeDistributionSection")[0] ?? "";
|
||||
expect(serverDetailPageSource).toContain("getServerRuntimeBinding");
|
||||
expect(serverDetailPageSource).toContain("updateServerRuntimeBinding");
|
||||
expect(runtimeBindingSectionSource).toContain("missingKeys");
|
||||
expect(runtimeBindingSectionSource).toContain('type={field.sensitive ? "password" : "text"}');
|
||||
for (const forbidden of ["secret://", "/Users/", "/var/run/", "unix://", "tcp://", "mysql://", "sqlite://"]) {
|
||||
expect(runtimeBindingSectionSource).not.toContain(forbidden);
|
||||
}
|
||||
});
|
||||
|
||||
it("routes plugin lifecycle controls through platform lifecycle APIs instead of generic jobs", () => {
|
||||
expect(serverDetailPageSource).toContain('action === "install" || action === "restart"');
|
||||
expect(serverDetailPageSource).toContain('action !== "start" && action !== "stop" && action !== "status"');
|
||||
expect(serverDetailPageSource).toContain('control.lifecycleAction === "start" || control.lifecycleAction === "stop" || control.lifecycleAction === "status"');
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.startServerInstance(instance.id");
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.stopServerInstance(instance.id");
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.queryServerProcessStatus(instance.id");
|
||||
expect(serverDetailPageSource).toContain("serverLifecycleCommandRequest(instance, \"start\")");
|
||||
expect(serverDetailPageSource).toContain("serverLifecycleCommandRequest(instance, \"stop\")");
|
||||
it("removes generic plugin controls from server detail", () => {
|
||||
expect(serverDetailPageSource).not.toContain("PluginControlsSection");
|
||||
expect(serverDetailPageSource).not.toContain("PluginBridgeExecutionPanel");
|
||||
expect(serverDetailPageSource).not.toContain("platformApiClient.createJob({");
|
||||
expect(serverDetailPageSource).not.toContain("插件控制");
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.startServerInstance(current.id");
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.stopServerInstance(current.id");
|
||||
expect(serverDetailPageSource).toContain("serverLifecycleCommandRequest(current, \"start\")");
|
||||
expect(serverDetailPageSource).toContain("serverLifecycleCommandRequest(current, \"stop\")");
|
||||
expect(serverDetailPageSource).not.toContain('capability: "process.start"');
|
||||
expect(serverDetailPageSource).not.toContain('capability: "process.stop"');
|
||||
});
|
||||
@@ -170,17 +128,15 @@ describe("ServerDetailPage config write approval", () => {
|
||||
expect(serverDetailPageSource).not.toContain('capability: "process.install"');
|
||||
});
|
||||
|
||||
it("routes the SCUM logs section to the declared file management workbench", () => {
|
||||
expect(serverDetailPageSource).toContain("serverDetailSectionLabel(entry, instance.data.pluginId)");
|
||||
expect(serverDetailPageSource).toContain('"文件管理"');
|
||||
expect(serverDetailPageSource).toContain("ScumFileManagementSection");
|
||||
it("routes plugin-declared pages into server detail tabs", () => {
|
||||
expect(serverDetailPageSource).toContain("serverDetailSectionEntries(readyPlugin)");
|
||||
expect(serverDetailPageSource).toContain("plugin:${page.key}");
|
||||
expect(serverDetailPageSource).toContain("PluginPageSection");
|
||||
expect(serverDetailPageSource).toContain("PluginPageHostPage");
|
||||
expect(serverDetailPageSource).toContain('routeKey: "files-config"');
|
||||
expect(serverDetailPageSource).toContain('file.kind === "config"');
|
||||
expect(serverDetailPageSource).not.toContain("ScumFileManagementSection");
|
||||
});
|
||||
|
||||
it("keeps plugin lifecycle and bridge-visible output on platform-owned logical references", () => {
|
||||
expect(serverDetailPageSource).toContain("parsePluginArtifactReference(result)");
|
||||
expect(serverDetailPageSource).toContain("platformApiClient.openArtifactDownload(artifact.id)");
|
||||
expect(serverDetailPageSource).toContain("downloadArtifactReference(reference");
|
||||
expect(artifactTransferSource).toContain("readContent(reference.artifactId");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -176,7 +176,7 @@ export function ServersPage({ session, operations, onNavigate }: PageComponentPr
|
||||
setForm(defaultServerCreateForm(plugins, endpoints));
|
||||
setShowCreate(false);
|
||||
await refresh();
|
||||
onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" });
|
||||
onNavigate("serverDetail", { serverId: result.instance.id });
|
||||
} catch (error) {
|
||||
operations.fail(operationId, error instanceof Error ? error.message : "创建失败", operationId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user