test(agents): share approval abort helper

This commit is contained in:
Vincent Koc
2026-04-12 11:14:11 +01:00
parent c185335817
commit 5959c9927e

View File

@@ -365,6 +365,28 @@ describe("before_tool_call requireApproval handling", () => {
mockCallGateway.mockReset();
});
async function runAbortDuringApprovalWait(options?: { onResolution?: ReturnType<typeof vi.fn> }) {
hookRunner.runBeforeToolCall.mockResolvedValue({
requireApproval: {
title: "Abortable",
description: "Will be aborted",
onResolution: options?.onResolution,
},
});
const controller = new AbortController();
mockCallGateway.mockResolvedValueOnce({ id: "server-id-abort", status: "accepted" });
mockCallGateway.mockImplementationOnce(() => new Promise(() => {}));
setTimeout(() => controller.abort(new Error("run cancelled")), 10);
return await runBeforeToolCallHook({
toolName: "bash",
params: {},
ctx: { agentId: "main", sessionKey: "main" },
signal: controller.signal,
});
}
it("blocks without triggering approval when both block and requireApproval are set", async () => {
hookRunner.runBeforeToolCall.mockResolvedValue({
block: true,
@@ -574,31 +596,7 @@ describe("before_tool_call requireApproval handling", () => {
});
it("unblocks immediately when abort signal fires during waitDecision", async () => {
hookRunner.runBeforeToolCall.mockResolvedValue({
requireApproval: {
title: "Abortable",
description: "Will be aborted",
},
});
const controller = new AbortController();
// First call: plugin.approval.request → accepted
mockCallGateway.mockResolvedValueOnce({ id: "server-id-abort", status: "accepted" });
// Second call: plugin.approval.waitDecision → never resolves (simulates long wait)
mockCallGateway.mockImplementationOnce(
() => new Promise(() => {}), // hangs forever
);
// Abort after a short delay
setTimeout(() => controller.abort(new Error("run cancelled")), 10);
const result = await runBeforeToolCallHook({
toolName: "bash",
params: {},
ctx: { agentId: "main", sessionKey: "main" },
signal: controller.signal,
});
const result = await runAbortDuringApprovalWait();
expect(result.blocked).toBe(true);
expect(result).toHaveProperty("reason", "Approval cancelled (run aborted)");
@@ -767,30 +765,7 @@ describe("before_tool_call requireApproval handling", () => {
it("calls onResolution with cancelled when abort signal fires", async () => {
const onResolution = vi.fn();
hookRunner.runBeforeToolCall.mockResolvedValue({
requireApproval: {
title: "Abortable with callback",
description: "Will be aborted",
onResolution,
},
});
const controller = new AbortController();
mockCallGateway.mockResolvedValueOnce({ id: "server-id-r5", status: "accepted" });
mockCallGateway.mockImplementationOnce(
() => new Promise(() => {}), // hangs forever
);
setTimeout(() => controller.abort(new Error("run cancelled")), 10);
const result = await runBeforeToolCallHook({
toolName: "bash",
params: {},
ctx: { agentId: "main", sessionKey: "main" },
signal: controller.signal,
});
const result = await runAbortDuringApprovalWait({ onResolution });
expect(result.blocked).toBe(true);
expect(result).toHaveProperty("reason", "Approval cancelled (run aborted)");