mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-23 13:18:12 +00:00
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.
89 lines
2.8 KiB
TypeScript
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",
|
|
});
|
|
});
|
|
});
|