-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Unit Tests for FormBuilderField and BookingFields components (#…
…16162) * Remove use of location from FormBuilder * Add tests * FormBuilderField and BookingFields tests * More tests * Remove always true if condition * Fix ui import mockig that got broken after the last merge
- Loading branch information
1 parent
263a96e
commit 28c631e
Showing
17 changed files
with
365 additions
and
318 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
183 changes: 183 additions & 0 deletions
183
packages/features/bookings/Booker/components/BookEventForm/BookingFields.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import "@calcom/ui/__mocks__/ui"; | ||
|
||
import { TooltipProvider } from "@radix-ui/react-tooltip"; | ||
import { render, fireEvent, screen } from "@testing-library/react"; | ||
import * as React from "react"; | ||
import type { UseFormReturn } from "react-hook-form"; | ||
import { FormProvider, useForm } from "react-hook-form"; | ||
import { expect } from "vitest"; | ||
|
||
import { getBookingFieldsWithSystemFields } from "../../../lib/getBookingFields"; | ||
import { BookingFields } from "./BookingFields"; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
type FormMethods = UseFormReturn<any>; | ||
|
||
const renderComponent = ({ | ||
props: props, | ||
formDefaultValues, | ||
}: { | ||
props: Parameters<typeof BookingFields>[0]; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
formDefaultValues?: any; | ||
}) => { | ||
let formMethods: UseFormReturn | undefined; | ||
const Wrapper = ({ children }: { children: React.ReactNode }) => { | ||
const form = useForm({ | ||
defaultValues: formDefaultValues, | ||
}); | ||
formMethods = form; | ||
return ( | ||
<TooltipProvider> | ||
<FormProvider {...form}>{children}</FormProvider> | ||
</TooltipProvider> | ||
); | ||
}; | ||
const result = render(<BookingFields {...props} />, { wrapper: Wrapper }); | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return { result, formMethods: formMethods! }; | ||
}; | ||
|
||
describe("BookingFields", () => { | ||
it("should correctly render with location fields", () => { | ||
const AttendeePhoneNumberOption = { | ||
label: "attendee_phone_number", | ||
value: "phone", | ||
}; | ||
|
||
const OrganizerLinkOption = { | ||
label: "https://google.com", | ||
value: "link", | ||
}; | ||
|
||
const locations = [ | ||
{ | ||
type: AttendeePhoneNumberOption.value, | ||
}, | ||
{ | ||
link: "https://google.com", | ||
type: OrganizerLinkOption.value, | ||
displayLocationPublicly: true, | ||
}, | ||
]; | ||
const { formMethods } = renderComponent({ | ||
props: { | ||
fields: getBookingFieldsWithSystemFields({ | ||
disableGuests: false, | ||
bookingFields: [], | ||
metadata: null, | ||
workflows: [], | ||
customInputs: [], | ||
}), | ||
locations, | ||
isDynamicGroupBooking: false, | ||
bookingData: null, | ||
}, | ||
formDefaultValues: {}, | ||
}); | ||
|
||
component.fillName({ value: "John Doe" }); | ||
component.fillEmail({ value: "john.doe@example.com" }); | ||
component.fillNotes({ value: "This is a note" }); | ||
expectScenarios.expectNameToBe({ value: "John Doe", formMethods }); | ||
expectScenarios.expectEmailToBe({ value: "john.doe@example.com", formMethods }); | ||
expectScenarios.expectNotesToBe({ value: "This is a note", formMethods }); | ||
|
||
component.fillRadioInputLocation({ label: AttendeePhoneNumberOption.label, inputValue: "+1234567890" }); | ||
expectScenarios.expectLocationToBe({ | ||
formMethods, | ||
label: AttendeePhoneNumberOption.label, | ||
toMatch: { | ||
formattedValue: "+1 (234) 567-890", | ||
value: { optionValue: "+1234567890", value: AttendeePhoneNumberOption.value }, | ||
}, | ||
}); | ||
|
||
component.fillRadioInputLocation({ label: OrganizerLinkOption.label }); | ||
expectScenarios.expectLocationToBe({ | ||
formMethods, | ||
label: OrganizerLinkOption.label, | ||
toMatch: { | ||
formattedValue: "+1 (234) 567-890", | ||
value: { optionValue: "", value: OrganizerLinkOption.value }, | ||
}, | ||
}); | ||
}); | ||
}); | ||
|
||
const component = { | ||
getName: ({ label = "your_name" }: { label?: string } = {}) => | ||
screen.getByRole("textbox", { | ||
name: new RegExp(label), | ||
}) as HTMLInputElement, | ||
getEmail: () => screen.getByRole("textbox", { name: /email/i }) as HTMLInputElement, | ||
getLocationRadioOption: ({ label }: { label: string }) => | ||
screen.getByRole("radio", { name: new RegExp(label) }) as HTMLInputElement, | ||
getLocationRadioInput: ({ placeholder }: { placeholder: string }) => | ||
screen.getByPlaceholderText(placeholder) as HTMLInputElement, | ||
getNotes: () => screen.getByRole("textbox", { name: /additional_notes/i }) as HTMLInputElement, | ||
getGuests: () => screen.getByLabelText("guests"), | ||
fillName: ({ value }: { value: string }) => { | ||
fireEvent.change(component.getName(), { target: { value } }); | ||
}, | ||
fillEmail: ({ value }: { value: string }) => { | ||
fireEvent.change(component.getEmail(), { target: { value } }); | ||
}, | ||
fillRadioInputLocation: ({ label, inputValue }: { label: string; inputValue?: string }) => { | ||
fireEvent.click(component.getLocationRadioOption({ label })); | ||
|
||
if (inputValue) { | ||
let placeholder = label; | ||
if (label === "attendee_phone_number") { | ||
placeholder = "enter_phone_number"; | ||
} else { | ||
// radioInput doesn't have a label, so we need to identify by placeholder | ||
throw new Error("Tell me how to identify the placeholder for this location input"); | ||
} | ||
fireEvent.change(component.getLocationRadioInput({ placeholder }), { | ||
target: { value: inputValue }, | ||
}); | ||
} | ||
}, | ||
fillNotes: ({ value }: { value: string }) => { | ||
fireEvent.change(component.getNotes(), { target: { value } }); | ||
}, | ||
}; | ||
|
||
const expectScenarios = { | ||
expectNameToBe: ({ value, formMethods }: { value: string; formMethods: FormMethods }) => { | ||
expect(component.getName().value).toEqual(value); | ||
expect(formMethods.getValues("responses.name")).toEqual(value); | ||
}, | ||
expectEmailToBe: ({ value, formMethods }: { value: string; formMethods: FormMethods }) => { | ||
expect(component.getEmail().value).toEqual(value); | ||
expect(formMethods.getValues("responses.email")).toEqual(value); | ||
}, | ||
expectLocationToBe: ({ | ||
formMethods, | ||
label, | ||
toMatch: { formattedValue, value }, | ||
}: { | ||
label: string; | ||
toMatch: { | ||
formattedValue?: string; | ||
value: { | ||
optionValue: string; | ||
value: string; | ||
}; | ||
}; | ||
formMethods: FormMethods; | ||
}) => { | ||
expect(component.getLocationRadioOption({ label }).checked).toBe(true); | ||
if (value.optionValue) { | ||
expect(component.getLocationRadioInput({ placeholder: "enter_phone_number" }).value).toEqual( | ||
formattedValue | ||
); | ||
} | ||
expect(formMethods.getValues("responses.location")).toEqual(value); | ||
}, | ||
expectNotesToBe: ({ value, formMethods }: { value: string; formMethods: FormMethods }) => { | ||
expect(component.getNotes().value).toEqual(value); | ||
expect(formMethods.getValues("responses.notes")).toEqual(value); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.