import { describe, expect, test } from "@jest/globals" // importing because of type conflict with globals from Cypress import { render, screen } from "@testing-library/react" import { type UserEvent, userEvent } from "@testing-library/user-event" import { FormProvider, useForm } from "react-hook-form" import { Lang } from "@/constants/languages" import { dt } from "@/lib/dt" import { getLocalizedMonthName } from "@/utils/dateFormatting" import Date from "./index" jest.mock("react-intl", () => ({ useIntl: () => ({ formatMessage: (message: { id: string }) => message.id, formatNumber: (value: number) => value, }), })) interface FormWrapperProps { defaultValues: Record children: React.ReactNode onSubmit: (data: unknown) => void } function FormWrapper({ defaultValues, children, onSubmit }: FormWrapperProps) { const methods = useForm({ defaultValues, }) return (
onSubmit(data))}> {children}
) } async function selectOption(user: UserEvent, name: RegExp, value: string) { // since its not a proper Select element selectOptions from userEvent doesn't work const select = screen.queryByRole("button", { name }) if (select) { await user.click(select) const option = screen.queryByRole("option", { name: value }) if (option) { await user.click(option) } else { await user.click(select) // click select again to close it } } } const testCases = [ { description: "date is set and submitted successfully", defaultValue: "", dateOfBirth: "1987-12-05", expectedOutput: { dateOfBirth: "1987-12-05", year: 1987, month: 12, day: 5, }, }, { description: "sets default value and submits successfully", defaultValue: "2000-01-01", dateOfBirth: "", expectedOutput: { dateOfBirth: "2000-01-01", year: 2000, month: 1, day: 1, }, }, { description: "accepts date exactly 18 years old", defaultValue: "", dateOfBirth: dt().subtract(18, "year").format("YYYY-MM-DD"), expectedOutput: { dateOfBirth: dt().subtract(18, "year").format("YYYY-MM-DD"), }, }, { description: "rejects date below 18 years old - by year", defaultValue: "", dateOfBirth: dt().subtract(17, "year").format("YYYY-MM-DD"), expectedOutput: { dateOfBirth: "", }, }, { description: "rejects date below 18 years old - by month", defaultValue: "", dateOfBirth: dt().subtract(18, "year").add(1, "month").format("YYYY-MM-DD"), expectedOutput: { dateOfBirth: "", }, }, { description: "rejects date below 18 years old - by day", defaultValue: "", dateOfBirth: dt().subtract(18, "year").add(1, "day").format("YYYY-MM-DD"), expectedOutput: { dateOfBirth: "", }, }, ] describe("Date input", () => { test.each(testCases)( "$description", async ({ defaultValue, dateOfBirth, expectedOutput }) => { const user = userEvent.setup() const handleSubmit = jest.fn() render( ) const date = dt(dateOfBirth).toDate() const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() await selectOption(user, /year/i, year.toString()) await selectOption(user, /month/i, getLocalizedMonthName(month, Lang.en)) await selectOption(user, /day/i, day.toString()) const submitButton = screen.getByRole("button", { name: /submit/i }) await user.click(submitButton) expect(handleSubmit).toHaveBeenCalledWith( expect.objectContaining(expectedOutput) ) } ) })