From 109d4ac720d84cf2917e8ccb02b39733631ac21c Mon Sep 17 00:00:00 2001 From: masonxhuang Date: Wed, 1 Apr 2026 17:45:39 +0800 Subject: [PATCH] test: cover forced-unsafe security scan failures --- src/cli/plugins-cli.install.test.ts | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/cli/plugins-cli.install.test.ts b/src/cli/plugins-cli.install.test.ts index dc5d4eb546d..d4e077b866d 100644 --- a/src/cli/plugins-cli.install.test.ts +++ b/src/cli/plugins-cli.install.test.ts @@ -779,6 +779,35 @@ describe("plugins cli install", () => { expect(runtimeErrors.at(-1)).toContain(pluginInstallError); }); + it("does not fall back to hook pack for local path when security scan fails under dangerous force unsafe install", async () => { + const localPluginDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-local-plugin-")); + const cfg = {} as OpenClawConfig; + const pluginInstallError = "plugin security scan failed"; + + loadConfig.mockReturnValue(cfg); + installPluginFromPath.mockResolvedValue({ + ok: false, + error: pluginInstallError, + code: "security_scan_failed", + }); + + try { + await expect( + runPluginsCommand([ + "plugins", + "install", + localPluginDir, + "--dangerously-force-unsafe-install", + ]), + ).rejects.toThrow("__exit__:1"); + } finally { + fs.rmSync(localPluginDir, { recursive: true, force: true }); + } + + expect(installHooksFromPath).not.toHaveBeenCalled(); + expect(runtimeErrors.at(-1)).toContain(pluginInstallError); + }); + it("does not fall back to hook pack for npm installs when dangerous force unsafe install is set", async () => { const cfg = {} as OpenClawConfig; const pluginInstallError = "plugin blocked by security scan"; @@ -803,6 +832,30 @@ describe("plugins cli install", () => { expect(runtimeErrors.at(-1)).toContain(pluginInstallError); }); + it("does not fall back to hook pack for npm installs when security scan fails under dangerous force unsafe install", async () => { + const cfg = {} as OpenClawConfig; + const pluginInstallError = "plugin security scan failed"; + + loadConfig.mockReturnValue(cfg); + installPluginFromClawHub.mockResolvedValue({ + ok: false, + error: "ClawHub /api/v1/packages/demo failed (404): Package not found", + code: "package_not_found", + }); + installPluginFromNpmSpec.mockResolvedValue({ + ok: false, + error: pluginInstallError, + code: "security_scan_failed", + }); + + await expect( + runPluginsCommand(["plugins", "install", "demo", "--dangerously-force-unsafe-install"]), + ).rejects.toThrow("__exit__:1"); + + expect(installHooksFromNpmSpec).not.toHaveBeenCalled(); + expect(runtimeErrors.at(-1)).toContain(pluginInstallError); + }); + it("still falls back to local hook pack when dangerous force unsafe install is set for non-security errors", async () => { const localHookDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-local-hook-pack-")); const cfg = {} as OpenClawConfig;