Skip to content
30 changes: 30 additions & 0 deletions app/api/chat/__tests__/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, it, expect, vi } from "vitest";
import { NextRequest } from "next/server";

import { POST, OPTIONS } from "@/app/api/chat/route";
import { handleChatWorkflowStream } from "@/lib/chat/handleChatWorkflowStream";

vi.mock("@/lib/chat/handleChatWorkflowStream", () => ({
handleChatWorkflowStream: vi.fn(async () => new Response("ok", { status: 200 })),
}));

vi.mock("@/lib/networking/getCorsHeaders", () => ({
getCorsHeaders: vi.fn(() => ({ "Access-Control-Allow-Origin": "*" })),
}));

describe("POST /api/chat route shell", () => {
it("delegates to handleChatWorkflowStream (canonical path; alias of /api/chat/workflow)", async () => {
const req = new NextRequest("http://localhost/api/chat", { method: "POST" });
const res = await POST(req);

expect(handleChatWorkflowStream).toHaveBeenCalledWith(req);
expect(res.status).toBe(200);
});

it("OPTIONS returns 200 with CORS headers", async () => {
const res = await OPTIONS();

expect(res.status).toBe(200);
expect(res.headers.get("Access-Control-Allow-Origin")).toBe("*");
});
});
9 changes: 5 additions & 4 deletions app/api/chat/workflow/route.ts → app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ export async function OPTIONS() {
}

/**
* POST /api/chat/workflow
* POST /api/chat
*
* Streams a sandbox-driven agent loop (Vercel Workflow) for an existing
* session + chat. Currently returns a hardcoded UIMessage stream stub —
* the workflow is wired up in a follow-up PR.
* Canonical path for the sandbox-driven agent loop (Vercel Workflow).
* Delegates to the same handler as `POST /api/chat/workflow`, which is
* retained as a backward-compatible alias while consumers (chat,
* open-agents, API-key callers) migrate to `/api/chat`.
*
* Contract: https://developers.recoupable.com/api-reference/chat/workflow
*
Expand Down
Loading