diff --git a/packages/features/bookings/lib/getBookingResponsesSchema.test.ts b/packages/features/bookings/lib/getBookingResponsesSchema.test.ts index 857bc170c0..2f16bbf1df 100644 --- a/packages/features/bookings/lib/getBookingResponsesSchema.test.ts +++ b/packages/features/bookings/lib/getBookingResponsesSchema.test.ts @@ -329,8 +329,7 @@ describe("getBookingResponsesSchema", () => { ); }); - // TODO: Fix this behaviour later - test.skip("`firstAndLastName` variant to `fullName` when passed as JSON string from URL prefill", async () => { + test("`firstAndLastName` variant to `fullName` when passed as JSON string from URL prefill", async () => { const schema = getBookingResponsesSchema({ bookingFields: [ { @@ -366,6 +365,126 @@ describe("getBookingResponsesSchema", () => { ); }); + test("JSON string with only firstName (no lastName) from URL prefill", async () => { + const schema = getBookingResponsesSchema({ + bookingFields: [ + { + name: "name", + type: "name", + required: true, + }, + { + name: "email", + type: "email", + required: true, + }, + ] as z.infer & z.BRAND<"HAS_SYSTEM_FIELDS">, + view: "ALL_VIEWS", + }); + const parsedResponses = await schema.safeParseAsync({ + name: '{"firstName":"John"}', + email: "john@example.com", + }); + + expectResponsesToBe( + parsedResponses, + expect.objectContaining({ + name: "John", + email: "john@example.com", + }) + ); + }); + + test("Invalid JSON string falls back to regular string handling", async () => { + const schema = getBookingResponsesSchema({ + bookingFields: [ + { + name: "name", + type: "name", + required: true, + }, + { + name: "email", + type: "email", + required: true, + }, + ] as z.infer & z.BRAND<"HAS_SYSTEM_FIELDS">, + view: "ALL_VIEWS", + }); + const parsedResponses = await schema.safeParseAsync({ + name: "{not valid json}", + email: "john@example.com", + }); + + expectResponsesToBe( + parsedResponses, + expect.objectContaining({ + name: "{not valid json}", + email: "john@example.com", + }) + ); + }); + + test("JSON array falls back to regular string handling", async () => { + const schema = getBookingResponsesSchema({ + bookingFields: [ + { + name: "name", + type: "name", + required: true, + }, + { + name: "email", + type: "email", + required: true, + }, + ] as z.infer & z.BRAND<"HAS_SYSTEM_FIELDS">, + view: "ALL_VIEWS", + }); + const parsedResponses = await schema.safeParseAsync({ + name: '["John", "Doe"]', + email: "john@example.com", + }); + + expectResponsesToBe( + parsedResponses, + expect.objectContaining({ + name: '["John", "Doe"]', + email: "john@example.com", + }) + ); + }); + + test("JSON object without firstName falls back to regular string handling", async () => { + const schema = getBookingResponsesSchema({ + bookingFields: [ + { + name: "name", + type: "name", + required: true, + }, + { + name: "email", + type: "email", + required: true, + }, + ] as z.infer & z.BRAND<"HAS_SYSTEM_FIELDS">, + view: "ALL_VIEWS", + }); + const parsedResponses = await schema.safeParseAsync({ + name: '{"name":"John Doe"}', + email: "john@example.com", + }); + + expectResponsesToBe( + parsedResponses, + expect.objectContaining({ + name: '{"name":"John Doe"}', + email: "john@example.com", + }) + ); + }); + test("`fullName` to `firstAndLastName` when there is a lastName(separated by space)", async () => { const schema = getBookingResponsesSchema({ bookingFields: [ diff --git a/packages/features/form-builder/schema.ts b/packages/features/form-builder/schema.ts index d06bcdbe57..cda2f8e561 100644 --- a/packages/features/form-builder/schema.ts +++ b/packages/features/form-builder/schema.ts @@ -144,6 +144,19 @@ export const fieldTypesSchemaMap = { } if (typeof response === "string") { + const nameJsonSchema = z.object({ + firstName: z.string(), + lastName: z.string().optional().default(""), + }); + + try { + const parsed = nameJsonSchema.safeParse(JSON.parse(response)); + if (parsed.success) { + return preprocessNameFieldDataWithVariant(correctedVariant, parsed.data); + } + } catch { + // if invalid JSON, then treat as regular string + } return preprocessNameFieldDataWithVariant(correctedVariant, response); }