Files
calendar/packages/app-store/routing-forms/lib/substituteVariables.test.ts
T
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
13cbb59e5e fix: Custom Event Redirect in Routing Form with Dropdown Based fields (#17870)
Co-authored-by: hariom@cal.com <hariombalhara@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-08-25 13:46:18 -04:00

230 lines
8.2 KiB
TypeScript

import { describe, it, expect } from "vitest";
import type { FormResponse, Field } from "../types/types";
import { substituteVariables } from "./substituteVariables";
describe("substituteVariables", () => {
const createSelectField = (
id: string,
identifier: string,
label: string,
options?: Array<{ id: string; label: string }>
): Field => ({
id,
identifier,
label,
type: "select",
options,
});
const createTextField = (id: string, identifier: string, label: string): Field => ({
id,
identifier,
label,
type: "text",
});
const createMultiselectField = (
id: string,
identifier: string,
label: string,
options?: Array<{ id: string; label: string }>
): Field => ({
id,
identifier,
label,
type: "multiselect",
options,
});
const createFormResponse = (
fieldId: string,
value: string | string[] | number,
label: string
): FormResponse => ({
[fieldId]: {
value,
label,
},
});
it("should substitute variables with option labels (not field labels or values)", () => {
const fields = [
createSelectField("field1", "department", "Department", [
{ id: "sales-123", label: "Sales Team" },
{ id: "eng-456", label: "Engineering" },
]),
];
const routeValue = "/team/{department}/meeting";
const response = createFormResponse("field1", "sales-123", "Department");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/team/sales-team/meeting");
expect(result).not.toBe("/team/sales-123/meeting");
expect(result).not.toBe("/team/department/meeting");
});
it("should handle multiple variable substitutions", () => {
const fields = [
createSelectField("field1", "department", "Department", [{ id: "eng-456", label: "Engineering" }]),
createTextField("field2", "teamName", "Team Name"),
];
const routeValue = "/{department}/{teamName}/book";
const response: FormResponse = {
...createFormResponse("field1", "eng-456", "Department"),
...createFormResponse("field2", "Backend Team", "Team Name"),
};
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/engineering/backend-team/book");
});
it("should handle special characters in labels by slugifying them", () => {
const fields = [
createSelectField("field1", "department", "Department", [{ id: "hr_dept", label: "HR & Recruitment" }]),
];
const routeValue = "/meeting/{department}";
const response = createFormResponse("field1", "hr_dept", "Department");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/meeting/hr-recruitment");
});
it("should handle case-insensitive variable matching", () => {
const fields = [
createSelectField("field1", "department", "Department", [
{ id: "support-001", label: "Customer Support" },
]),
];
const routeValue = "/team/{DEPARTMENT}/schedule";
const response = createFormResponse("field1", "support-001", "Department");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/team/customer-support/schedule");
});
it("should not substitute variables that don't have matching fields", () => {
const fields = [createTextField("field1", "knownField", "Known Field")];
const routeValue = "/team/{unknownField}/meeting";
const response = createFormResponse("field1", "sales-123", "Sales Team");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/team/{unknownField}/meeting");
});
it("should handle array values in response labels", () => {
const fields = [
createMultiselectField("field3", "priority", "Priority Level", [
{ id: "high", label: "High" },
{ id: "urgent", label: "Urgent" },
]),
];
const routeValue = "/priorities/{priority}";
const response = createFormResponse("field3", ["high", "urgent"], "Priority Level");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/priorities/high-urgent");
});
it("should handle numeric labels", () => {
const fields = [
createSelectField("field1", "department", "Department", [{ id: "room-id-123", label: "Room 404" }]),
];
const routeValue = "/room/{department}";
const response = createFormResponse("field1", "room-id-123", "Department");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/room/room-404");
});
it("should not modify the URL if no variables are present", () => {
const fields = [createTextField("field1", "someField", "Some Field")];
const routeValue = "/team/fixed/meeting";
const response = createFormResponse("field1", "sales-123", "Sales Team");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/team/fixed/meeting");
});
it("should handle complex URLs with query parameters", () => {
const fields = [
createSelectField("field1", "department", "Department", [
{ id: "marketing-789", label: "Marketing & PR" },
]),
];
const routeValue = "/event/{department}?type=meeting&priority=high";
const response = createFormResponse("field1", "marketing-789", "Department");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/event/marketing-pr?type=meeting&priority=high");
});
it("should substitute text field values directly", () => {
const fields = [createTextField("field1", "username", "Username")];
const routeValue = "/user/{username}/profile";
const response = createFormResponse("field1", "John Doe", "Username");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/user/john-doe/profile");
});
it("should handle number field values", () => {
const fields = [
{ id: "field1", identifier: "employeeId", label: "Employee ID", type: "number" as const },
];
const routeValue = "/employee/{employeeId}/details";
const response = createFormResponse("field1", 12345, "Employee ID");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/employee/12345/details");
});
it("should handle multiple text and number fields in one URL", () => {
const fields = [
createTextField("field1", "department", "Department Name"),
{ id: "field2", identifier: "roomNumber", label: "Room Number", type: "number" as const },
createTextField("field3", "building", "Building"),
];
const routeValue = "/{building}/floor/{roomNumber}/{department}";
const response: FormResponse = {
...createFormResponse("field1", "Engineering", "Department Name"),
...createFormResponse("field2", 404, "Room Number"),
...createFormResponse("field3", "Tower A", "Building"),
};
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/tower-a/floor/404/engineering");
});
it("should handle text fields with special characters", () => {
const fields = [createTextField("field1", "projectName", "Project Name")];
const routeValue = "/project/{projectName}/board";
const response = createFormResponse("field1", "Cal.com Platform & API", "Project Name");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/project/cal.com-platform-api/board");
});
it("should handle empty text field values", () => {
const fields = [createTextField("field1", "optional", "Optional Field")];
const routeValue = "/form/{optional}/submit";
const response = createFormResponse("field1", "", "Optional Field");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/form//submit");
});
it("should handle textarea fields like text fields", () => {
const fields = [
{ id: "field1", identifier: "description", label: "Description", type: "textarea" as const },
];
const routeValue = "/ticket/{description}";
const response = createFormResponse("field1", "Bug Report Summary", "Description");
const result = substituteVariables(routeValue, response, fields);
expect(result).toBe("/ticket/bug-report-summary");
});
});