import React from 'react';
import { waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import renderWithTheme from '../../../testUtils/renderWithTheme';
import DateRangePicker from '../DateRangePicker';
describe('rendering', () => {
it('renders two inputs and calendar', async () => {
const { getByDisplayValue, getAllByText, getByTestId } = renderWithTheme(
);
await waitFor(() => {
expect(getByDisplayValue('02/05/2021')).toBeInTheDocument();
expect(getByDisplayValue('10/05/2021')).toBeInTheDocument();
});
userEvent.click(getByDisplayValue('02/05/2021'));
await waitFor(() => {
const firstMonthSelect = getByTestId('first-month-select');
const firstYearSelect = getByTestId('first-year-select');
const secondMonthSelect = getByTestId('second-month-select');
const secondYearSelect = getByTestId('second-year-select');
expect(firstMonthSelect).toSelectItem('May');
expect(firstYearSelect).toSelectItem('2021');
expect(secondMonthSelect).toSelectItem('Jun');
expect(secondYearSelect).toSelectItem('2021');
expect(getAllByText('10').length).toBe(3);
});
});
it('renders two inputs with correct format', async () => {
const { getByDisplayValue } = renderWithTheme(
);
await waitFor(() => {
expect(getByDisplayValue('2021/05/02')).toBeInTheDocument();
expect(getByDisplayValue('2021/05/10')).toBeInTheDocument();
});
});
});
describe('interaction', () => {
it('allows to blur', async () => {
const onBlur = jest.fn();
const { getByPlaceholderText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('Start'));
userEvent.click(document.body);
expect(onBlur).toHaveBeenCalledTimes(1);
});
it('allows to pick start date and then end date', async () => {
const onChange = jest.fn();
const { getByPlaceholderText, getAllByText, queryByText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('Start'));
await waitFor(() => {
// Calendar is open
expect(getAllByText('Su')[0]).toBeVisible();
});
userEvent.click(getAllByText('9')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith({
startDate: '09/05/2021',
endDate: '10/05/2021',
});
// Calendar is still open
expect(getAllByText('Su')[1]).toBeVisible();
});
userEvent.click(getAllByText('15')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(2);
expect(onChange).toHaveBeenCalledWith({
startDate: '02/05/2021',
endDate: '15/05/2021',
});
// Calendar is closed
expect(queryByText('Su')).not.toBeInTheDocument();
});
});
it('allows to pick end date and then start date', async () => {
const onChange = jest.fn();
const { getByPlaceholderText, getAllByText, queryByText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('End'));
await waitFor(() => {
// Calendar is open
expect(getAllByText('Su')[0]).toBeVisible();
});
userEvent.click(getAllByText('9')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith({
startDate: '02/05/2021',
endDate: '09/05/2021',
});
// Calendar is still open
expect(getAllByText('Su')[1]).toBeVisible();
});
userEvent.click(getAllByText('8')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(2);
expect(onChange).toHaveBeenCalledWith({
startDate: '08/05/2021',
endDate: '10/05/2021',
});
// Calendar is closed
expect(queryByText('Su')).not.toBeInTheDocument();
});
});
it('resets end date when new start date is after end date', async () => {
const onChange = jest.fn();
const { getByPlaceholderText, getAllByText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('Start'));
await waitFor(() => {
// Calendar is open
expect(getAllByText('Su')[0]).toBeVisible();
});
userEvent.click(getAllByText('12')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith({
startDate: '12/05/2021',
endDate: undefined,
});
// Calendar is still open
expect(getAllByText('Su')[1]).toBeVisible();
});
});
it('resets start date when new end date is before start date', async () => {
const onChange = jest.fn();
const { getByPlaceholderText, getAllByText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('End'));
await waitFor(() => {
// Calendar is open
expect(getAllByText('Su')[0]).toBeVisible();
});
userEvent.click(getAllByText('1')[0]);
await waitFor(() => {
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith({
startDate: undefined,
endDate: '01/05/2021',
});
// Calendar is still open
expect(getAllByText('Su')[1]).toBeVisible();
});
});
it('does not allow to pick a date out of range', async () => {
const onChange = jest.fn();
const { getByPlaceholderText, getAllByText } = renderWithTheme(
);
userEvent.click(getByPlaceholderText('Start'));
await waitFor(() => {
// Calendar is open
expect(getAllByText('Su')[0]).toBeVisible();
});
await waitFor(() => {
expect(() => userEvent.click(getAllByText('1')[0])).toThrowError(
'unable to click element as it has or inherits pointer-events set to "none"'
);
});
await waitFor(() => {
expect(() => userEvent.click(getAllByText('21')[0])).toThrowError(
'unable to click element as it has or inherits pointer-events set to "none"'
);
});
});
it('does not allow to edit disabled DateRangePicker', async () => {
const { queryByText, getByDisplayValue } = renderWithTheme(
);
userEvent.click(getByDisplayValue('11/05/2021'));
await waitFor(() => {
expect(queryByText('Su')).not.toBeInTheDocument();
});
});
it('does not allow invalid value', () => {
jest.spyOn(console, 'error').mockImplementation(() => '');
expect(() =>
renderWithTheme(
)
).toThrowError('Invalid time value');
});
it('does not allow to clear value when clearable is false', () => {
const { getByTestId, queryByTestId } = renderWithTheme(
);
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
userEvent.hover(getByTestId('date-range-picker'));
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
});
it('does not allow to clear value when value is undefined', () => {
const { getByTestId, queryByTestId } = renderWithTheme(
);
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
userEvent.hover(getByTestId('date-range-picker'));
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
});
it('allows to clear value when startDate is not undefined', () => {
const onChange = jest.fn();
const { getByTestId, queryByTestId } = renderWithTheme(
);
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
userEvent.hover(getByTestId('date-range-picker'));
expect(queryByTestId('remove-icon')).toBeInTheDocument();
});
it('allows to clear value when endDate is not undefined', () => {
const onChange = jest.fn();
const { getByTestId, queryByTestId } = renderWithTheme(
);
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
userEvent.hover(getByTestId('date-range-picker'));
expect(queryByTestId('remove-icon')).toBeInTheDocument();
});
it('allows to clear value', async () => {
const onChange = jest.fn();
const { getByTestId, queryByTestId, container } = renderWithTheme(
);
expect(queryByTestId('remove-icon')).not.toBeInTheDocument();
expect(container.querySelector('.hero-icon-calendar')).toBeInTheDocument();
userEvent.hover(getByTestId('date-range-picker'));
expect(container.querySelector('.hero-icon-calendar')).toBeNull();
userEvent.click(getByTestId('remove-icon'));
await waitFor(() => {
expect(onChange).toHaveBeenCalledWith({
startDate: undefined,
endDate: undefined,
});
});
});
});