mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
test: speed up auto reply command tests
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { EffectiveToolInventoryResult } from "../../agents/tools-effective-inventory.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||
import {
|
||||
@@ -6,92 +7,106 @@ import {
|
||||
createTestRegistry,
|
||||
} from "../../test-utils/channel-plugins.js";
|
||||
|
||||
async function loadToolsHarness(options?: {
|
||||
resolveToolsMock?: ReturnType<typeof vi.fn>;
|
||||
resolveTools?: () => {
|
||||
agentId: string;
|
||||
profile: string;
|
||||
groups: Array<{
|
||||
id: "core" | "plugin" | "channel";
|
||||
label: string;
|
||||
source: "core" | "plugin" | "channel";
|
||||
pluginId?: string;
|
||||
channelId?: string;
|
||||
tools: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
source: "core" | "plugin" | "channel";
|
||||
pluginId?: string;
|
||||
channelId?: string;
|
||||
}>;
|
||||
}>;
|
||||
};
|
||||
function makeInventoryEntry(params: {
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
source: "core" | "plugin" | "channel";
|
||||
pluginId?: string;
|
||||
channelId?: string;
|
||||
}) {
|
||||
vi.resetModules();
|
||||
vi.doMock("../../agents/agent-scope.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../agents/agent-scope.js")>(
|
||||
"../../agents/agent-scope.js",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
resolveSessionAgentId: () => "main",
|
||||
};
|
||||
});
|
||||
const resolveToolsMock =
|
||||
options?.resolveToolsMock ??
|
||||
vi.fn(
|
||||
options?.resolveTools ??
|
||||
(() => ({
|
||||
agentId: "main",
|
||||
profile: "coding",
|
||||
groups: [
|
||||
{
|
||||
id: "core" as const,
|
||||
label: "Built-in tools",
|
||||
source: "core" as const,
|
||||
tools: [
|
||||
{
|
||||
id: "exec",
|
||||
label: "Exec",
|
||||
description: "Run shell commands",
|
||||
source: "core" as const,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "plugin" as const,
|
||||
label: "Connected tools",
|
||||
source: "plugin" as const,
|
||||
tools: [
|
||||
{
|
||||
id: "docs_lookup",
|
||||
label: "Docs Lookup",
|
||||
description: "Search internal documentation",
|
||||
source: "plugin" as const,
|
||||
pluginId: "docs",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})),
|
||||
);
|
||||
vi.doMock("../../agents/tools-effective-inventory.js", () => ({
|
||||
resolveEffectiveToolInventory: resolveToolsMock,
|
||||
}));
|
||||
vi.doMock("./agent-runner-utils.js", () => ({
|
||||
buildThreadingToolContext: () => ({
|
||||
return {
|
||||
...params,
|
||||
rawDescription: params.description,
|
||||
};
|
||||
}
|
||||
|
||||
function makeDefaultInventory(): EffectiveToolInventoryResult {
|
||||
return {
|
||||
agentId: "main",
|
||||
profile: "coding",
|
||||
groups: [
|
||||
{
|
||||
id: "core",
|
||||
label: "Built-in tools",
|
||||
source: "core",
|
||||
tools: [
|
||||
makeInventoryEntry({
|
||||
id: "exec",
|
||||
label: "Exec",
|
||||
description: "Run shell commands",
|
||||
source: "core",
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "plugin",
|
||||
label: "Connected tools",
|
||||
source: "plugin",
|
||||
tools: [
|
||||
makeInventoryEntry({
|
||||
id: "docs_lookup",
|
||||
label: "Docs Lookup",
|
||||
description: "Search internal documentation",
|
||||
source: "plugin",
|
||||
pluginId: "docs",
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
const toolsTestState = vi.hoisted(() => {
|
||||
const defaultResolveTools = (): EffectiveToolInventoryResult => makeDefaultInventory();
|
||||
|
||||
return {
|
||||
resolveToolsImpl: defaultResolveTools,
|
||||
resolveToolsMock: vi.fn((..._args: unknown[]) => defaultResolveTools()),
|
||||
threadingContext: {
|
||||
currentChannelId: "channel-123",
|
||||
currentMessageId: "message-456",
|
||||
}),
|
||||
}));
|
||||
vi.doMock("./reply-threading.js", () => ({
|
||||
resolveReplyToMode: () => "all",
|
||||
}));
|
||||
},
|
||||
replyToMode: "all" as const,
|
||||
};
|
||||
});
|
||||
|
||||
const { buildCommandTestParams } = await import("./commands.test-harness.js");
|
||||
const { handleToolsCommand } = await import("./commands-info.js");
|
||||
return { buildCommandTestParams, handleToolsCommand, resolveToolsMock };
|
||||
vi.mock("../../agents/agent-scope.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../agents/agent-scope.js")>(
|
||||
"../../agents/agent-scope.js",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
resolveSessionAgentId: () => "main",
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../agents/tools-effective-inventory.js", () => ({
|
||||
resolveEffectiveToolInventory: (...args: unknown[]) => toolsTestState.resolveToolsMock(...args),
|
||||
}));
|
||||
|
||||
vi.mock("./agent-runner-utils.js", () => ({
|
||||
buildThreadingToolContext: () => toolsTestState.threadingContext,
|
||||
}));
|
||||
|
||||
vi.mock("./reply-threading.js", () => ({
|
||||
resolveReplyToMode: () => toolsTestState.replyToMode,
|
||||
}));
|
||||
|
||||
let buildCommandTestParams: typeof import("./commands.test-harness.js").buildCommandTestParams;
|
||||
let handleToolsCommand: typeof import("./commands-info.js").handleToolsCommand;
|
||||
|
||||
async function loadToolsHarness(options?: { resolveTools?: () => EffectiveToolInventoryResult }) {
|
||||
toolsTestState.resolveToolsImpl = options?.resolveTools ?? (() => makeDefaultInventory());
|
||||
toolsTestState.resolveToolsMock.mockImplementation((..._args: unknown[]) =>
|
||||
toolsTestState.resolveToolsImpl(),
|
||||
);
|
||||
|
||||
return {
|
||||
buildCommandTestParams,
|
||||
handleToolsCommand,
|
||||
resolveToolsMock: toolsTestState.resolveToolsMock,
|
||||
};
|
||||
}
|
||||
|
||||
function buildConfig() {
|
||||
@@ -102,6 +117,17 @@ function buildConfig() {
|
||||
}
|
||||
|
||||
describe("handleToolsCommand", () => {
|
||||
beforeAll(async () => {
|
||||
({ buildCommandTestParams } = await import("./commands.test-harness.js"));
|
||||
({ handleToolsCommand } = await import("./commands-info.js"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
toolsTestState.resolveToolsMock.mockReset();
|
||||
toolsTestState.resolveToolsImpl = () => makeDefaultInventory();
|
||||
setActivePluginRegistry(createTestRegistry([]));
|
||||
});
|
||||
|
||||
it("renders a product-facing tool list", async () => {
|
||||
const { buildCommandTestParams, handleToolsCommand, resolveToolsMock } =
|
||||
await loadToolsHarness();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { importFreshModule } from "../../../test/helpers/import-fresh.ts";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { SessionBindingRecord } from "../../infra/outbound/session-binding-service.js";
|
||||
import type { HandleCommandsParams } from "./commands-types.js";
|
||||
@@ -487,8 +486,13 @@ function expectIdleTimeoutSetReply(
|
||||
}
|
||||
|
||||
describe("/session idle and /session max-age", () => {
|
||||
beforeEach(async () => {
|
||||
if (!handleSessionCommand) {
|
||||
({ handleSessionCommand } = await import("./commands-session.js"));
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
hoisted.setThreadBindingIdleTimeoutBySessionKeyMock.mockReset();
|
||||
hoisted.setThreadBindingMaxAgeBySessionKeyMock.mockReset();
|
||||
hoisted.setMatrixThreadBindingIdleTimeoutBySessionKeyMock.mockReset();
|
||||
@@ -499,13 +503,6 @@ describe("/session idle and /session max-age", () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
({ handleSessionCommand } = await importFreshModule<typeof import("./commands-session.js")>(
|
||||
import.meta.url,
|
||||
"./commands-session.js?scope=commands-session-lifecycle",
|
||||
));
|
||||
});
|
||||
|
||||
it("sets idle timeout for the focused thread-chat session", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-02-20T00:00:00.000Z"));
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
let listSkillCommandsForAgents: typeof import("./skill-commands.js").listSkillCommandsForAgents;
|
||||
let listSkillCommandsForWorkspace: typeof import("./skill-commands.js").listSkillCommandsForWorkspace;
|
||||
let resolveSkillCommandInvocation: typeof import("./skill-commands.js").resolveSkillCommandInvocation;
|
||||
let skillCommandsTesting: typeof import("./skill-commands.js").__testing;
|
||||
|
||||
type SkillCommandMockRegistrar = (path: string, factory: () => unknown) => void;
|
||||
|
||||
function resolveUniqueSkillCommandName(base: string, used: Set<string>): string {
|
||||
let name = base;
|
||||
let suffix = 2;
|
||||
@@ -82,39 +80,29 @@ function buildWorkspaceSkillCommandSpecs(
|
||||
});
|
||||
}
|
||||
|
||||
function installSkillCommandTestMocks(registerMock: SkillCommandMockRegistrar) {
|
||||
// Avoid importing the full chat command registry for reserved-name calculation.
|
||||
registerMock("./commands-registry.js", () => ({
|
||||
listChatCommands: () => [],
|
||||
}));
|
||||
vi.mock("./commands-registry.js", () => ({
|
||||
listChatCommands: () => [],
|
||||
}));
|
||||
|
||||
registerMock("../infra/skills-remote.js", () => ({
|
||||
getRemoteSkillEligibility: () => ({}),
|
||||
}));
|
||||
vi.mock("../infra/skills-remote.js", () => ({
|
||||
getRemoteSkillEligibility: () => ({}),
|
||||
}));
|
||||
|
||||
// Avoid filesystem-driven skill scanning for these unit tests; we only need command naming semantics.
|
||||
registerMock("../agents/skills.js", () => ({
|
||||
buildWorkspaceSkillCommandSpecs,
|
||||
}));
|
||||
}
|
||||
vi.mock("../agents/skills.js", () => ({
|
||||
buildWorkspaceSkillCommandSpecs,
|
||||
}));
|
||||
|
||||
const registerDynamicSkillCommandMock: SkillCommandMockRegistrar = (modulePath, factory) => {
|
||||
vi.doMock(modulePath, factory as Parameters<typeof vi.doMock>[1]);
|
||||
};
|
||||
|
||||
async function loadFreshSkillCommandsModuleForTest() {
|
||||
vi.resetModules();
|
||||
installSkillCommandTestMocks(registerDynamicSkillCommandMock);
|
||||
beforeAll(async () => {
|
||||
({
|
||||
listSkillCommandsForAgents,
|
||||
listSkillCommandsForWorkspace,
|
||||
resolveSkillCommandInvocation,
|
||||
__testing: skillCommandsTesting,
|
||||
} = await import("./skill-commands.js"));
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await loadFreshSkillCommandsModuleForTest();
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("resolveSkillCommandInvocation", () => {
|
||||
|
||||
Reference in New Issue
Block a user