Move dependency resolver tests to test/messages/mod.test.js

Also update the existing local mod fixtures to carry a factorio_version
and drop enable-all-feature-flags from the live expectations: the 2.0
releases of pyalternativeenergy only list it as optional, it was only
pulled in before because 2.1 releases were being selected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Fable 5 committed 2026-08-18 16:54:19 +00:00
1 parent 5e6b06f009
commit 5e633ac2f1
2 files changed
+69 -76

No files matched your search

-73
View File
@@ -1,6 +1,5 @@
"use strict";
const assert = require("assert").strict;
const lib = require("@clusterio/lib");
const { ControlConnection } = require("@clusterio/controller");
describe("controller/src/ControlConnection", function() {
@@ -40,76 +39,4 @@ describe("controller/src/ControlConnection", function() {
assert.equal(mockController.stopped, false);
});
});
describe(".handleModDependencyResolveRequest()", function() {
const originalFetchModReleases = lib.ModStore.fetchModReleases;
const portal = new Map();
let localMods;
function release(version, factorioVersion, dependencies = []) {
return {
version, sha1: "0".repeat(40),
info_json: { factorio_version: factorioVersion, dependencies },
};
}
before(function() {
lib.ModStore.fetchModReleases = async (name) => {
const releases = portal.get(name);
if (!releases) {
throw new Error("Fetch: returned 404 Not Found");
}
return { name, owner: "owner", title: name, releases };
};
});
after(function() {
lib.ModStore.fetchModReleases = originalFetchModReleases;
});
beforeEach(function() {
portal.clear();
localMods = [];
});
async function resolve(mods, factorioVersion, checkForUpdates = false) {
const response = await ControlConnection.prototype.handleModDependencyResolveRequest.call(
{ _controller: { modStore: { mods: () => localMods } } },
new lib.ModDependencyResolveRequest(
mods.map(mod => new lib.ModDependency(mod)), factorioVersion, checkForUpdates,
),
);
return new Map(response.dependencies.map(mod => [mod.name, mod]));
}
it("only selects portal releases matching the mod pack's Factorio version", async function() {
portal.set("root", [release("1.0.0", "2.0", ["dep"]), release("1.1.0", "2.1", ["dep"])]);
portal.set("dep", [
release("1.0.0", "1.1"),
release("2.0.0", "2.0"),
release("3.0.0", "2.1"),
]);
assert.equal((await resolve(["root = 1.0.0"], "2.0")).get("dep").version, "2.0.0");
assert.equal((await resolve(["root = 1.1.0"], "2.1")).get("dep").version, "3.0.0");
});
it("only selects local mods matching the mod pack's Factorio version", async function() {
portal.set("root", [release("1.0.0", "2.0", ["dep"])]);
portal.set("dep", [release("2.0.0", "2.0")]);
localMods = [
lib.ModInfo.fromJSON({ name: "dep", version: "3.0.0", factorio_version: "2.1" }),
lib.ModInfo.fromJSON({ name: "dep", version: "1.0.0", factorio_version: "2.0" }),
];
assert.equal((await resolve(["root = 1.0.0"], "2.0")).get("dep").version, "1.0.0");
assert.equal((await resolve(["root = 1.0.0"], "2.0", true)).get("dep").version, "2.0.0");
});
it("reports dependencies without a matching Factorio version as not found", async function() {
portal.set("root", [release("1.0.0", "2.0", ["dep"])]);
portal.set("dep", [release("3.0.0", "2.1")]);
const response = await ControlConnection.prototype.handleModDependencyResolveRequest.call(
{ _controller: { modStore: { mods: () => localMods } } },
new lib.ModDependencyResolveRequest([new lib.ModDependency("root = 1.0.0")], "2.0", false),
);
assert.equal(response.errors.get("dep"), "notFound");
});
});
});
+69 -3
View File
@@ -384,8 +384,10 @@ describe("messages/mod", function() {
}
});
it("prefers the locally installed version if matching", async function() {
controller.modStore.addMod(lib.ModInfo.fromJSON({ name: "foo", version: "1.0.0" }));
for (const factorioVersion of factorioVersions) {
controller.modStore.addMod(lib.ModInfo.fromJSON({
name: "foo", version: "1.0.0", factorio_version: factorioVersion,
}));
setPortalModRelease("root", "1.0.0", factorioVersion, ["foo"]);
setPortalModRelease("foo", "2.0.0", factorioVersion, []);
@@ -402,8 +404,10 @@ describe("messages/mod", function() {
}
});
it("prefers the mod portal version when checking for updates", async function() {
controller.modStore.addMod(lib.ModInfo.fromJSON({ name: "foo", version: "1.0.0" }));
for (const factorioVersion of factorioVersions) {
controller.modStore.addMod(lib.ModInfo.fromJSON({
name: "foo", version: "1.0.0", factorio_version: factorioVersion,
}));
setPortalModRelease("root", "1.0.0", factorioVersion, ["foo"]);
setPortalModRelease("foo", "2.0.0", factorioVersion, []);
@@ -455,6 +459,68 @@ describe("messages/mod", function() {
assert.deepEqual(depIds, new Set(["root_1.0.0", "foo_2.0.0", "bar_1.5.0"]));
}
});
it("only selects portal releases matching the factorio version", async function() {
setPortalModRelease("root", "1.0.0", "2.0", ["foo"]);
ModReleases.set("foo", {
name: "foo",
releases: [{
version: "1.0.0", info_json: { factorio_version: "1.1", dependencies: [] },
}, {
version: "2.0.0", info_json: { factorio_version: "2.0", dependencies: [] },
}, {
version: "3.0.0", info_json: { factorio_version: "2.1", dependencies: [] },
}],
});
const result = await controlConnection.handleModDependencyResolveRequest(
new lib.ModDependencyResolveRequest([new ModDependency("root")], "2.0")
);
assert.deepEqual(result.errors, new Map([
["base", "notFound"],
]));
const depIds = new Set(result.dependencies.map(mod => mod.id));
assert.deepEqual(depIds, new Set(["root_1.0.0", "foo_2.0.0"]));
});
it("only selects local mods matching the factorio version", async function() {
controller.modStore.addMod(lib.ModInfo.fromJSON({
name: "foo", version: "1.0.0", factorio_version: "2.0",
}));
controller.modStore.addMod(lib.ModInfo.fromJSON({
name: "foo", version: "3.0.0", factorio_version: "2.1",
}));
setPortalModRelease("root", "1.0.0", "2.0", ["foo"]);
setPortalModRelease("foo", "2.0.0", "2.0", []);
let result = await controlConnection.handleModDependencyResolveRequest(
new lib.ModDependencyResolveRequest([new ModDependency("root")], "2.0")
);
let depIds = new Set(result.dependencies.map(mod => mod.id));
assert.deepEqual(depIds, new Set(["root_1.0.0", "foo_1.0.0"]));
result = await controlConnection.handleModDependencyResolveRequest(
new lib.ModDependencyResolveRequest([new ModDependency("root")], "2.0", true)
);
depIds = new Set(result.dependencies.map(mod => mod.id));
assert.deepEqual(depIds, new Set(["root_1.0.0", "foo_2.0.0"]));
});
it("highlights dependencies with no release for the factorio version", async function() {
setPortalModRelease("root", "1.0.0", "2.0", ["foo"]);
setPortalModRelease("foo", "1.0.0", "2.1", []);
const result = await controlConnection.handleModDependencyResolveRequest(
new lib.ModDependencyResolveRequest([new ModDependency("root")], "2.0")
);
assert.deepEqual(result.errors, new Map([
["base", "notFound"],
["foo", "notFound"],
]));
assert.equal(result.dependencies.length, 1);
assert.equal(result.dependencies[0].id, "root_1.0.0");
});
it("rejects when a network error occurs", async function() {
lib.ModStore.fetchModReleases = function() {
throw new Error("Mock network error");
@@ -484,7 +550,7 @@ describe("messages/mod", function() {
"pyalienlife", "pyalienlifegraphics", "pyalienlifegraphics2", "pyalienlifegraphics3",
"pycoalprocessing", "pycoalprocessinggraphics", "pyfusionenergy", "pyfusionenergygraphics",
"pypetroleumhandling", "pypetroleumhandlinggraphics", "pyrawores", "pyraworesgraphics",
"pyhightech", "pyhightechgraphics", "pyindustry", "pyindustrygraphics", "enable-all-feature-flags",
"pyhightech", "pyhightechgraphics", "pyindustry", "pyindustrygraphics",
]));
});
});