import { afterEach, describe, expect, it, vi } from "vitest"; import type { ClawdbotConfig } from "../config/config.js"; import { createExecApprovalForwarder } from "./exec-approval-forwarder.js"; const baseRequest = { id: "req-1", request: { command: "echo hello", agentId: "main", sessionKey: "agent:main:main", }, createdAtMs: 1000, expiresAtMs: 6000, }; afterEach(() => { vi.useRealTimers(); }); describe("exec approval forwarder", () => { it("forwards to session target and resolves", async () => { vi.useFakeTimers(); const deliver = vi.fn().mockResolvedValue([]); const cfg = { approvals: { exec: { enabled: true, mode: "session" } }, } as ClawdbotConfig; const forwarder = createExecApprovalForwarder({ getConfig: () => cfg, deliver, nowMs: () => 1000, resolveSessionTarget: () => ({ channel: "slack", to: "U1" }), }); await forwarder.handleRequested(baseRequest); expect(deliver).toHaveBeenCalledTimes(1); await forwarder.handleResolved({ id: baseRequest.id, decision: "allow-once", resolvedBy: "slack:U1", ts: 2000, }); expect(deliver).toHaveBeenCalledTimes(2); await vi.runAllTimersAsync(); expect(deliver).toHaveBeenCalledTimes(2); }); it("forwards to explicit targets and expires", async () => { vi.useFakeTimers(); const deliver = vi.fn().mockResolvedValue([]); const cfg = { approvals: { exec: { enabled: true, mode: "targets", targets: [{ channel: "telegram", to: "123" }], }, }, } as ClawdbotConfig; const forwarder = createExecApprovalForwarder({ getConfig: () => cfg, deliver, nowMs: () => 1000, resolveSessionTarget: () => null, }); await forwarder.handleRequested(baseRequest); expect(deliver).toHaveBeenCalledTimes(1); await vi.runAllTimersAsync(); expect(deliver).toHaveBeenCalledTimes(2); }); });