Remove SCUM server-management client path
This commit is contained in:
@@ -26,9 +26,7 @@ import {
|
||||
parseBridgeExecutionResponse,
|
||||
parseAIInvocationResponse,
|
||||
type GameClientBridgeQueryTemplateDeclaration,
|
||||
type GameClientBridgeCompanionDeclaration,
|
||||
type GamePluginManifest,
|
||||
type RuntimeClientManagerProfile,
|
||||
type PluginLifecycleActionDeclaration,
|
||||
type PluginBridgeContext
|
||||
} from "../sdk/index.js";
|
||||
@@ -74,16 +72,6 @@ function writeFixtureJSON(fixtureDir: string, relativePath: string, value: unkno
|
||||
fs.writeFileSync(target, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
||||
}
|
||||
|
||||
function listProductionGoFiles(directory: string): string[] {
|
||||
return fs.readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
||||
const target = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
return listProductionGoFiles(target);
|
||||
}
|
||||
return entry.isFile() && entry.name.endsWith(".go") && !entry.name.endsWith("_test.go") ? [target] : [];
|
||||
});
|
||||
}
|
||||
|
||||
function validateTemporaryBridgeManifest(mutate?: (manifest: MutableBridgeManifest, fixtureDir: string) => void): string[] {
|
||||
const fixtureDir = fs.mkdtempSync(path.join(os.tmpdir(), "browser-bridge-manifest-"));
|
||||
try {
|
||||
@@ -129,8 +117,8 @@ function validateTemporaryBridgeManifest(mutate?: (manifest: MutableBridgeManife
|
||||
}
|
||||
}
|
||||
|
||||
function validateTemporaryScumCompanionManifest(mutate: (manifest: Record<string, any>, fixtureDir: string) => void): string[] {
|
||||
const fixtureDir = fs.mkdtempSync(path.join(os.tmpdir(), "browser-scum-companion-manifest-"));
|
||||
function validateTemporaryScumManifest(mutate: (manifest: Record<string, any>, fixtureDir: string) => void): string[] {
|
||||
const fixtureDir = fs.mkdtempSync(path.join(os.tmpdir(), "browser-scum-manifest-"));
|
||||
try {
|
||||
fs.cpSync(path.join(pluginsRoot, "examples/scum-server-plugin"), fixtureDir, { recursive: true });
|
||||
const manifestPath = path.join(fixtureDir, "manifest.json");
|
||||
@@ -209,18 +197,18 @@ describe("plugin manifest validation", () => {
|
||||
});
|
||||
|
||||
it("rejects lifecycle executable assets missing from the manifest seed declaration", () => {
|
||||
const errors = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
const errors = validateTemporaryScumManifest((manifest) => {
|
||||
manifest.assetFiles = manifest.assetFiles.filter((file: { path: string }) => file.path !== "bin/scum-start.cmd");
|
||||
});
|
||||
expect(errors.some((error) => error.includes("lifecycleAction.start.executableKey") && error.includes("manifest.assetFiles"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects unsupported or unsafe inline create-field declarations", () => {
|
||||
const malformed = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
const malformed = validateTemporaryScumManifest((manifest) => {
|
||||
manifest.server.createFields[0].type = "path";
|
||||
});
|
||||
expect(malformed.some((error) => error.includes("createFields") && error.includes("type"))).toBe(true);
|
||||
const unsafe = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
const unsafe = validateTemporaryScumManifest((manifest) => {
|
||||
manifest.server.createFields[0].defaultValue = "/srv/hidden-server";
|
||||
});
|
||||
expect(unsafe.some((error) => error.includes("raw host path"))).toBe(true);
|
||||
@@ -244,167 +232,6 @@ describe("plugin manifest validation", () => {
|
||||
]));
|
||||
});
|
||||
|
||||
it("defines a generated SCUM companion config without inline proof or session material", () => {
|
||||
const pluginDir = path.join(pluginsRoot, "examples/scum-server-plugin");
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(pluginDir, "manifest.json"), "utf8")) as {
|
||||
gameClientBridge: { companion?: GameClientBridgeCompanionDeclaration };
|
||||
};
|
||||
const companion = manifest.gameClientBridge.companion;
|
||||
expect(companion).toMatchObject({
|
||||
profileKey: "scum-client-manager",
|
||||
configTemplateKey: "client-config",
|
||||
configFormat: "yaml",
|
||||
platformBaseUrlSource: "run-control",
|
||||
registrationProof: "hmac-sha256",
|
||||
proofMaterialSource: "component-package",
|
||||
proofMaterialEnv: "SCUM_COMPONENT_PROOF",
|
||||
sessionMode: "component-session",
|
||||
tlsPolicy: "verify-system-roots",
|
||||
heartbeatIntervalSeconds: 30,
|
||||
requestTimeoutSeconds: 15
|
||||
});
|
||||
const schema = JSON.parse(fs.readFileSync(path.join(pluginDir, companion!.configSchemaRef), "utf8"));
|
||||
const example = JSON.parse(fs.readFileSync(path.join(pluginDir, "schemas/companion/config.generated.example.json"), "utf8"));
|
||||
const validate = new Ajv2020({ strict: false, validateFormats: false }).compile(schema);
|
||||
expect(validate(example), JSON.stringify(validate.errors)).toBe(true);
|
||||
expect(JSON.stringify(example)).not.toMatch(/authKey|componentKey|credential|password|sessionToken|secret|\/api\/v1\/scum-clients\//i);
|
||||
expect(example).toMatchObject({ proof: { materialEnv: "SCUM_COMPONENT_PROOF" }, session: { mode: "component-session" }, tls: { policy: "verify-system-roots" } });
|
||||
});
|
||||
|
||||
it("rejects unsafe SCUM companion bootstrap policy and inline session material", () => {
|
||||
const policyErrors = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
manifest.gameClientBridge.companion.tlsPolicy = "skip-verification";
|
||||
});
|
||||
expect(policyErrors.some((error) => error.includes("tlsPolicy") || error.includes("secure component registration/session/TLS policy"))).toBe(true);
|
||||
|
||||
const materialErrors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const examplePath = path.join(fixtureDir, "schemas/companion/config.generated.example.json");
|
||||
const example = JSON.parse(fs.readFileSync(examplePath, "utf8"));
|
||||
example.proof.sessionToken = "inline-session-material";
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.generated.example.json", example);
|
||||
});
|
||||
expect(materialErrors.some((error) => error.includes("inline proof/session material") || error.includes("additional properties"))).toBe(true);
|
||||
|
||||
const environmentErrors = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
manifest.gameClientBridge.companion.proofMaterialEnv = "LD_PRELOAD";
|
||||
});
|
||||
expect(environmentErrors.some((error) => error.includes("proofMaterialEnv"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects generated SCUM companion configs with incomplete capabilities or unsafe Platform URLs", () => {
|
||||
const capabilityErrors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const examplePath = path.join(fixtureDir, "schemas/companion/config.generated.example.json");
|
||||
const example = JSON.parse(fs.readFileSync(examplePath, "utf8"));
|
||||
example.capabilities = ["component.register", "component.heartbeat", "component.health", "game-client.bridge"];
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.generated.example.json", example);
|
||||
});
|
||||
expect(capabilityErrors.some((error) => error.includes("capabilities"))).toBe(true);
|
||||
|
||||
for (const unsafeURL of ["https://user:raw-token@example.test?session=raw-token#fragment", "https://?missing-host"]) {
|
||||
const urlErrors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const examplePath = path.join(fixtureDir, "schemas/companion/config.generated.example.json");
|
||||
const example = JSON.parse(fs.readFileSync(examplePath, "utf8"));
|
||||
example.platform.baseUrl = unsafeURL;
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.generated.example.json", example);
|
||||
});
|
||||
expect(urlErrors.some((error) => error.includes("platform.baseUrl"))).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("cross-validates generated SCUM companion config against its declaration and runtime profile", () => {
|
||||
const proofErrors = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
manifest.gameClientBridge.companion.proofMaterialEnv = "OTHER_COMPONENT_PROOF";
|
||||
});
|
||||
expect(proofErrors.some((error) => error.includes("proof.materialEnv") && error.includes("proofMaterialEnv"))).toBe(true);
|
||||
|
||||
const profileErrors = validateTemporaryScumCompanionManifest((manifest) => {
|
||||
const manager = manifest.runtimeProfiles.clientManagers.find((candidate: Record<string, unknown>) => candidate.key === "scum-client-manager");
|
||||
manager.health.requiredCapabilities = manager.health.requiredCapabilities.filter((capability: string) => capability !== "logs.stream");
|
||||
});
|
||||
expect(profileErrors.some((error) => error.includes("capabilities") && error.includes("requiredCapabilities"))).toBe(true);
|
||||
|
||||
const sessionErrors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const examplePath = path.join(fixtureDir, "schemas/companion/config.generated.example.json");
|
||||
const example = JSON.parse(fs.readFileSync(examplePath, "utf8"));
|
||||
example.session.mode = "legacy-shared-token";
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.generated.example.json", example);
|
||||
});
|
||||
expect(sessionErrors.some((error) => error.includes("session"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects unsafe optional fields declared only by the SCUM companion config schema", () => {
|
||||
const schemaErrors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const schemaPath = path.join(fixtureDir, "schemas/companion/config.schema.json");
|
||||
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
||||
schema.properties.hostPath = { type: "string", minLength: 1, maxLength: 200 };
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.schema.json", schema);
|
||||
});
|
||||
expect(schemaErrors.some((error) => error.includes("hostPath") && error.includes("raw host path"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects legacy companion endpoints, insecure TLS flags, and credential keys", () => {
|
||||
const cases = [
|
||||
{
|
||||
name: "legacy shared-token endpoint",
|
||||
mutate(schema: Record<string, any>, _example: Record<string, any>): void {
|
||||
schema.description = "legacy /api/v1/scum-clients/commands endpoint";
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "insecure TLS flag",
|
||||
mutate(schema: Record<string, any>, _example: Record<string, any>): void {
|
||||
schema.description = "InsecureSkipVerify";
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "inline credential key",
|
||||
mutate(schema: Record<string, any>, example: Record<string, any>): void {
|
||||
schema.properties.credential = { type: "string", minLength: 1, maxLength: 200 };
|
||||
example.credential = "legacy-shared-value";
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
const errors = validateTemporaryScumCompanionManifest((_manifest, fixtureDir) => {
|
||||
const schemaPath = path.join(fixtureDir, "schemas/companion/config.schema.json");
|
||||
const examplePath = path.join(fixtureDir, "schemas/companion/config.generated.example.json");
|
||||
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8")) as Record<string, any>;
|
||||
const example = JSON.parse(fs.readFileSync(examplePath, "utf8")) as Record<string, any>;
|
||||
testCase.mutate(schema, example);
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.schema.json", schema);
|
||||
writeFixtureJSON(fixtureDir, "schemas/companion/config.generated.example.json", example);
|
||||
});
|
||||
|
||||
expect(errors, testCase.name).toContain(
|
||||
"manifest.gameClientBridge.companion.configSchemaRef: companion config must not contain legacy endpoints, insecure TLS, or inline proof/session material"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the production SCUM companion free of unsafe legacy transport and updater patterns", () => {
|
||||
const companionDir = path.join(pluginsRoot, "examples/scum-server-plugin/companion");
|
||||
const forbiddenPatterns = [
|
||||
{ name: "legacy shared-token endpoint", pattern: /\/api\/v1\/scum-clients\//i },
|
||||
{ name: "legacy shared credential", pattern: /\b(?:SCUMClientCredential|scum_client_credential)\b/i },
|
||||
{ name: "disabled TLS verification", pattern: /\bInsecureSkipVerify\s*:\s*true\b/ },
|
||||
{ name: "arbitrary process or shell execution", pattern: /(?:\b(?:os\/exec|exec\.Command(?:Context)?|os\.StartProcess|syscall\.Exec)\b|\b(?:bash|zsh|powershell|pwsh|cmd(?:\.exe)?)\s+-[a-z/])/i },
|
||||
{ name: "direct socket transport", pattern: /(?:\bnet\.(?:Dial|DialTimeout)\s*\(|\b(?:tcp|unix|ws):\/\/)/i },
|
||||
{ name: "arbitrary URL self-update or download", pattern: /(?:\b(?:self_?update|update_?url|download_?url|updater)\b|\bhttp\.(?:Get|DefaultClient\.Get)\s*\(|\b(?:curl|wget)\b)/i }
|
||||
];
|
||||
|
||||
const productionFiles = listProductionGoFiles(companionDir);
|
||||
expect(productionFiles.length).toBeGreaterThan(0);
|
||||
for (const file of productionFiles) {
|
||||
const source = fs.readFileSync(file, "utf8");
|
||||
const relativeFile = path.relative(companionDir, file);
|
||||
for (const forbidden of forbiddenPatterns) {
|
||||
const match = source.match(forbidden.pattern);
|
||||
expect(match ? `${relativeFile}: ${match[0]}` : null, forbidden.name).toBeNull();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("covers the SCUM 4.1 bridge and lifecycle declarations", () => {
|
||||
const manifestPath = path.join(pluginsRoot, "examples/scum-server-plugin/manifest.json");
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")) as {
|
||||
@@ -450,7 +277,6 @@ describe("plugin manifest validation", () => {
|
||||
expect(installAction.environment?.SERVER_TEMPLATE).toBe("scum-server");
|
||||
expect(manifest.permissions).toEqual(expect.arrayContaining(["server.game-client.read", "server.game-client.command", "server.game-client.maintenance"]));
|
||||
expect(manifest.gameClientBridge.commands.map((command) => command.type)).toEqual(expect.arrayContaining([
|
||||
"companion.diagnostics",
|
||||
"player.lookup",
|
||||
"reward.deliver",
|
||||
"player.notify",
|
||||
@@ -459,7 +285,8 @@ describe("plugin manifest validation", () => {
|
||||
"restart.prepare",
|
||||
"maintenance.prepare"
|
||||
]));
|
||||
expect(manifest.gameClientBridge.snapshots.map((snapshot) => snapshot.type)).toEqual(expect.arrayContaining(["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"]));
|
||||
expect(manifest.gameClientBridge.snapshots.map((snapshot) => snapshot.type)).toEqual(expect.arrayContaining(["online.sessions", "players", "squads", "vehicles", "flags"]));
|
||||
expect(manifest.runtimeProfiles?.clientManagers).toBeUndefined();
|
||||
expect(manifest.gameClientBridge.queryTemplates.find((template) => template.key === "scum.vehicles")?.projections).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ collection: "scum_trade_goods", mergeExisting: true, fixedValues: expect.objectContaining({ catalogType: "vehicle", type: "21", typeName: "其他载具" }) })
|
||||
]));
|
||||
@@ -473,8 +300,8 @@ describe("plugin manifest validation", () => {
|
||||
expect(manifest.fileWorkspace?.directories.map((directory) => `${directory.key}:${directory.scope}`)).toEqual(expect.arrayContaining(["scum-config:config", "scum-logs:logs"]));
|
||||
expect(manifest.fileWorkspace?.files.map((file) => file.key)).toEqual(expect.arrayContaining(["scum-server-settings", "scum-admin-users", "scum-chat-log", "scum-performance-log"]));
|
||||
expect(manifest.fileWorkspace?.configFields.map((field) => field.key)).toEqual(expect.arrayContaining(["server-name", "game-port", "query-port", "max-players", "welcome-message"]));
|
||||
expect(manifest.runtimeProfiles?.lifecycleProfiles?.find((profile) => profile.key === "scum-client")?.capabilities).not.toContain("remote.run.rcon.command");
|
||||
expect(manifest.runtimeProfiles?.logSources?.map((source) => source.key)).toEqual(expect.arrayContaining(["scum-chat-events", "scum-server-events", "scum-login-events", "scum-trade-events", "scum-client-events"]));
|
||||
expect(manifest.runtimeProfiles?.lifecycleProfiles?.find((profile) => profile.key === "scum-client")).toBeUndefined();
|
||||
expect(manifest.runtimeProfiles?.logSources?.map((source) => source.key)).toEqual(expect.arrayContaining(["scum-chat-events", "scum-server-events", "scum-login-events", "scum-trade-events"]));
|
||||
});
|
||||
|
||||
it("declares bounded and permissioned SCUM bridge commands", () => {
|
||||
@@ -492,7 +319,6 @@ describe("plugin manifest validation", () => {
|
||||
};
|
||||
};
|
||||
const expected = {
|
||||
"companion.diagnostics": { permission: "server.game-client.read" },
|
||||
"player.lookup": { permission: "server.game-client.read" },
|
||||
"reward.deliver": { permission: "server.game-client.command" },
|
||||
"player.notify": { permission: "server.game-client.command" },
|
||||
@@ -559,7 +385,7 @@ describe("plugin manifest validation", () => {
|
||||
pages: Array<{ pageKey: string; snapshotTypes?: string[] }>;
|
||||
};
|
||||
};
|
||||
const expectedTypes = ["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"];
|
||||
const expectedTypes = ["online.sessions", "players", "squads", "vehicles", "flags"];
|
||||
const snapshotsByType = new Map(manifest.gameClientBridge.snapshots.map((snapshot) => [snapshot.type, snapshot]));
|
||||
|
||||
expect([...snapshotsByType.keys()]).toEqual(expect.arrayContaining(expectedTypes));
|
||||
@@ -639,7 +465,7 @@ describe("plugin manifest validation", () => {
|
||||
const sqliteTransport = manifest.runtimeProfiles?.transportProfiles?.find((profile) => profile.key === "scum-database");
|
||||
expect(sqliteTransport).toMatchObject({ kind: "sqlite", targetKey: "scum-database" });
|
||||
expect(sqliteTransport?.capabilities).toEqual(expect.arrayContaining(["remote.run.db.sqlite.query", "remote.run.db.sqlite.execute"]));
|
||||
expect(manifest.runtimeProfiles?.dataTargets).toEqual(expect.arrayContaining([expect.objectContaining({ key: "scum-database", kind: "sqlite.snapshot", sourcePath: "SCUM/Saved/SaveFiles/SCUM.db", workspaceKey: "databases/scum-database" })]));
|
||||
expect(manifest.runtimeProfiles?.dataTargets).toBeUndefined();
|
||||
for (const key of expectedKeys) {
|
||||
const template = templatesByKey.get(key)!;
|
||||
expect(template.engine).toBe("sqlite");
|
||||
@@ -703,22 +529,11 @@ describe("plugin manifest validation", () => {
|
||||
});
|
||||
|
||||
|
||||
it("aligns the SCUM Client Manager declaration with the real Go bootstrap", () => {
|
||||
it("does not declare a SCUM client-manager profile", () => {
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(pluginsRoot, "examples/scum-server-plugin/manifest.json"), "utf8")) as {
|
||||
runtimeProfiles?: { clientManagers?: Array<{
|
||||
key: string;
|
||||
build?: { workspaceRef?: string; entryRef?: string };
|
||||
configTemplates?: Array<{ key?: string; templateRef?: string; outputRef?: string }>;
|
||||
deployment?: { arguments?: string[] };
|
||||
health?: { intervalSeconds?: number; degradedAfterSeconds?: number; offlineAfterSeconds?: number };
|
||||
}> };
|
||||
runtimeProfiles?: { clientManagers?: unknown[] };
|
||||
};
|
||||
const manager = manifest.runtimeProfiles?.clientManagers?.find((profile) => profile.key === "scum-client-manager");
|
||||
expect(manager?.build).toMatchObject({ entryRef: "main.go" });
|
||||
expect(manager?.build).not.toHaveProperty("workspaceRef");
|
||||
expect(manager?.configTemplates).toEqual([{ key: "client-config", templateRef: "config.yaml.example", outputRef: "config.yaml" }]);
|
||||
expect(manager?.deployment?.arguments).toBeUndefined();
|
||||
expect(manager?.health).toMatchObject({ intervalSeconds: 30, degradedAfterSeconds: 90, offlineAfterSeconds: 120 });
|
||||
expect(manifest.runtimeProfiles?.clientManagers).toBeUndefined();
|
||||
});
|
||||
|
||||
it("accepts the Minecraft server plugin manifest", () => {
|
||||
@@ -953,7 +768,7 @@ describe("plugin SDK", () => {
|
||||
|
||||
it("builds safe game-client bridge requests without component transport material", () => {
|
||||
const request = createGameClientBridgeQueueRequest({
|
||||
profileKey: "scum-client",
|
||||
profileKey: "example-client",
|
||||
commandType: "diagnostic.ping",
|
||||
payload: { message: "hello" },
|
||||
idempotencyKey: "diagnostic-1",
|
||||
@@ -1302,18 +1117,18 @@ describe("plugin SDK", () => {
|
||||
action: "logs.backfill.request",
|
||||
payload: { sourceKey: "chat-log", limit: "500" }
|
||||
});
|
||||
expect(createClientManagerRequest({ requestId: "client-1", context, operation: "generate", profileKey: "scum-client-manager", targetOS: "windows", targetArch: "amd64", idempotencyKey: "idem-client" })).toMatchObject({
|
||||
expect(createClientManagerRequest({ requestId: "client-1", context, operation: "generate", profileKey: "example-client-manager", targetOS: "windows", targetArch: "amd64", idempotencyKey: "idem-client" })).toMatchObject({
|
||||
action: "client-manager.request",
|
||||
payload: { operation: "generate", profileKey: "scum-client-manager" }
|
||||
payload: { operation: "generate", profileKey: "example-client-manager" }
|
||||
});
|
||||
expect(JSON.stringify(createClientManagerRequest({ requestId: "client-2", context, operation: "reset-key", profileKey: "scum-client-manager", idempotencyKey: "idem-reset" }))).not.toContain("secret");
|
||||
expect(createClientManagerRequest({ requestId: "client-3", context, operation: "deploy", profileKey: "scum-client-manager", installationId: "cm-install-1", artifactId: "artifact-1", expectedDeploymentGeneration: 2, idempotencyKey: "idem-deploy" })).toMatchObject({
|
||||
expect(JSON.stringify(createClientManagerRequest({ requestId: "client-2", context, operation: "reset-key", profileKey: "example-client-manager", idempotencyKey: "idem-reset" }))).not.toContain("secret");
|
||||
expect(createClientManagerRequest({ requestId: "client-3", context, operation: "deploy", profileKey: "example-client-manager", installationId: "cm-install-1", artifactId: "artifact-1", expectedDeploymentGeneration: 2, idempotencyKey: "idem-deploy" })).toMatchObject({
|
||||
action: "client-manager.request",
|
||||
payload: { operation: "deploy", installationId: "cm-install-1", artifactId: "artifact-1", expectedDeploymentGeneration: "2" }
|
||||
});
|
||||
expect(parseClientManagerLifecycleStatus({
|
||||
installationId: "cm-install-1",
|
||||
profileKey: "scum-client-manager",
|
||||
profileKey: "example-client-manager",
|
||||
status: "online",
|
||||
phase: "healthy",
|
||||
targetOS: "windows",
|
||||
@@ -1326,7 +1141,7 @@ describe("plugin SDK", () => {
|
||||
})).toMatchObject({ installationId: "cm-install-1", deploymentGeneration: 2, actions: ["stop", "restart", "update", "uninstall"] });
|
||||
expect(parseClientManagerLifecycleStatus({
|
||||
installationId: "cm-install-1",
|
||||
profileKey: "scum-client-manager",
|
||||
profileKey: "example-client-manager",
|
||||
status: "online",
|
||||
deploymentGeneration: "2",
|
||||
actions: "stop",
|
||||
|
||||
Reference in New Issue
Block a user