test(plugins): cover bundled dependency edge cases

This commit is contained in:
Vincent Koc
2026-04-26 20:30:45 -07:00
parent 4878d3e059
commit f60378519c
3 changed files with 99 additions and 4 deletions

View File

@@ -97,6 +97,21 @@ describe("command-path-policy", () => {
hideBanner: true,
ensureCliPath: true,
});
for (const commandPath of [
["plugins", "install"],
["plugins", "list"],
["plugins", "inspect"],
["plugins", "registry"],
["plugins", "doctor"],
]) {
expect(resolveCliCommandPathPolicy(commandPath)).toEqual({
bypassConfigGuard: false,
routeConfigGuard: "never",
loadPlugins: "never",
hideBanner: false,
ensureCliPath: true,
});
}
expect(resolveCliCommandPathPolicy(["cron", "list"])).toEqual({
bypassConfigGuard: true,
routeConfigGuard: "never",

View File

@@ -174,8 +174,17 @@ describe("registerSubCliCommands", () => {
expect(acpAction).toHaveBeenCalledTimes(1);
});
it("does not preload plugin CLI registrations for builtin plugins update", async () => {
process.argv = ["node", "openclaw", "plugins", "update", "lossless-claw"];
it.each([
["plugins update", ["plugins", "update", "lossless-claw"]],
["plugins update --all", ["plugins", "update", "--all"]],
["plugins install", ["plugins", "install", "lossless-claw"]],
["plugins list", ["plugins", "list"]],
["plugins inspect", ["plugins", "inspect", "lossless-claw"]],
["plugins registry --refresh", ["plugins", "registry", "--refresh"]],
["plugins doctor", ["plugins", "doctor"]],
["plugins --help", ["plugins", "--help"]],
])("does not preload plugin CLI registrations for builtin %s", async (_label, args) => {
process.argv = ["node", "openclaw", ...args];
const program = new Command().name("openclaw");
await registerSubCliByName(program, "plugins");

View File

@@ -613,6 +613,13 @@ describe("installBundledRuntimeDeps", () => {
});
describe("scanBundledPluginRuntimeDeps config policy", () => {
type RuntimeDepsConfigCase = {
name: string;
config: Parameters<typeof scanBundledPluginRuntimeDeps>[0]["config"];
includeConfiguredChannels: boolean;
expectedDeps: string[];
};
function setupPolicyPackageRoot(): string {
const packageRoot = makeTempDir();
writeBundledPluginPackage({
@@ -630,7 +637,7 @@ describe("scanBundledPluginRuntimeDeps config policy", () => {
return packageRoot;
}
it.each([
const cases: RuntimeDepsConfigCase[] = [
{
name: "includes default-enabled bundled plugins",
config: {},
@@ -661,6 +668,33 @@ describe("scanBundledPluginRuntimeDeps config policy", () => {
includeConfiguredChannels: false,
expectedDeps: [],
},
{
name: "lets plugin deny override explicit bundled channel enablement",
config: {
plugins: { deny: ["telegram"] },
channels: { telegram: { enabled: true } },
},
includeConfiguredChannels: false,
expectedDeps: ["alpha-runtime@1.0.0"],
},
{
name: "lets the plugin master toggle suppress explicit bundled channel enablement",
config: {
plugins: { enabled: false },
channels: { telegram: { enabled: true } },
},
includeConfiguredChannels: false,
expectedDeps: [],
},
{
name: "lets plugin entry disablement override explicit bundled channel enablement",
config: {
plugins: { entries: { telegram: { enabled: false } } },
channels: { telegram: { enabled: true } },
},
includeConfiguredChannels: false,
expectedDeps: ["alpha-runtime@1.0.0"],
},
{
name: "lets explicit bundled channel enablement bypass restrictive allowlists",
config: {
@@ -691,7 +725,9 @@ describe("scanBundledPluginRuntimeDeps config policy", () => {
includeConfiguredChannels: true,
expectedDeps: ["alpha-runtime@1.0.0"],
},
])("$name", ({ config, includeConfiguredChannels, expectedDeps }) => {
];
it.each(cases)("$name", ({ config, includeConfiguredChannels, expectedDeps }) => {
const result = scanBundledPluginRuntimeDeps({
packageRoot: setupPolicyPackageRoot(),
config,
@@ -702,6 +738,41 @@ describe("scanBundledPluginRuntimeDeps config policy", () => {
expect(result.conflicts).toEqual([]);
});
it("honors deny and disabled entries when scanning an explicit effective plugin set", () => {
const packageRoot = setupPolicyPackageRoot();
const denied = scanBundledPluginRuntimeDeps({
packageRoot,
pluginIds: ["telegram"],
config: {
plugins: { deny: ["telegram"] },
channels: { telegram: { enabled: true } },
},
});
const disabled = scanBundledPluginRuntimeDeps({
packageRoot,
pluginIds: ["telegram"],
config: {
plugins: { entries: { telegram: { enabled: false } } },
channels: { telegram: { enabled: true } },
},
});
const allowed = scanBundledPluginRuntimeDeps({
packageRoot,
pluginIds: ["telegram"],
config: {
plugins: { entries: { telegram: { enabled: true } } },
channels: { telegram: { enabled: true } },
},
});
expect(denied.deps).toEqual([]);
expect(disabled.deps).toEqual([]);
expect(allowed.deps.map((dep) => `${dep.name}@${dep.version}`)).toEqual([
"telegram-runtime@2.0.0",
]);
});
it("reads each bundled plugin manifest once per runtime-deps scan", () => {
const packageRoot = makeTempDir();
const pluginRoot = writeBundledPluginPackage({