Files
factorio-clusterio/test/lib/plugin.js
T
BastiaanandClaude Fable 5.1 1a10b38743 Only report a missing plugin web build when one is expected (#1013)
Plugins with only host, instance or ctl code have no reason to ship a
webpack build, yet the plugin list showed "Missing dist/web/manifest.json"
as an error for them and the controller logged a warning on every start.

Decide whether a build is expected from the plugin declaration, using the
same rule the create tool uses to decide when to generate one: a web or
controller entrypoint, or any config fields. Plugins outside that rule get
no bundle path and no error, the web UI skips loading them, and the plugin
pages show them as having no web module instead of an error or a prompt to
reload.

Fixes #1004

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 01:59:16 +01:00

57 lines
2.0 KiB
JavaScript

import assert from "node:assert/strict";
import * as mock from "../mock.js";
import * as lib from "@clusterio/lib";
describe("lib/plugin", function() {
describe("pluginNeedsWebBuild()", function() {
it("should be false for plugins with only host, instance or ctl code", function() {
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo" }), false);
assert.equal(lib.pluginNeedsWebBuild({
name: "foo", title: "Foo", hostEntrypoint: "host.js", instanceEntrypoint: "instance.js",
ctlEntrypoint: "ctl.js", messages: [],
}), false);
});
it("should be true for plugins with web or controller code or config fields", function() {
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo", webEntrypoint: "web.js" }), true);
assert.equal(lib.pluginNeedsWebBuild({
name: "foo", title: "Foo", controllerEntrypoint: "controller.js",
}), true);
for (const field of [
"controllerConfigFields", "hostConfigFields", "instanceConfigFields", "controlConfigFields",
]) {
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo", [field]: {} }), true, field);
}
});
});
describe("invokeHook()", function() {
let betaTestCalled = false;
let plugins = new Map([
["alpha", {
test: async function() { },
pass: async function(arg) { return arg; },
error: async function() { throw new Error("Test"); },
logger: new mock.MockLogger(),
}],
["beta", {
test: async function() { betaTestCalled = true; },
pass: async function() { },
error: async function() { },
logger: new mock.MockLogger(),
}],
]);
it("should invoke the hook on the plugin", async function() {
await lib.invokeHook(plugins, "test");
assert(betaTestCalled, "Hook was not called");
});
it("should pass and return args", async function() {
let result = await lib.invokeHook(plugins, "pass", 1234);
assert.deepEqual(result, [1234]);
});
it("should ignore errors", async function() {
await lib.invokeHook(plugins, "error");
});
});
});