fix(CalEventParser): skip null/undefined values in getUserFieldsResponses (#29703)

When a booking question is optional and left unanswered, the field value
stored in customInputs can be null. The previous guard only checked
for empty strings, so null (and undefined) would coerce to the literal
strings "null"/"undefined" inside the template literal, polluting calendar
event descriptions.

Fixes #29688
This commit is contained in:
okxint
2026-07-08 18:01:41 +00:00
committed by GitHub
parent bb7c87cae1
commit 009f91d163
2 changed files with 31 additions and 2 deletions
+30 -1
View File
@@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { getRichDescription } from "./CalEventParser";
import { getRichDescription, getUserFieldsResponses } from "./CalEventParser";
describe("getRichDescription", () => {
const t = ((key: string, _args?: Record<string, unknown>) => key) as TFunction;
@@ -85,3 +85,32 @@ describe("getRichDescription", () => {
expect(description).toContain("who:");
});
});
describe("getUserFieldsResponses", () => {
const t = ((key: string) => key) as TFunction;
it("does not render null values for unanswered optional booking questions", () => {
// When an optional booking question is left unanswered, customInputs may store null
// for that field. Before the fix, null coerced to the string "null" in the template
// literal, polluting the calendar event description.
const result = getUserFieldsResponses(
{ customInputs: { "Phone Number": null, Name: "Alice" } },
t
);
expect(result).not.toContain("null");
expect(result).toContain("Name");
expect(result).toContain("Alice");
});
it("does not render empty string values for booking questions", () => {
const result = getUserFieldsResponses(
{ customInputs: { "Phone Number": "", Name: "Bob" } },
t
);
expect(result).not.toContain("Phone Number");
expect(result).toContain("Name");
expect(result).toContain("Bob");
});
});
+1 -1
View File
@@ -117,7 +117,7 @@ export const getUserFieldsResponses = (
const responsesString = Object.keys(labelValueMap)
.map((key) => {
if (!labelValueMap) return "";
if (labelValueMap[key] !== "") {
if (labelValueMap[key] != null && labelValueMap[key] !== "") {
return `
${t(key)}:
${labelValueMap[key]}