This commit is contained in:
2026-09-10 17:03:10 +02:00
parent 90dc18a167
commit 3a3d70efeb
27 changed files with 4973 additions and 3 deletions
+73
View File
@@ -0,0 +1,73 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import {
liveUrlForTool,
normalizePath,
responseProjectMismatch,
} from "../out/agent/mcpServer.js";
const PROJECT_A = "D:/Mods/Example";
test("live URLs always pin the requested project", () => {
const url = liveUrlForTool("http://127.0.0.1:1234", PROJECT_A, "find_asset", {
id: "AthenaCannon",
type: "GameObject",
});
assert.ok(url);
const parsed = new URL(url);
assert.equal(parsed.pathname, "/find_asset");
assert.equal(parsed.searchParams.get("project"), PROJECT_A);
assert.equal(parsed.searchParams.get("id"), "AthenaCannon");
assert.equal(parsed.searchParams.get("type"), "GameObject");
});
test("get_asset_references serialises its list and scalar options", () => {
const url = liveUrlForTool("http://127.0.0.1:1234/", PROJECT_A, "get_asset_references", {
id: "AthenaCannon",
depth: 2,
targetTypes: ["WeaponTemplate", "GameObject"],
maxEdges: 25,
includeUnresolved: true,
});
assert.ok(url);
const parsed = new URL(url);
assert.equal(parsed.pathname, "/get_asset_references");
assert.equal(parsed.searchParams.get("depth"), "2");
assert.equal(parsed.searchParams.get("targetTypes"), "WeaponTemplate,GameObject");
assert.equal(parsed.searchParams.get("maxEdges"), "25");
assert.equal(parsed.searchParams.get("includeUnresolved"), "true");
assert.equal(parsed.searchParams.get("project"), PROJECT_A);
});
test("live URLs omit the project selector when none is configured", () => {
const url = liveUrlForTool("http://127.0.0.1:1234", null, "get_status", {});
assert.equal(url, "http://127.0.0.1:1234/status");
});
test("unknown tools have no live URL", () => {
assert.equal(liveUrlForTool("http://127.0.0.1:1", PROJECT_A, "nope", {}), null);
});
test("responseProjectMismatch flags answers from another project", () => {
// Matching project (case/separator-insensitive) is accepted.
assert.equal(
responseProjectMismatch({ index: { projectDir: "d:/mods/example" } }, PROJECT_A),
false,
);
// A different project must be rejected: this is the multi-window cross-talk guard.
assert.equal(
responseProjectMismatch({ index: { projectDir: "D:/Mods/Other" } }, PROJECT_A),
true,
);
// No project configured, or no projectDir in the payload: nothing to check.
assert.equal(responseProjectMismatch({ index: { state: "ready" } }, PROJECT_A), false);
assert.equal(
responseProjectMismatch({ index: { projectDir: "D:/Mods/Other" } }, null),
false,
);
assert.equal(responseProjectMismatch(null, PROJECT_A), false);
});
test("normalizePath is case- and separator-insensitive", () => {
assert.equal(normalizePath("D:\\Mods\\Example\\"), normalizePath("d:/mods/example"));
});