import React from 'react'; import { add, format, startOfDay, sub, } from 'date-fns'; import { fireEvent, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import DatePicker from './index'; describe('DatePicker', () => { describe('enforces [minDate, maxDate] range on input date through text', () => { const dateFormat = 'MM/dd/yyyy'; const maxDate = startOfDay(new Date()); const startDate = sub(maxDate, { months: 1 }); const minDate = sub(maxDate, { years: 3 }); it('repositions start date to minDate if a start date entered via text input is before minDate', () => { const onDateChange = jest.fn(); const { container } = render( , ); const startDateBeforeMinDate = sub(minDate, { days: 1 }); const startDateTextInputElement = container.querySelectorAll('[type="text"]')[0]; userEvent.clear(startDateTextInputElement); userEvent.type(startDateTextInputElement, format(startDateBeforeMinDate, dateFormat)); fireEvent.blur(startDateTextInputElement); expect(onDateChange).toBeCalledWith([minDate, null]); expect(onDateChange).toBeCalledTimes(1); }); it('accepts input start date if the input start date is between the valid [minDate, maxDate] range', () => { const onDateChange = jest.fn(); const { container } = render( , ); const validStartDate = add(startDate, { days: 1 }); const startDateTextInputElement = container.querySelectorAll('[type="text"]')[0]; userEvent.clear(startDateTextInputElement); userEvent.type(startDateTextInputElement, format(validStartDate, dateFormat)); fireEvent.blur(startDateTextInputElement); expect(onDateChange).toBeCalledWith([validStartDate, null]); expect(onDateChange).toBeCalledTimes(1); }); it('repositions start date to maxDate if a start date entered via text input is after maxDate', () => { const onDateChange = jest.fn(); const { container } = render( , ); const startDateAfterMaxDate = add(maxDate, { days: 1 }); const startDateTextInputElement = container.querySelectorAll('[type="text"]')[0]; userEvent.clear(startDateTextInputElement); userEvent.type(startDateTextInputElement, format(startDateAfterMaxDate, dateFormat)); fireEvent.blur(startDateTextInputElement); expect(onDateChange).toBeCalledWith([maxDate, null]); expect(onDateChange).toBeCalledTimes(1); }); it('repositions start date and end date to minDate if an end date entered via text input is before minDate', () => { const onDateChange = jest.fn(); const { container } = render( , ); const endDateBeforeMinDate = sub(minDate, { days: 1 }); const endDateTextInputElement = container.querySelectorAll('[type="text"]')[1]; userEvent.clear(endDateTextInputElement); userEvent.type(endDateTextInputElement, format(endDateBeforeMinDate, dateFormat)); fireEvent.blur(endDateTextInputElement); expect(onDateChange).toBeCalledWith([minDate, minDate]); expect(onDateChange).toBeCalledTimes(1); }); it('accepts input end date if the input end date is between the valid [minDate, maxDate] range and is after startDate', () => { const onDateChange = jest.fn(); const { container } = render( , ); const validEndDate = add(startDate, { days: 1 }); const endDateTextInputElement = container.querySelectorAll('[type="text"]')[1]; userEvent.clear(endDateTextInputElement); userEvent.type(endDateTextInputElement, format(validEndDate, dateFormat)); fireEvent.blur(endDateTextInputElement); expect(onDateChange).toBeCalledWith([startDate, validEndDate]); expect(onDateChange).toBeCalledTimes(1); }); it('repositions end date to maxDate if an end date entered via text input is after maxDate', () => { const onDateChange = jest.fn(); const { container } = render( , ); const endDateAfterMaxDate = add(maxDate, { days: 1 }); const endDateTextInputElement = container.querySelectorAll('[type="text"]')[1]; userEvent.clear(endDateTextInputElement); userEvent.type(endDateTextInputElement, format(endDateAfterMaxDate, dateFormat)); fireEvent.blur(endDateTextInputElement); expect(onDateChange).toBeCalledWith([startDate, maxDate]); expect(onDateChange).toBeCalledTimes(1); }); }); });