Files
openclaw/src/auto-reply/reply/commands-core.test.ts
Rai Butera b20b16965c test(hooks): cover reset hook agent id edge cases
Add regression coverage for the before_reset hook context when the
session key is undefined and when it targets the main agent session.
This documents the fallback contract around
resolveAgentIdFromSessionKey and protects the reset hook path from
future regressions.
2026-03-08 18:54:25 +03:00

89 lines
2.8 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { HookRunner } from "../../plugins/hooks.js";
import type { HandleCommandsParams } from "./commands-types.js";
const hookRunnerMocks = vi.hoisted(() => ({
hasHooks: vi.fn<HookRunner["hasHooks"]>(),
runBeforeReset: vi.fn<HookRunner["runBeforeReset"]>(),
}));
vi.mock("../../plugins/hook-runner-global.js", () => ({
getGlobalHookRunner: () =>
({
hasHooks: hookRunnerMocks.hasHooks,
runBeforeReset: hookRunnerMocks.runBeforeReset,
}) as unknown as HookRunner,
}));
const { emitResetCommandHooks } = await import("./commands-core.js");
describe("emitResetCommandHooks", () => {
async function runBeforeResetContext(sessionKey?: string) {
const command = {
surface: "discord",
senderId: "rai",
channel: "discord",
from: "discord:rai",
to: "discord:bot",
resetHookTriggered: false,
} as HandleCommandsParams["command"];
await emitResetCommandHooks({
action: "new",
ctx: {} as HandleCommandsParams["ctx"],
cfg: {} as HandleCommandsParams["cfg"],
command,
sessionKey,
previousSessionEntry: {
sessionId: "prev-session",
} as HandleCommandsParams["previousSessionEntry"],
workspaceDir: "/tmp/openclaw-workspace",
});
await vi.waitFor(() => expect(hookRunnerMocks.runBeforeReset).toHaveBeenCalledTimes(1));
const [, ctx] = hookRunnerMocks.runBeforeReset.mock.calls[0] ?? [];
return ctx;
}
beforeEach(() => {
hookRunnerMocks.hasHooks.mockReset();
hookRunnerMocks.runBeforeReset.mockReset();
hookRunnerMocks.hasHooks.mockImplementation((hookName) => hookName === "before_reset");
hookRunnerMocks.runBeforeReset.mockResolvedValue(undefined);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("passes the bound agent id to before_reset hooks for multi-agent session keys", async () => {
const ctx = await runBeforeResetContext("agent:navi:main");
expect(ctx).toMatchObject({
agentId: "navi",
sessionKey: "agent:navi:main",
sessionId: "prev-session",
workspaceDir: "/tmp/openclaw-workspace",
});
});
it("falls back to main when the reset hook has no session key", async () => {
const ctx = await runBeforeResetContext(undefined);
expect(ctx).toMatchObject({
agentId: "main",
sessionKey: undefined,
sessionId: "prev-session",
workspaceDir: "/tmp/openclaw-workspace",
});
});
it("keeps the main-agent path on the main agent workspace", async () => {
const ctx = await runBeforeResetContext("agent:main:main");
expect(ctx).toMatchObject({
agentId: "main",
sessionKey: "agent:main:main",
sessionId: "prev-session",
workspaceDir: "/tmp/openclaw-workspace",
});
});
});