Files
calendar/packages/features/bookings/Booker/hooks/useInitialFormValues.test.ts
T
98b6d63164 refactor: apply biome formatting to packages/features (#27844)
* refactor: apply biome formatting to packages/features (batch 1 - small subdirs)

Format small subdirectories in packages/features: di, flags, holidays, oauth,
settings, users, assignment-reason, selectedCalendar, hashedLink, host, form,
form-builder, availability, data-table, pbac, schedules, troubleshooter,
eventtypes, calendar-subscription, and root-level files.

Also includes straggler apps/web BookEventForm.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 2 - medium subdirs)

Format medium subdirectories in packages/features: auth, credentials,
calendars, routing-forms, routing-trace, attributes, watchlist, calAIPhone,
tasker, and webhooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 3 - bookings + insights)

Format bookings and insights subdirectories in packages/features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 4 - ee)

Format packages/features/ee subdirectory covering billing, workflows,
organizations, teams, managed-event-types, round-robin, dsync,
integration-attribute-sync, and payments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 5 - booking-audit part 1)

Format booking-audit di, actions, common, dto, repository, and types
subdirectories in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 6 - booking-audit part 2)

Format booking-audit service subdirectory in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:47:14 +01:00

295 lines
7.7 KiB
TypeScript

/**
* @vitest-environment jsdom
*/
import { cleanup, renderHook, waitFor } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import type { BookerEvent } from "@calcom/features/bookings/types";
import { useInitialFormValues } from "./useInitialFormValues";
vi.mock("@calcom/features/bookings/Booker/store", () => ({
useBookerStore: vi.fn((selector) => {
const state = {
bookingData: null,
formValues: {},
};
return selector(state);
}),
}));
vi.mock("@calcom/features/bookings/lib/getBookingResponsesSchema", () => ({
getBookingResponsesPartialSchema: vi.fn(() => ({
parseAsync: vi.fn((data) => Promise.resolve(data)),
})),
}));
describe("useInitialFormValues - Autofill Disable Feature", () => {
const mockBookingFields = [
{ name: "name", type: "text" as const, required: true },
{ name: "email", type: "email" as const, required: true },
{ name: "phone", type: "phone" as const, required: false },
] as unknown as BookerEvent["bookingFields"];
const baseProps = {
rescheduleUid: null,
isRescheduling: false,
email: null,
name: null,
username: null,
hasSession: false,
extraOptions: {},
prefillFormParams: {
guests: [],
name: null,
},
};
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
cleanup();
});
describe("when organization has NOT disabled autofill", () => {
it("should use URL parameters to prefill form fields", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: {
organizationSettings: {
disableAutofillOnBookingPage: false,
},
},
owner: null,
};
const extraOptions = {
phone: "+1234567890",
customField: "custom value",
};
const prefillFormParams = {
guests: ["guest1@example.com", "guest2@example.com"],
name: "John Doe",
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
prefillFormParams,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses).toMatchObject({
name: "John Doe",
phone: "+1234567890",
});
});
it("should use URL parameters when organizationSettings is undefined", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: null,
owner: null,
};
const extraOptions = {
phone: "+1234567890",
};
const prefillFormParams = {
guests: [],
name: "Jane Smith",
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
prefillFormParams,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses).toMatchObject({
name: "Jane Smith",
phone: "+1234567890",
});
});
});
describe("when organization HAS disabled autofill", () => {
it("should NOT use URL parameters when team.organizationSettings.disableAutofillOnBookingPage is true", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: {
parent: {
organizationSettings: {
disableAutofillOnBookingPage: true,
},
},
},
owner: null,
};
const extraOptions = {
phone: "+1234567890",
customField: "custom value",
};
const prefillFormParams = {
guests: ["guest1@example.com"],
name: "John Doe",
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
prefillFormParams,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses?.phone).toBeUndefined();
expect(result.current.values.responses?.name).toBe("");
});
it("should NOT use URL parameters when team.parent.organizationSettings.disableAutofillOnBookingPage is true", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: {
organizationSettings: null,
parent: {
organizationSettings: {
disableAutofillOnBookingPage: true,
},
},
},
owner: null,
};
const extraOptions = {
phone: "+9876543210",
};
const prefillFormParams = {
guests: [],
name: "Parent Team User",
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
prefillFormParams,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses?.phone).toBeUndefined();
expect(result.current.values.responses?.name).toBe("");
});
it("should NOT use URL parameters when owner.organization.organizationSettings.disableAutofillOnBookingPage is true", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: null,
owner: {
profile: {
organization: {
organizationSettings: {
disableAutofillOnBookingPage: true,
},
},
},
},
};
const extraOptions = {
phone: "+5555555555",
};
const prefillFormParams = {
guests: [],
name: "Personal Event User",
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
prefillFormParams,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses?.phone).toBeUndefined();
expect(result.current.values.responses?.name).toBe("");
});
});
describe("session data handling with autofill disabled", () => {
it("should not use session email/name when autofill is disabled", async () => {
const eventType: Pick<BookerEvent, "bookingFields" | "team" | "owner"> = {
bookingFields: mockBookingFields,
team: {
parent: {
organizationSettings: {
disableAutofillOnBookingPage: true,
},
},
},
owner: null,
};
const extraOptions = {
phone: "+1234567890", // This should be blocked
};
const { result } = renderHook(() =>
useInitialFormValues({
...baseProps,
eventType,
extraOptions,
email: "session@example.com", // Session data
name: "Session User", // Session data
hasSession: true,
})
);
await waitFor(() => {
expect(result.current.values.responses).toBeDefined();
});
expect(result.current.values.responses?.email).toBe("");
expect(result.current.values.responses?.name).toBe("");
expect(result.current.values.responses?.phone).toBeUndefined();
});
});
});