From fbfa27735b33bca5358179b60f818612032a5711 Mon Sep 17 00:00:00 2001 From: chauhan_s Date: Thu, 20 Nov 2025 16:15:22 +0530 Subject: [PATCH] feat: add validation for null values in bookingFieldsResponses (#25272) * feat: add validation for null values in bookingFieldsResponses - Add test case to verify 400 error when bookingFieldsResponses contains null values - Create ValidateBookingFieldsResponses decorator to reject null values in booking field responses - Apply validator to CreateBookingInput_2024_08_13.bookingFieldsResponses property - Ensure all booking field response values are non-null strings * feat: transform null values to empty strings in bookingFieldsResponses - Remove ValidateBookingFieldsResponses validator that rejected null values - Add Transform decorator to convert null values to empty strings in bookingFieldsResponses - Update test to verify null values are transformed to empty strings instead of returning 400 error * remove extra spaces * test: add rescheduleReason null value test case --------- Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> --- .../e2e/booking-fields.e2e-spec.ts | 35 +++++++++++++++---- .../2024-08-13/inputs/create-booking.input.ts | 10 +++++- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-fields.e2e-spec.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-fields.e2e-spec.ts index 22ef6d6012..a9ce338506 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-fields.e2e-spec.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-fields.e2e-spec.ts @@ -20,11 +20,7 @@ import { randomString } from "test/utils/randomString"; import { withApiAuth } from "test/utils/withApiAuth"; import { CAL_API_VERSION_HEADER, SUCCESS_STATUS, VERSION_2024_08_13 } from "@calcom/platform-constants"; -import { - CreateBookingInput_2024_08_13, - GetBookingOutput_2024_08_13, - GetSeatedBookingOutput_2024_08_13, -} from "@calcom/platform-types"; +import { CreateBookingInput_2024_08_13, GetBookingOutput_2024_08_13, GetSeatedBookingOutput_2024_08_13 } from "@calcom/platform-types"; import { BookingOutput_2024_08_13 } from "@calcom/platform-types"; import type { Booking, PlatformOAuthClient, Team, User, EventType } from "@calcom/prisma/client"; @@ -854,7 +850,7 @@ describe("Bookings Endpoints 2024-08-13", () => { describe("Booking Field Type Validation", () => { const basePayload = { - start: "2025-06-19T11:00:00.000Z", + start: new Date(Date.UTC(2030, 5, 19, 11, 0, 0)).toISOString(), attendee: { name: "Charlie TypeTest", email: "charlie.typetest@example.com", @@ -1162,6 +1158,31 @@ describe("Bookings Endpoints 2024-08-13", () => { `One or more invalid options for booking field '${fieldName}'. Allowed options are: blue, red.` ); }); + + it("should transform null values to empty strings in bookingFieldsResponses", async () => { + const payload = { + ...basePayload, + eventTypeId: eventTypeWithBookingFields.id, + bookingFieldsResponses: { + "favorite-movie": "The Matrix", + rescheduleReason: null, + notes: null, + }, + }; + const response = await request(app.getHttpServer()) + .post(`/v2/bookings`) + .send(payload) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13); + expect(response.status).toBe(201); + expect(response.body.status).toEqual(SUCCESS_STATUS); + + if (responseDataIsBooking(response.body.data)) { + const data: BookingOutput_2024_08_13 = response.body.data; + expect(data.bookingFieldsResponses.notes).toBe(""); + expect(data.bookingFieldsResponses.rescheduleReason).toBe(""); + expect(data.bookingFieldsResponses["favorite-movie"]).toBe("The Matrix"); + } + }); }); afterAll(async () => { @@ -1176,4 +1197,4 @@ describe("Bookings Endpoints 2024-08-13", () => { function responseDataIsBooking(data: any): data is BookingOutput_2024_08_13 { return !Array.isArray(data) && typeof data === "object" && data && "id" in data; } -}); +}); \ No newline at end of file diff --git a/packages/platform/types/bookings/2024-08-13/inputs/create-booking.input.ts b/packages/platform/types/bookings/2024-08-13/inputs/create-booking.input.ts index d837715d0c..1cd1cc431d 100644 --- a/packages/platform/types/bookings/2024-08-13/inputs/create-booking.input.ts +++ b/packages/platform/types/bookings/2024-08-13/inputs/create-booking.input.ts @@ -1,5 +1,5 @@ import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from "@nestjs/swagger"; -import { Type } from "class-transformer"; +import { Transform, Type } from "class-transformer"; import type { ValidationArguments, ValidationOptions } from "class-validator"; import { IsInt, @@ -239,6 +239,14 @@ export class CreateBookingInput_2024_08_13 { }) @IsObject() @IsOptional() + @Transform(({ value }) => { + if (!value || typeof value !== "object") return value; + const transformed: Record = {}; + for (const [key, val] of Object.entries(value)) { + transformed[key] = val === null ? "" : val; + } + return transformed; + }) bookingFieldsResponses?: Record; @ApiPropertyOptional({