diff --git a/src/cli/nodes-cli.coverage.test.ts b/src/cli/nodes-cli.coverage.test.ts index 1898549cd..44d108797 100644 --- a/src/cli/nodes-cli.coverage.test.ts +++ b/src/cli/nodes-cli.coverage.test.ts @@ -1,5 +1,5 @@ import { Command } from "commander"; -import { describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const callGateway = vi.fn(async (opts: { method?: string }) => { if (opts.method === "node.list") { @@ -75,13 +75,20 @@ vi.mock("../config/config.js", () => ({ })); describe("nodes-cli coverage", () => { - it("invokes system.run with parsed params", async () => { + let registerNodesCli: (program: Command) => void; + + beforeAll(async () => { + ({ registerNodesCli } = await import("./nodes-cli.js")); + }); + + beforeEach(() => { runtimeLogs.length = 0; runtimeErrors.length = 0; callGateway.mockClear(); randomIdempotencyKey.mockClear(); + }); - const { registerNodesCli } = await import("./nodes-cli.js"); + it("invokes system.run with parsed params", async () => { const program = new Command(); program.exitOverride(); registerNodesCli(program); @@ -126,12 +133,6 @@ describe("nodes-cli coverage", () => { }); it("invokes system.run with raw command", async () => { - runtimeLogs.length = 0; - runtimeErrors.length = 0; - callGateway.mockClear(); - randomIdempotencyKey.mockClear(); - - const { registerNodesCli } = await import("./nodes-cli.js"); const program = new Command(); program.exitOverride(); registerNodesCli(program); @@ -156,11 +157,6 @@ describe("nodes-cli coverage", () => { }); it("invokes system.notify with provided fields", async () => { - runtimeLogs.length = 0; - runtimeErrors.length = 0; - callGateway.mockClear(); - - const { registerNodesCli } = await import("./nodes-cli.js"); const program = new Command(); program.exitOverride(); registerNodesCli(program); @@ -195,11 +191,6 @@ describe("nodes-cli coverage", () => { }); it("invokes location.get with params", async () => { - runtimeLogs.length = 0; - runtimeErrors.length = 0; - callGateway.mockClear(); - - const { registerNodesCli } = await import("./nodes-cli.js"); const program = new Command(); program.exitOverride(); registerNodesCli(program); diff --git a/src/docker-setup.test.ts b/src/docker-setup.test.ts index 07b349c76..9bc47c82a 100644 --- a/src/docker-setup.test.ts +++ b/src/docker-setup.test.ts @@ -103,33 +103,23 @@ describe("docker-setup.sh", () => { expect(defaultsEnvFile).toContain("OPENCLAW_EXTRA_MOUNTS="); expect(defaultsEnvFile).toContain("OPENCLAW_HOME_VOLUME="); - const homeVolumeResult = spawnSync("bash", [sandbox.scriptPath], { + await writeFile(sandbox.logPath, ""); + const aptAndHomeVolumeResult = spawnSync("bash", [sandbox.scriptPath], { cwd: sandbox.rootDir, env: createEnv(sandbox, { + OPENCLAW_DOCKER_APT_PACKAGES: "ffmpeg build-essential", OPENCLAW_EXTRA_MOUNTS: "", OPENCLAW_HOME_VOLUME: "openclaw-home", }), encoding: "utf8", }); - expect(homeVolumeResult.status).toBe(0); + expect(aptAndHomeVolumeResult.status).toBe(0); + const aptEnvFile = await readFile(join(sandbox.rootDir, ".env"), "utf8"); + expect(aptEnvFile).toContain("OPENCLAW_DOCKER_APT_PACKAGES=ffmpeg build-essential"); const extraCompose = await readFile(join(sandbox.rootDir, "docker-compose.extra.yml"), "utf8"); expect(extraCompose).toContain("openclaw-home:/home/node"); expect(extraCompose).toContain("volumes:"); expect(extraCompose).toContain("openclaw-home:"); - - await writeFile(sandbox.logPath, ""); - const aptResult = spawnSync("bash", [sandbox.scriptPath], { - cwd: sandbox.rootDir, - env: createEnv(sandbox, { - OPENCLAW_DOCKER_APT_PACKAGES: "ffmpeg build-essential", - OPENCLAW_EXTRA_MOUNTS: "", - OPENCLAW_HOME_VOLUME: "", - }), - encoding: "utf8", - }); - expect(aptResult.status).toBe(0); - const aptEnvFile = await readFile(join(sandbox.rootDir, ".env"), "utf8"); - expect(aptEnvFile).toContain("OPENCLAW_DOCKER_APT_PACKAGES=ffmpeg build-essential"); const log = await readFile(sandbox.logPath, "utf8"); expect(log).toContain("--build-arg OPENCLAW_DOCKER_APT_PACKAGES=ffmpeg build-essential"); }); diff --git a/src/security/audit.test.ts b/src/security/audit.test.ts index be566016b..54adece00 100644 --- a/src/security/audit.test.ts +++ b/src/security/audit.test.ts @@ -4,15 +4,60 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { ChannelPlugin } from "../channels/plugins/types.js"; import type { OpenClawConfig } from "../config/config.js"; -import { discordPlugin } from "../../extensions/discord/src/channel.js"; -import { slackPlugin } from "../../extensions/slack/src/channel.js"; -import { telegramPlugin } from "../../extensions/telegram/src/channel.js"; import { collectPluginsCodeSafetyFindings } from "./audit-extra.js"; import { runSecurityAudit } from "./audit.js"; import * as skillScanner from "./skill-scanner.js"; const isWindows = process.platform === "win32"; +function stubChannelPlugin(params: { + id: "discord" | "slack" | "telegram"; + label: string; + resolveAccount: (cfg: OpenClawConfig) => unknown; +}): ChannelPlugin { + return { + id: params.id, + meta: { + id: params.id, + label: params.label, + selectionLabel: params.label, + docsPath: "/docs/testing", + blurb: "test stub", + }, + capabilities: { + chatTypes: ["dm", "group"], + }, + security: {}, + config: { + listAccountIds: (cfg) => { + const enabled = Boolean((cfg.channels as Record | undefined)?.[params.id]); + return enabled ? ["default"] : []; + }, + resolveAccount: (cfg) => params.resolveAccount(cfg), + isEnabled: () => true, + isConfigured: () => true, + }, + }; +} + +const discordPlugin = stubChannelPlugin({ + id: "discord", + label: "Discord", + resolveAccount: (cfg) => ({ config: cfg.channels?.discord ?? {} }), +}); + +const slackPlugin = stubChannelPlugin({ + id: "slack", + label: "Slack", + resolveAccount: (cfg) => ({ config: cfg.channels?.slack ?? {} }), +}); + +const telegramPlugin = stubChannelPlugin({ + id: "telegram", + label: "Telegram", + resolveAccount: (cfg) => ({ config: cfg.channels?.telegram ?? {} }), +}); + function successfulProbeResult(url: string) { return { ok: true,