test: guard session hook mock calls

This commit is contained in:
Peter Steinberger
2026-05-12 05:13:58 +01:00
parent e35bc01ade
commit be233081e2

View File

@@ -145,6 +145,24 @@ function expectFields(value: unknown, expected: Record<string, unknown>): void {
}
}
function requireHookCall(
mock: ReturnType<typeof vi.fn>,
label: string,
): readonly [Record<string, unknown>, Record<string, unknown> | undefined] {
const call = mock.mock.calls.at(0);
if (!call) {
throw new Error(`expected ${label} hook call`);
}
const [event, context] = call;
if (!event || typeof event !== "object") {
throw new Error(`expected ${label} hook event`);
}
if (context !== undefined && (!context || typeof context !== "object")) {
throw new Error(`expected ${label} hook context`);
}
return [event as Record<string, unknown>, context as Record<string, unknown> | undefined];
}
describe("session hook context wiring", () => {
beforeEach(() => {
hookRunnerMocks.hasHooks.mockReset();
@@ -177,7 +195,7 @@ describe("session hook context wiring", () => {
});
expect(hookRunnerMocks.runSessionStart).toHaveBeenCalledTimes(1);
const [event, context] = hookRunnerMocks.runSessionStart.mock.calls[0] ?? [];
const [event, context] = requireHookCall(hookRunnerMocks.runSessionStart, "session_start");
expectFields(event, { sessionKey });
expectFields(context, { sessionKey, agentId: "main", sessionId: event?.sessionId });
});
@@ -199,7 +217,7 @@ describe("session hook context wiring", () => {
expect(hookRunnerMocks.runSessionEnd).toHaveBeenCalledTimes(1);
expect(hookRunnerMocks.runSessionStart).toHaveBeenCalledTimes(1);
const [event, context] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [event, context] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
expectFields(event, {
sessionKey,
reason: "new",
@@ -208,7 +226,10 @@ describe("session hook context wiring", () => {
expectFields(context, { sessionKey, agentId: "main", sessionId: event?.sessionId });
expect(event?.sessionFile).toContain(".jsonl.reset.");
const [startEvent, startContext] = hookRunnerMocks.runSessionStart.mock.calls[0] ?? [];
const [startEvent, startContext] = requireHookCall(
hookRunnerMocks.runSessionStart,
"session_start",
);
expectFields(startEvent, { resumedFrom: "old-session" });
expect(event?.nextSessionId).toBe(startEvent?.sessionId);
expectFields(startContext, { sessionId: startEvent?.sessionId });
@@ -230,7 +251,7 @@ describe("session hook context wiring", () => {
commandAuthorized: true,
});
const [event] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [event] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
expectFields(event, { reason: "reset" });
});
@@ -255,7 +276,7 @@ describe("session hook context wiring", () => {
commandAuthorized: true,
});
const [event] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [event] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
expectFields(event, { reason: "new" });
});
@@ -272,8 +293,8 @@ describe("session hook context wiring", () => {
updatedAt: new Date(2026, 0, 18, 3, 0, 0).getTime(),
});
const [event] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [startEvent] = hookRunnerMocks.runSessionStart.mock.calls[0] ?? [];
const [event] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
const [startEvent] = requireHookCall(hookRunnerMocks.runSessionStart, "session_start");
expectFields(event, {
reason: "daily",
transcriptArchived: true,
@@ -302,7 +323,7 @@ describe("session hook context wiring", () => {
},
});
const [event] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [event] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
expectFields(event, { reason: "idle" });
} finally {
vi.useRealTimers();
@@ -327,7 +348,7 @@ describe("session hook context wiring", () => {
},
});
const [event] = hookRunnerMocks.runSessionEnd.mock.calls[0] ?? [];
const [event] = requireHookCall(hookRunnerMocks.runSessionEnd, "session_end");
expectFields(event, { reason: "idle" });
} finally {
vi.useRealTimers();