Merged in feat/SW-619-signup-non-happy (pull request #1083)
Feat/SW-619 signup non happy * feat(SW-619): Added tests for Date input * feat(SW-619): Updated date input to not allow date below 18 years old, also added form validation and tests to cover this change * fix * feat(SW-619): add info banner if membership verification fails * fix(SW-619): update test description Approved-by: Christel Westerberg Approved-by: Arvid Norlin
This commit is contained in:
138
components/TempDesignSystem/Form/Date/date.test.tsx
Normal file
138
components/TempDesignSystem/Form/Date/date.test.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
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"
|
||||
|
||||
interface FormWrapperProps {
|
||||
defaultValues: Record<string, unknown>
|
||||
children: React.ReactNode
|
||||
onSubmit: (data: unknown) => void
|
||||
}
|
||||
|
||||
function FormWrapper({ defaultValues, children, onSubmit }: FormWrapperProps) {
|
||||
const methods = useForm({
|
||||
defaultValues,
|
||||
})
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form onSubmit={methods.handleSubmit((data) => onSubmit(data))}>
|
||||
{children}
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</FormProvider>
|
||||
)
|
||||
}
|
||||
|
||||
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(
|
||||
<FormWrapper
|
||||
defaultValues={{ dateOfBirth: defaultValue }}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Date name="dateOfBirth" />
|
||||
</FormWrapper>
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -19,6 +19,8 @@ import styles from "./date.module.css"
|
||||
|
||||
export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
const intl = useIntl()
|
||||
const lang = useLang()
|
||||
|
||||
const { control, setValue, formState, watch } = useFormContext()
|
||||
const { field, fieldState } = useController({
|
||||
control,
|
||||
@@ -31,14 +33,20 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
const month = watch(DateName.month)
|
||||
const day = watch(DateName.day)
|
||||
|
||||
const lang = useLang()
|
||||
const months = rangeArray(1, 12).map((month) => ({
|
||||
const minAgeDate = dt().subtract(18, "year").toDate() // age 18
|
||||
const minAgeYear = minAgeDate.getFullYear()
|
||||
const minAgeMonth = year === minAgeYear ? minAgeDate.getMonth() + 1 : null
|
||||
const minAgeDay =
|
||||
Number(year) === minAgeYear && Number(month) === minAgeMonth
|
||||
? minAgeDate.getDate()
|
||||
: null
|
||||
|
||||
const months = rangeArray(1, minAgeMonth ?? 12).map((month) => ({
|
||||
value: month,
|
||||
label: getLocalizedMonthName(month, lang),
|
||||
}))
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const years = rangeArray(1900, currentYear - 18)
|
||||
const years = rangeArray(1900, minAgeYear)
|
||||
.reverse()
|
||||
.map((year) => ({ value: year, label: year.toString() }))
|
||||
|
||||
@@ -48,7 +56,7 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
month ? Number(month) - 1 : null
|
||||
)
|
||||
|
||||
const days = rangeArray(1, daysInMonth).map((day) => ({
|
||||
const days = rangeArray(1, minAgeDay ?? daysInMonth).map((day) => ({
|
||||
value: day,
|
||||
label: `${day}`,
|
||||
}))
|
||||
@@ -119,7 +127,6 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
ref={field.ref}
|
||||
value={dateValue}
|
||||
data-testid={name}
|
||||
className={styles.datePicker}
|
||||
>
|
||||
<Group>
|
||||
<DateInput className={styles.container}>
|
||||
|
||||
Reference in New Issue
Block a user