perf: tighten auto-reply command tests

This commit is contained in:
Peter Steinberger
2026-04-24 07:22:03 +01:00
parent 37c37eecfb
commit ad0fcf9143
3 changed files with 64 additions and 197 deletions

View File

@@ -1,5 +1,5 @@
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { TemplateContext } from "../templating.js";
import type { FollowupRun, QueueSettings } from "./queue.js";
import { createMockFollowupRun, createMockTypingController } from "./test-helpers.js";
@@ -117,8 +117,11 @@ function makeRunReplyAgentParams(
}
describe("runReplyAgent media path normalization", () => {
beforeEach(async () => {
vi.resetModules();
beforeAll(async () => {
({ runReplyAgent } = await import("./agent-runner.js"));
});
beforeEach(() => {
runEmbeddedPiAgentMock.mockReset();
runWithModelFallbackMock.mockReset();
abortEmbeddedPiRunMock.mockReset();
@@ -155,7 +158,6 @@ describe("runReplyAgent media path normalization", () => {
model,
}),
);
({ runReplyAgent } = await import("./agent-runner.js"));
});
afterEach(() => {

View File

@@ -191,6 +191,64 @@ describe("handlePluginsCommand", () => {
expect(result?.reply?.text).toContain("requires operator.admin");
});
it("enables and disables a discovered plugin", async () => {
validateConfigObjectWithPluginsMock.mockImplementation((next) => ({ ok: true, config: next }));
const enableParams = buildPluginsParams("/plugins enable superpowers", buildCfg());
enableParams.command.senderIsOwner = true;
const enableResult = await handlePluginsCommand(enableParams, true);
expect(enableResult?.reply?.text).toContain('Plugin "superpowers" enabled');
expect(writeConfigFileMock).toHaveBeenLastCalledWith(
expect.objectContaining({
plugins: expect.objectContaining({
entries: expect.objectContaining({
superpowers: expect.objectContaining({ enabled: true }),
}),
}),
}),
);
const disableParams = buildPluginsParams("/plugins disable superpowers", buildCfg());
disableParams.command.senderIsOwner = true;
const disableResult = await handlePluginsCommand(disableParams, true);
expect(disableResult?.reply?.text).toContain('Plugin "superpowers" disabled');
expect(writeConfigFileMock).toHaveBeenLastCalledWith(
expect.objectContaining({
plugins: expect.objectContaining({
entries: expect.objectContaining({
superpowers: expect.objectContaining({ enabled: false }),
}),
}),
}),
);
});
it("resolves write targets by runtime-derived plugin name", async () => {
buildPluginDiagnosticsReportMock.mockReturnValue({
workspaceDir: "/tmp/plugins-workspace",
plugins: [
{
id: "superpowers",
name: "Super Powers",
status: "disabled",
format: "openclaw",
bundleFormat: "claude",
},
],
});
validateConfigObjectWithPluginsMock.mockImplementation((next) => ({ ok: true, config: next }));
const params = buildPluginsParams("/plugins enable Super Powers", buildCfg());
params.command.senderIsOwner = true;
const result = await handlePluginsCommand(params, true);
expect(result?.reply?.text).toContain('Plugin "superpowers" enabled');
expect(buildPluginDiagnosticsReportMock).toHaveBeenCalled();
expect(buildPluginSnapshotReportMock).not.toHaveBeenCalled();
});
it("returns an explicit unauthorized reply for native /plugins list", async () => {
const params = buildPluginsParams("/plugins list", buildCfg());
params.command.senderIsOwner = false;

View File

@@ -1,193 +0,0 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { installedPluginRoot } from "../../../test/helpers/bundled-plugin-paths.js";
import { createPluginRecord, createPluginStatusReport } from "../../plugins/status.test-helpers.js";
const WORKSPACE_PLUGIN_ROOT = installedPluginRoot("/tmp/workspace/.openclaw", "superpowers");
const {
readConfigFileSnapshotMock,
validateConfigObjectWithPluginsMock,
writeConfigFileMock,
buildPluginSnapshotReportMock,
buildPluginDiagnosticsReportMock,
} = vi.hoisted(() => ({
readConfigFileSnapshotMock: vi.fn(),
validateConfigObjectWithPluginsMock: vi.fn(),
writeConfigFileMock: vi.fn(),
buildPluginSnapshotReportMock: vi.fn(),
buildPluginDiagnosticsReportMock: vi.fn(),
}));
vi.mock("../../config/config.js", async () => {
const actual =
await vi.importActual<typeof import("../../config/config.js")>("../../config/config.js");
return {
...actual,
readConfigFileSnapshot: readConfigFileSnapshotMock,
validateConfigObjectWithPlugins: validateConfigObjectWithPluginsMock,
writeConfigFile: writeConfigFileMock,
};
});
vi.mock("../../plugins/status.js", async () => {
const actual =
await vi.importActual<typeof import("../../plugins/status.js")>("../../plugins/status.js");
return {
...actual,
buildPluginSnapshotReport: buildPluginSnapshotReportMock,
buildPluginDiagnosticsReport: buildPluginDiagnosticsReportMock,
};
});
import { handleCommands } from "./commands-core.js";
import { buildCommandTestParams } from "./commands.test-harness.js";
function buildCfg() {
return {
plugins: {
enabled: true,
},
commands: {
text: true,
plugins: true,
},
};
}
describe("handleCommands /plugins toggle", () => {
afterEach(() => {
readConfigFileSnapshotMock.mockReset();
validateConfigObjectWithPluginsMock.mockReset();
writeConfigFileMock.mockReset();
buildPluginSnapshotReportMock.mockReset();
buildPluginDiagnosticsReportMock.mockReset();
});
it("enables a discovered plugin", async () => {
const config = buildCfg();
readConfigFileSnapshotMock.mockResolvedValue({
valid: true,
path: "/tmp/openclaw.json",
resolved: config,
});
buildPluginDiagnosticsReportMock.mockReturnValue(
createPluginStatusReport({
workspaceDir: "/tmp/workspace",
plugins: [
createPluginRecord({
id: "superpowers",
format: "bundle",
source: WORKSPACE_PLUGIN_ROOT,
enabled: false,
status: "disabled",
}),
],
}),
);
validateConfigObjectWithPluginsMock.mockImplementation((next) => ({ ok: true, config: next }));
writeConfigFileMock.mockResolvedValue(undefined);
const params = buildCommandTestParams("/plugins enable superpowers", buildCfg());
params.command.senderIsOwner = true;
const result = await handleCommands(params);
expect(result.reply?.text).toContain('Plugin "superpowers" enabled');
expect(writeConfigFileMock).toHaveBeenCalledWith(
expect.objectContaining({
plugins: expect.objectContaining({
entries: expect.objectContaining({
superpowers: expect.objectContaining({ enabled: true }),
}),
}),
}),
);
});
it("disables a discovered plugin", async () => {
const config = buildCfg();
readConfigFileSnapshotMock.mockResolvedValue({
valid: true,
path: "/tmp/openclaw.json",
resolved: config,
});
buildPluginDiagnosticsReportMock.mockReturnValue(
createPluginStatusReport({
workspaceDir: "/tmp/workspace",
plugins: [
createPluginRecord({
id: "superpowers",
format: "bundle",
source: WORKSPACE_PLUGIN_ROOT,
enabled: true,
}),
],
}),
);
validateConfigObjectWithPluginsMock.mockImplementation((next) => ({ ok: true, config: next }));
writeConfigFileMock.mockResolvedValue(undefined);
const params = buildCommandTestParams("/plugins disable superpowers", buildCfg());
params.command.senderIsOwner = true;
const result = await handleCommands(params);
expect(result.reply?.text).toContain('Plugin "superpowers" disabled');
expect(writeConfigFileMock).toHaveBeenCalledWith(
expect.objectContaining({
plugins: expect.objectContaining({
entries: expect.objectContaining({
superpowers: expect.objectContaining({ enabled: false }),
}),
}),
}),
);
});
it("resolves write targets by runtime-derived plugin name", async () => {
const config = buildCfg();
readConfigFileSnapshotMock.mockResolvedValue({
valid: true,
path: "/tmp/openclaw.json",
resolved: config,
});
buildPluginSnapshotReportMock.mockReturnValue(
createPluginStatusReport({
workspaceDir: "/tmp/workspace",
plugins: [
createPluginRecord({
id: "superpowers",
name: "superpowers",
format: "bundle",
source: WORKSPACE_PLUGIN_ROOT,
enabled: false,
status: "disabled",
}),
],
}),
);
buildPluginDiagnosticsReportMock.mockReturnValue(
createPluginStatusReport({
workspaceDir: "/tmp/workspace",
plugins: [
createPluginRecord({
id: "superpowers",
name: "Super Powers",
format: "bundle",
source: WORKSPACE_PLUGIN_ROOT,
enabled: false,
status: "disabled",
}),
],
}),
);
validateConfigObjectWithPluginsMock.mockImplementation((next) => ({ ok: true, config: next }));
writeConfigFileMock.mockResolvedValue(undefined);
const params = buildCommandTestParams("/plugins enable Super Powers", buildCfg());
params.command.senderIsOwner = true;
const result = await handleCommands(params);
expect(result.reply?.text).toContain('Plugin "superpowers" enabled');
expect(buildPluginDiagnosticsReportMock).toHaveBeenCalled();
expect(buildPluginSnapshotReportMock).not.toHaveBeenCalled();
});
});