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({