diff --git a/src/auto-reply/reply/commands-filesystem.test-support.ts b/src/auto-reply/reply/commands-filesystem.test-support.ts new file mode 100644 index 00000000000..c4b3c45b559 --- /dev/null +++ b/src/auto-reply/reply/commands-filesystem.test-support.ts @@ -0,0 +1,20 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; + +export function createCommandWorkspaceHarness(prefix: string) { + const tempDirs: string[] = []; + + return { + async createWorkspace(): Promise { + const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix)); + tempDirs.push(dir); + return dir; + }, + async cleanupWorkspaces() { + await Promise.all( + tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })), + ); + }, + }; +} diff --git a/src/auto-reply/reply/commands-mcp.test.ts b/src/auto-reply/reply/commands-mcp.test.ts index 24d7f15f34b..f70f167a80b 100644 --- a/src/auto-reply/reply/commands-mcp.test.ts +++ b/src/auto-reply/reply/commands-mcp.test.ts @@ -1,19 +1,11 @@ -import fs from "node:fs/promises"; -import os from "node:os"; -import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import { withTempHome } from "../../config/home-env.test-harness.js"; import { handleCommands } from "./commands-core.js"; +import { createCommandWorkspaceHarness } from "./commands-filesystem.test-support.js"; import { buildCommandTestParams } from "./commands.test-harness.js"; -const tempDirs: string[] = []; - -async function createWorkspace(): Promise { - const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-command-mcp-")); - tempDirs.push(dir); - return dir; -} +const workspaceHarness = createCommandWorkspaceHarness("openclaw-command-mcp-"); function buildCfg(): OpenClawConfig { return { @@ -26,14 +18,12 @@ function buildCfg(): OpenClawConfig { describe("handleCommands /mcp", () => { afterEach(async () => { - await Promise.all( - tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })), - ); + await workspaceHarness.cleanupWorkspaces(); }); it("writes MCP config and shows it back", async () => { await withTempHome("openclaw-command-mcp-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); const setParams = buildCommandTestParams( '/mcp set context7={"command":"uvx","args":["context7-mcp"]}', buildCfg(), @@ -57,7 +47,7 @@ describe("handleCommands /mcp", () => { it("rejects internal writes without operator.admin", async () => { await withTempHome("openclaw-command-mcp-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); const params = buildCommandTestParams( '/mcp set context7={"command":"uvx","args":["context7-mcp"]}', buildCfg(), @@ -77,7 +67,7 @@ describe("handleCommands /mcp", () => { it("accepts non-stdio MCP config at the config layer", async () => { await withTempHome("openclaw-command-mcp-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); const params = buildCommandTestParams( '/mcp set remote={"url":"https://example.com/mcp"}', buildCfg(), diff --git a/src/auto-reply/reply/commands-plugins.test.ts b/src/auto-reply/reply/commands-plugins.test.ts index 133a8021d3c..1aeb184e5b7 100644 --- a/src/auto-reply/reply/commands-plugins.test.ts +++ b/src/auto-reply/reply/commands-plugins.test.ts @@ -1,19 +1,13 @@ import fs from "node:fs/promises"; -import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import { withTempHome } from "../../config/home-env.test-harness.js"; import { handleCommands } from "./commands-core.js"; +import { createCommandWorkspaceHarness } from "./commands-filesystem.test-support.js"; import { buildCommandTestParams } from "./commands.test-harness.js"; -const tempDirs: string[] = []; - -async function createWorkspace(): Promise { - const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-command-plugins-")); - tempDirs.push(dir); - return dir; -} +const workspaceHarness = createCommandWorkspaceHarness("openclaw-command-plugins-"); async function createClaudeBundlePlugin(params: { workspaceDir: string; pluginId: string }) { const pluginDir = path.join(params.workspaceDir, ".openclaw", "extensions", params.pluginId); @@ -38,14 +32,12 @@ function buildCfg(): OpenClawConfig { describe("handleCommands /plugins", () => { afterEach(async () => { - await Promise.all( - tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })), - ); + await workspaceHarness.cleanupWorkspaces(); }); it("lists discovered plugins and shows plugin details", async () => { await withTempHome("openclaw-command-plugins-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); await createClaudeBundlePlugin({ workspaceDir, pluginId: "superpowers" }); const listParams = buildCommandTestParams("/plugins list", buildCfg(), undefined, { @@ -69,7 +61,7 @@ describe("handleCommands /plugins", () => { it("enables and disables a discovered plugin", async () => { await withTempHome("openclaw-command-plugins-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); await createClaudeBundlePlugin({ workspaceDir, pluginId: "superpowers" }); const enableParams = buildCommandTestParams( @@ -113,7 +105,7 @@ describe("handleCommands /plugins", () => { it("rejects internal writes without operator.admin", async () => { await withTempHome("openclaw-command-plugins-home-", async () => { - const workspaceDir = await createWorkspace(); + const workspaceDir = await workspaceHarness.createWorkspace(); await createClaudeBundlePlugin({ workspaceDir, pluginId: "superpowers" }); const params = buildCommandTestParams(