Files
unreal-engine-mcp-system-pl…/test/mockUE.test.js
Bonchellon eba71c4ca8 Unified, portable Unreal Engine MCP system plugin
Merge of the two project copies into one self-contained plugin (the superset:
variable_op + variables.py, full pcg_op runtime/declarative/preset ops, the
CreateWidgetFloatAnimation widget tool, and full Voxel graph authoring).

Made fully project- and machine-agnostic — no hardcoded paths:
- New src/projectPaths.js auto-detects the host .uproject (walk-up), project
  name, Editor build target, log file, and engine install (EngineAssociation
  via launcher manifest/registry, else installed-engine scan). All overridable
  via UE_* env vars.
- Rewired buildOrchestrator/insights/launcher/insightsExporter/server.js and the
  Python workers (cpp_scaffold, live_coding, apply_graph, console) off the old
  C:/Github/ihy, IHY*, E:/UE_Versions and UE_5.7 literals onto the resolver.
- Voxel made optional: Build.cs auto-detects the Voxel plugin (env
  UE_MCP_WITH_VOXEL override) and the C++ compiles to stubs under WITH_MCP_VOXEL,
  so the module builds in projects without Voxel; .uplugin marks Voxel optional.
- De-branded the agent-gateway and docs; scrubbed a leaked API key; excluded
  node_modules/Binaries/Intermediate/__pycache__/secrets from the repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 01:07:24 +03:00

61 lines
2.2 KiB
JavaScript

// Spin up a fake Remote Control endpoint and verify the bridge talks to it.
import { test } from "node:test";
import assert from "node:assert/strict";
import http from "node:http";
import { executePythonInUE, ping } from "../src/ueBridge.js";
function startMockUE() {
const seen = { calls: [] };
const srv = http.createServer((req, res) => {
let body = "";
req.on("data", c => body += c);
req.on("end", () => {
if (req.url === "/remote/info" && req.method === "GET") {
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ name: "MockUE", version: "5.7" }));
}
if (req.url === "/remote/object/call" && req.method === "PUT") {
let parsed = null;
try { parsed = JSON.parse(body); } catch {}
seen.calls.push(parsed);
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ ReturnValue: true }));
}
res.writeHead(404); res.end();
});
});
return new Promise(resolve => {
srv.listen(0, "127.0.0.1", () => {
const { port } = srv.address();
resolve({ srv, seen, baseUrl: `http://127.0.0.1:${port}` });
});
});
}
test("ping reaches mock UE", async () => {
const { srv, baseUrl } = await startMockUE();
try {
const r = await ping({ baseUrl, timeoutMs: 2000 });
assert.equal(r.ok, true);
assert.equal(r.info.name, "MockUE");
} finally { srv.close(); }
});
test("executePythonInUE PUTs the right payload to /remote/object/call", async () => {
const { srv, seen, baseUrl } = await startMockUE();
try {
const r = await executePythonInUE("print('hi')", { baseUrl, timeoutMs: 2000 });
assert.equal(r.ok, true);
assert.equal(seen.calls.length, 1);
assert.equal(seen.calls[0].functionName, "ExecutePythonCommand");
assert.equal(seen.calls[0].parameters.PythonCommand, "print('hi')");
assert.ok(seen.calls[0].objectPath.includes("PythonScriptLibrary"));
} finally { srv.close(); }
});
test("executePythonInUE returns ok:false when UE unreachable", async () => {
const r = await executePythonInUE("print('x')", { baseUrl: "http://127.0.0.1:1", timeoutMs: 500 });
assert.equal(r.ok, false);
assert.match(r.error, /cannot reach UE/);
});