Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/app/api/affiliates/offers/[id]/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,28 @@ describe("PATCH /api/affiliates/offers/[id] - product_url validation (#137)", ()
expect(body.error).toContain("string");
});

it("rejects non-string title values before trimming", async () => {
const res = await PATCH(
makeRequest("offer-1", { title: { text: "New title" } }),
makeParams("offer-1")
);

expect(res.status).toBe(400);
const body = await res.json();
expect(body.error).toBe("title must be a string");
});

it("rejects non-string description values before trimming", async () => {
const res = await PATCH(
makeRequest("offer-1", { description: ["New description"] }),
makeParams("offer-1")
);

expect(res.status).toBe(400);
const body = await res.json();
expect(body.error).toBe("description must be a string");
});

it("accepts valid https URL in product_url (#137)", async () => {
// Mock the update chain to succeed
mockFrom.mockReturnValue(chainable({ id: "offer-1", product_url: "https://example.com/product" }));
Expand Down
14 changes: 12 additions & 2 deletions src/app/api/affiliates/offers/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,18 @@ export async function PATCH(
// Partial validation — only validate provided fields
const updateData: Record<string, unknown> = { updated_at: new Date().toISOString() };

if (body.title !== undefined) updateData.title = body.title.trim();
if (body.description !== undefined) updateData.description = body.description.trim();
if (body.title !== undefined) {
if (typeof body.title !== "string") {
return NextResponse.json({ error: "title must be a string" }, { status: 400 });
}
updateData.title = body.title.trim();
}
if (body.description !== undefined) {
if (typeof body.description !== "string") {
return NextResponse.json({ error: "description must be a string" }, { status: 400 });
}
updateData.description = body.description.trim();
}
if (body.product_url !== undefined) {
if (body.product_url !== null && typeof body.product_url !== "string") {
return NextResponse.json({ error: "product_url must be a string" }, { status: 400 });
Expand Down
Loading