diff --git a/src/app/api/testimonials/route.test.ts b/src/app/api/testimonials/route.test.ts new file mode 100644 index 00000000..d19b0e5d --- /dev/null +++ b/src/app/api/testimonials/route.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it, vi, beforeEach } from "vitest"; + +vi.mock("@/lib/auth/get-user", () => ({ + getAuthContext: vi.fn(), +})); + +vi.mock("@/lib/supabase/service", () => ({ + createServiceClient: vi.fn(), +})); + +vi.mock("@/lib/email", () => ({ + sendEmail: vi.fn(), +})); + +import { POST } from "./route"; +import { getAuthContext } from "@/lib/auth/get-user"; +import { createServiceClient } from "@/lib/supabase/service"; + +function postReq(json: () => Promise) { + return { + url: "http://localhost/api/testimonials", + headers: new Headers(), + json, + } as any; +} + +describe("POST /api/testimonials", () => { + beforeEach(() => vi.clearAllMocks()); + + it("returns 400 for malformed JSON before creating a testimonial", async () => { + (getAuthContext as any).mockResolvedValue({ + user: { id: "11111111-1111-4111-8111-111111111111" }, + supabase: {}, + }); + + const res = await POST(postReq(() => Promise.reject(new SyntaxError("bad json")))); + + expect(res.status).toBe(400); + const body = await res.json(); + expect(body.error).toBe("Invalid JSON body"); + expect(createServiceClient).not.toHaveBeenCalled(); + }); +}); diff --git a/src/app/api/testimonials/route.ts b/src/app/api/testimonials/route.ts index 9303a9dd..a6b6ccfa 100644 --- a/src/app/api/testimonials/route.ts +++ b/src/app/api/testimonials/route.ts @@ -70,7 +70,12 @@ export async function POST(request: NextRequest) { } const { user, supabase } = auth; - const body = await request.json(); + let body: any; + try { + body = await request.json(); + } catch { + return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); + } const { profile_id, gig_id, rating, content } = body; // Must provide exactly one target