From f43e0065292aa271aa161b71cffd35e94edbc9af Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 20 Apr 2026 18:51:02 +0100 Subject: [PATCH] perf(test): mock plugin trust audit deps --- src/security/audit-plugins-trust.test.ts | 61 +++++++++++++++--------- src/security/audit-plugins-trust.ts | 8 ++-- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/security/audit-plugins-trust.test.ts b/src/security/audit-plugins-trust.test.ts index 6891bf93049..8a7062d7943 100644 --- a/src/security/audit-plugins-trust.test.ts +++ b/src/security/audit-plugins-trust.test.ts @@ -18,6 +18,41 @@ const mockChannelPlugins = vi.hoisted(() => [ }, ]); +const readInstalledPackageVersionMock = vi.hoisted(() => + vi.fn(async (dir: string) => { + if (dir.includes("/extensions/voice-call") || dir.includes("\\extensions\\voice-call")) { + return "9.9.9"; + } + if (dir.includes("/hooks/test-hooks") || dir.includes("\\hooks\\test-hooks")) { + return "8.8.8"; + } + return undefined; + }), +); + +vi.mock("../infra/package-update-utils.js", () => ({ + readInstalledPackageVersion: readInstalledPackageVersionMock, +})); + +vi.mock("../plugins/config-state.js", () => ({ + normalizePluginId: (id: string) => id, + normalizePluginsConfig: ( + config: + | { + allow?: string[]; + deny?: string[]; + enabled?: boolean; + entries?: Record; + } + | undefined, + ) => ({ + allow: config?.allow ?? [], + deny: config?.deny ?? [], + enabled: config?.enabled !== false, + entries: config?.entries ?? {}, + }), +})); + vi.mock("../channels/plugins/index.js", () => ({ getChannelPlugin: (id: string) => mockChannelPlugins.find((plugin) => plugin.id === id), getLoadedChannelPlugin: () => undefined, @@ -133,25 +168,8 @@ describe("security audit install metadata findings", () => { }, { name: "warns when install records drift from installed package versions", - run: async () => { - const tmp = await makeTmpDir("install-version-drift"); - const stateDir = path.join(tmp, "state"); - const pluginDir = path.join(stateDir, "extensions", "voice-call"); - const hookDir = path.join(stateDir, "hooks", "test-hooks"); - await fs.mkdir(pluginDir, { recursive: true }); - await fs.mkdir(hookDir, { recursive: true }); - await fs.writeFile( - path.join(pluginDir, "package.json"), - JSON.stringify({ name: "@openclaw/voice-call", version: "9.9.9" }), - "utf-8", - ); - await fs.writeFile( - path.join(hookDir, "package.json"), - JSON.stringify({ name: "@openclaw/test-hooks", version: "8.8.8" }), - "utf-8", - ); - - return runInstallMetadataAudit( + run: async () => + runInstallMetadataAudit( { plugins: { installs: { @@ -176,9 +194,8 @@ describe("security audit install metadata findings", () => { }, }, }, - stateDir, - ); - }, + sharedInstallMetadataStateDir, + ), expectedPresent: ["plugins.installs_version_drift", "hooks.installs_version_drift"], }, ]; diff --git a/src/security/audit-plugins-trust.ts b/src/security/audit-plugins-trust.ts index eb5954746e8..6301d995ada 100644 --- a/src/security/audit-plugins-trust.ts +++ b/src/security/audit-plugins-trust.ts @@ -8,7 +8,6 @@ import type { AgentToolsConfig } from "../config/types.tools.js"; import { readInstalledPackageVersion } from "../infra/package-update-utils.js"; import { normalizePluginId, normalizePluginsConfig } from "../plugins/config-state.js"; import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; -import { safeStat } from "./audit-fs.js"; import type { SecurityAuditFinding } from "./audit.types.js"; type SandboxToolPolicy = import("../agents/sandbox/types.js").SandboxToolPolicy; @@ -125,8 +124,11 @@ async function listInstalledPluginDirs(params: { onReadError?: (error: unknown) => void; }): Promise<{ extensionsDir: string; pluginDirs: string[] }> { const extensionsDir = path.join(params.stateDir, "extensions"); - const st = await safeStat(extensionsDir); - if (!st.ok || !st.isDir) { + const st = await fs.stat(extensionsDir).catch((err: unknown) => { + params.onReadError?.(err); + return null; + }); + if (!st?.isDirectory()) { return { extensionsDir, pluginDirs: [] }; } const entries = await fs.readdir(extensionsDir, { withFileTypes: true }).catch((err) => {