Files
calendar/packages/features/routing-forms/lib/getUrlSearchParamsToForward.test.ts
T
Joe Au-YeungGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1d5228ef38 fix: skip duplicate CRM lookup when router already performed it (#27487)
When the routing form redirects to an event type, it now passes
cal.crmLookupDone=true to indicate that the CRM contact owner lookup
was already performed. The event type SSR checks for this flag and
skips the duplicate CRM lookup, improving performance.

This fixes the scenario where no CRM contact owner exists - previously
the lookup would be performed twice (once in the router, once in SSR),
but now it's only performed once.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 14:28:34 +00:00

424 lines
12 KiB
TypeScript

import { v4 as uuidv4 } from "uuid";
import { describe, it, expect } from "vitest";
import { getUrlSearchParamsToForward } from "./getUrlSearchParamsToForward";
function fromEntriesWithDuplicateKeys(entries: IterableIterator<[string, string]> | null) {
const result: Record<string, string | string[]> = {};
if (entries === null) {
return result;
}
// Consider setting atleast ES2015 as target
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
for (const [key, value] of entries) {
if (result.hasOwnProperty(key)) {
let currentValue = result[key];
if (!Array.isArray(currentValue)) {
currentValue = [currentValue];
}
currentValue.push(value);
result[key] = currentValue;
} else {
result[key] = value;
}
}
return result;
}
describe("getUrlSearchParamsToForward", () => {
it("should build query params from response correctly when identifier is present in fields", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "value1", label: "Field 1" },
[field2Id]: { value: ["option1", "option2"], label: "Field 2" },
};
const fields = [
{ id: field1Id, identifier: "f1", type: "text", label: "Field 1" },
{
id: field2Id,
identifier: "f2",
label: "Field 2",
type: "multiselect",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
],
},
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
f1: "value1",
f2: ["Option 1", "Option 2"],
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should build query params from response correctly when identifier is not present in fields. Should fallback to label", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "value1" },
[field2Id]: { value: "value2" },
};
const fields = [
{ id: field1Id, label: "Field 1", type: "text" },
{ id: field2Id, label: "Field 2", type: "text" },
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
"Field 1": "value1",
"Field 2": "value2",
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should handle select fields correctly when options have id set", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "Option 1" },
[field2Id]: { value: ["Option 1", "Option 2"] },
};
const fields = [
{
id: field1Id,
label: "Field 1",
type: "select",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
],
},
{
id: field2Id,
label: "Field 2",
type: "multiselect",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
{ id: "option3", label: "Option 3" },
],
},
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
"Field 1": "Option 1",
"Field 2": ["Option 1", "Option 2"],
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should handle select fields correctly when options have no id set(Legacy options)", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "Option 1" },
[field2Id]: { value: ["Option 1", "Option 2"] },
};
const fields = [
{
id: field1Id,
label: "Field 1",
type: "select",
options: [
{ id: null, label: "Option 1" },
{ id: null, label: "Option 2" },
],
},
{
id: field2Id,
label: "Field 2",
type: "multiselect",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
{ id: "option3", label: "Option 3" },
],
},
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
"Field 1": "Option 1",
"Field 2": ["Option 1", "Option 2"],
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should handle number values correctly", () => {
const field1Id = uuidv4();
const response = {
[field1Id]: { value: 123 },
};
const fields = [{ id: field1Id, label: "Field 1", type: "number" }];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
"Field 1": "123",
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse: response,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should add cal.skipContactOwner when attributeRoutingConfig.skipContactOwner is true", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "value1", label: "Field 1" },
[field2Id]: { value: ["option1", "option2"], label: "Field 2" },
};
const fields = [
{ id: field1Id, identifier: "f1", type: "text", label: "Field 1" },
{
id: field2Id,
identifier: "f2",
label: "Field 2",
type: "multiselect",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
],
},
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
f1: "value1",
f2: ["Option 1", "Option 2"],
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
"cal.skipContactOwner": "true",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: {
skipContactOwner: true,
},
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should add cal.routedTeamMemberIds to query params", () => {
const field1Id = uuidv4();
const field2Id = uuidv4();
const formResponse = {
[field1Id]: { value: "value1", label: "Field 1" },
[field2Id]: { value: ["option1", "option2"], label: "Field 2" },
};
const fields = [
{ id: field1Id, identifier: "f1", type: "text", label: "Field 1" },
{
id: field2Id,
identifier: "f2",
label: "Field 2",
type: "multiselect",
options: [
{ id: "option1", label: "Option 1" },
{ id: "option2", label: "Option 2" },
],
},
];
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
f1: "value1",
f2: ["Option 1", "Option 2"],
query1: "value1",
query2: "value2",
"cal.routingFormResponseId": "1",
"cal.routedTeamMemberIds": "1,2",
};
const result = getUrlSearchParamsToForward({
formResponse,
fields,
searchParams,
teamMembersMatchingAttributeLogic: [1, 2],
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
describe("Dry Run", () => {
it("should add cal.routingFormResponseId=0 when formResponseId is 0", () => {
const searchParams = new URLSearchParams("?query1=value1&query2=value2");
const expectedParams = {
"cal.routingFormResponseId": "0",
query1: "value1",
query2: "value2",
};
const result = getUrlSearchParamsToForward({
formResponse: {},
fields: [],
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 0,
queuedFormResponseId: null,
attributeRoutingConfig: null,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
});
describe("CRM Lookup Done", () => {
it("should add cal.crmLookupDone when crmLookupDone is true", () => {
const searchParams = new URLSearchParams("?query1=value1");
const expectedParams = {
query1: "value1",
"cal.routingFormResponseId": "1",
"cal.crmLookupDone": "true",
};
const result = getUrlSearchParamsToForward({
formResponse: {},
fields: [],
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
crmLookupDone: true,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should not add cal.crmLookupDone when crmLookupDone is false", () => {
const searchParams = new URLSearchParams("?query1=value1");
const expectedParams = {
query1: "value1",
"cal.routingFormResponseId": "1",
};
const result = getUrlSearchParamsToForward({
formResponse: {},
fields: [],
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
crmLookupDone: false,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
it("should add both CRM contact owner email and crmLookupDone when both are provided", () => {
const searchParams = new URLSearchParams("?query1=value1");
const expectedParams = {
query1: "value1",
"cal.routingFormResponseId": "1",
"cal.crmContactOwnerEmail": "owner@example.com",
"cal.crmContactOwnerRecordType": "Contact",
"cal.crmAppSlug": "salesforce",
"cal.crmLookupDone": "true",
};
const result = getUrlSearchParamsToForward({
formResponse: {},
fields: [],
searchParams,
teamMembersMatchingAttributeLogic: null,
formResponseId: 1,
queuedFormResponseId: null,
attributeRoutingConfig: null,
crmContactOwnerEmail: "owner@example.com",
crmContactOwnerRecordType: "Contact",
crmAppSlug: "salesforce",
crmLookupDone: true,
});
expect(fromEntriesWithDuplicateKeys(result.entries())).toEqual(expectedParams);
});
});
});