import { beforeEach, describe, expect, it, vi } from "vitest"; // Mock @vercel/sandbox so runAgentTurn doesn't try to create real sandboxes const mockRunCommand = vi.fn(); const mockWriteFiles = vi.fn(); const mockStop = vi.fn(); const mockCreate = vi.fn().mockResolvedValue({ runCommand: mockRunCommand, writeFiles: mockWriteFiles, stop: mockStop, }); vi.mock("@vercel/sandbox", () => ({ Sandbox: { create: mockCreate }, })); function cmdResult(exitCode: number, stdoutStr: string, stderrStr = "") { return { exitCode, stdout: async () => stdoutStr, stderr: async () => stderrStr, }; } describe("handlers", () => { beforeEach(() => { vi.clearAllMocks(); process.env.SIGMA_MEMBER_WIF = "L1test"; process.env.ANTHROPIC_API_KEY = "sk-test"; // Default: script returns success mockRunCommand.mockImplementation(({ cmd, args }) => { if (cmd === "node" && args?.[0] === "agent.mjs") { return cmdResult( 0, JSON.stringify({ success: true, summary: "Agent completed", actions: [], }), ); } return cmdResult(0, ""); }); }); describe("handlePost", () => { it("runs agent with scheduled_post trigger", async () => { mockRunCommand.mockImplementation(({ cmd, args }) => { if (cmd === "node" && args?.[0] === "agent.mjs") { return cmdResult( 0, JSON.stringify({ success: true, summary: "Posted something", actions: [{ tool: "create_post", input: { content: "test" } }], }), ); } return cmdResult(0, ""); }); const { handlePost } = await import("../src/handlers/post"); const result = await handlePost(); expect(mockCreate).toHaveBeenCalled(); expect(result.success).toBe(true); expect(result.summary).toBe("Posted something"); }); it("returns error result on failure", async () => { mockRunCommand.mockImplementation(({ cmd, args }) => { if (cmd === "node" && args?.[0] === "agent.mjs") { return cmdResult(1, "", "Sandbox timeout"); } return cmdResult(0, ""); }); const { handlePost } = await import("../src/handlers/post"); const result = await handlePost(); expect(result.success).toBe(false); }); }); describe("handleHeartbeat", () => { it("runs agent with heartbeat trigger", async () => { mockRunCommand.mockImplementation(({ cmd, args }) => { if (cmd === "node" && args?.[0] === "agent.mjs") { return cmdResult( 0, JSON.stringify({ success: true, summary: "Liked 2 posts", actions: [ { tool: "like_post", input: { targetTxId: "tx1" } }, { tool: "like_post", input: { targetTxId: "tx2" } }, ], }), ); } return cmdResult(0, ""); }); const { handleHeartbeat } = await import("../src/handlers/heartbeat"); const result = await handleHeartbeat(); expect(mockCreate).toHaveBeenCalled(); expect(result.success).toBe(true); }); it("catches thrown errors and returns failure result", async () => { mockCreate.mockRejectedValueOnce(new Error("sandbox exploded")); const { handleHeartbeat } = await import("../src/handlers/heartbeat"); const result = await handleHeartbeat(); expect(result.success).toBe(false); expect(result.error).toBe("sandbox exploded"); }); }); describe("handlePost error handling", () => { it("catches thrown errors and returns failure result", async () => { mockCreate.mockRejectedValueOnce(new Error("sandbox exploded")); const { handlePost } = await import("../src/handlers/post"); const result = await handlePost(); expect(result.success).toBe(false); expect(result.error).toBe("sandbox exploded"); }); }); });