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);
});
});
});