UNPKG

@roo-ui/components

Version:

612 lines (478 loc) 21.5 kB
import React from 'react'; import { parse, format } from 'date-fns'; import range from 'lodash/range'; import { qantas as theme } from '@roo-ui/themes'; import { mountWithTheme } from '@roo-ui/test-utils'; import DateRangePicker from './DateRangePicker'; const dateToString = date => format(date, 'YYYY-MM-DD'); const rangeInclusive = (start = 0, end = 0) => range(start, end + 1); const getDayOfMonth = (wrapper, dayOfMonth) => wrapper.find('CalendarDay').at(dayOfMonth - 1); describe('<DateRangePicker />', () => { let wrapper; const defaultProps = { minDate: parse('2018-07-01'), onRangeSelected: jest.fn, monthsToDisplay: 1, stacked: true, weekdayNames: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], disabledDates: [parse('2018-07-04'), parse('2018-07-05')], }; const setup = (args = {}) => { const props = { ...defaultProps, ...args }; wrapper = mountWithTheme(<DateRangePicker {...props} />, theme); }; describe('when initial dates are passed in', () => { describe('and those dates are in the same month as the minDate', () => { const initialStartDate = new Date('2018-07-15'); const initialEndDate = new Date('2018-07-20'); beforeEach(() => setup({ initialStartDate, initialEndDate })); it('displays the correct month', () => { const MonthWrapper = wrapper.find('MonthWrapper'); expect(MonthWrapper.find('Text').first().text()).toEqual('Jul 2018'); }); }); describe('and those dates are in advance of the minDate', () => { const initialStartDate = new Date('2018-11-15'); const initialEndDate = new Date('2018-11-20'); beforeEach(() => setup({ initialStartDate, initialEndDate })); it('displays the correct month', () => { const MonthWrapper = wrapper.find('MonthWrapper'); expect(MonthWrapper.find('Text').first().text()).toEqual('Nov 2018'); }); }); }); describe('disabledDates', () => { const initialStartDate = new Date('2018-07-15'); const initialEndDate = new Date('2018-07-20'); beforeEach(() => setup({ initialStartDate, initialEndDate })); it('disables dates in disabledDates array', () => { const date4 = wrapper.find('CalendarDay').at(3); const date5 = wrapper.find('CalendarDay').at(4); expect(date4.props()).toEqual(expect.objectContaining({ selected: false, selectable: false, disabled: true, })); expect(date5.props()).toEqual(expect.objectContaining({ selected: false, selectable: false, disabled: true, })); }); it('does not disable other dates', () => { const date3 = wrapper.find('CalendarDay').at(2); const date6 = wrapper.find('CalendarDay').at(5); expect(date3.props()).not.toEqual(expect.objectContaining({ disabled: true })); expect(date6.props()).not.toEqual(expect.objectContaining({ disabled: true })); }); }); describe('preselected range', () => { const initialStartDate = parse('2018-07-15'); const initialEndDate = parse('2018-07-20'); beforeEach(() => { setup({ initialStartDate, initialEndDate }); }); it('highlights dates in range', () => { rangeInclusive(15, 20).forEach((index) => { const day = getDayOfMonth(wrapper, index); expect(day.props()).toEqual(expect.objectContaining({ highlighted: true })); }); }); it('selects start & end dates', () => { const day15 = wrapper.find('CalendarDay').at(14); const day20 = wrapper.find('CalendarDay').at(19); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); expect(day20.props()).toEqual(expect.objectContaining({ selected: true })); }); }); describe('callbacks', () => { let callback; describe('when selecting three sequential days', () => { beforeEach(() => { callback = jest.fn(); const initialDisplayDate = parse('2018-07-15'); setup({ initialDisplayDate, onChangeDates: callback }); getDayOfMonth(wrapper, 1).find('button').simulate('click'); getDayOfMonth(wrapper, 2).find('button').simulate('click'); getDayOfMonth(wrapper, 3).find('button').simulate('click'); wrapper.update(); }); it('calls the callback three times', () => { expect(callback).toHaveBeenCalledTimes(3); }); it('calls the first callback with only the correct start date', () => { expect(dateToString(callback.mock.calls[0][0].startDate)).toEqual('2018-07-01'); expect(callback.mock.calls[0][0].endDate).toBeNull(); }); it('calls the second callback with the correct start and end dates', () => { expect(dateToString(callback.mock.calls[1][0].startDate)).toEqual('2018-07-01'); expect(dateToString(callback.mock.calls[1][0].endDate)).toEqual('2018-07-02'); }); it('calls the third callback with the correct start date and resets the end date', () => { expect(dateToString(callback.mock.calls[2][0].startDate)).toEqual('2018-07-03'); expect(callback.mock.calls[2][0].endDate).toBeNull(); }); }); }); describe('when only start date is set', () => { const initialStartDate = parse('2018-07-15'); describe('with isSettingStartDate is false', () => { const isSettingStartDate = false; beforeEach(() => { setup({ initialStartDate, isSettingStartDate }); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); describe('with mouse on a past date', () => { let hoverdDate; beforeEach(() => { hoverdDate = wrapper.find('CalendarDay').at(11); hoverdDate.simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('does not highlight range', () => { const date13 = wrapper.find('CalendarDay').at(12); const date14 = wrapper.find('CalendarDay').at(13); expect(date13.props()).not.toEqual(expect.objectContaining({ highlighted: true })); expect(date14.props()).not.toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a past date', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(11).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(11); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); }); describe('with mouse on a future date', () => { let date18; beforeEach(() => { date18 = wrapper.find('CalendarDay').at(17); date18.find('button').simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('highlights the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a future date', () => { let date18; beforeEach(() => { wrapper.find('CalendarDay').at(17).find('button').simulate('click'); wrapper.update(); date18 = wrapper.find('CalendarDay').at(17); }); it('selects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(date18.props()).toEqual(expect.objectContaining({ selected: true })); }); it('highlights the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).toEqual(expect.objectContaining({ highlighted: true })); }); }); }); describe('with isSettingStartDate is true', () => { const isSettingStartDate = true; beforeEach(() => { setup({ initialStartDate, isSettingStartDate }); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); describe('with mouse on a past date', () => { let hoverdDate; beforeEach(() => { hoverdDate = wrapper.find('CalendarDay').at(11); hoverdDate.simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('does not highlight range', () => { const date13 = wrapper.find('CalendarDay').at(12); const date14 = wrapper.find('CalendarDay').at(13); expect(date13.props()).not.toEqual(expect.objectContaining({ highlighted: true })); expect(date14.props()).not.toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a past date', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(11).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(11); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); }); describe('with mouse on a future date', () => { let date18; beforeEach(() => { date18 = wrapper.find('CalendarDay').at(17); date18.find('button').simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('does not highlight the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).not.toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).not.toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a future date', () => { let date18; beforeEach(() => { wrapper.find('CalendarDay').at(17).find('button').simulate('click'); wrapper.update(); date18 = wrapper.find('CalendarDay').at(17); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(date18.props()).toEqual(expect.objectContaining({ selected: true })); }); it('does not highlight the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).not.toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).not.toEqual(expect.objectContaining({ highlighted: true })); }); }); }); describe('with isSettingEndDate is true', () => { const isSettingEndDate = true; beforeEach(() => { setup({ initialStartDate, isSettingEndDate }); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); describe('with mouse on a past date', () => { let hoverdDate; beforeEach(() => { hoverdDate = wrapper.find('CalendarDay').at(11); hoverdDate.simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('does not highlight range', () => { const date13 = wrapper.find('CalendarDay').at(12); const date14 = wrapper.find('CalendarDay').at(13); expect(date13.props()).not.toEqual(expect.objectContaining({ highlighted: true })); expect(date14.props()).not.toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a past date', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(11).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(11); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); }); describe('with mouse on a future date', () => { let date18; beforeEach(() => { date18 = wrapper.find('CalendarDay').at(17); date18.find('button').simulate('mouseEnter'); wrapper.update(); }); it('selects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('highlights the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).toEqual(expect.objectContaining({ highlighted: true })); }); }); describe('when click on a future date', () => { let date18; beforeEach(() => { wrapper.find('CalendarDay').at(17).find('button').simulate('click'); wrapper.update(); date18 = wrapper.find('CalendarDay').at(17); }); it('selects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(date18.props()).toEqual(expect.objectContaining({ selected: true })); }); it('highlights the range', () => { const date16 = wrapper.find('CalendarDay').at(15); const date17 = wrapper.find('CalendarDay').at(16); expect(date16.props()).toEqual(expect.objectContaining({ highlighted: true })); expect(date17.props()).toEqual(expect.objectContaining({ highlighted: true })); }); }); }); }); describe('when start date & end date are set', () => { const initialStartDate = parse('2018-07-15'); const initialEndDate = parse('2018-07-20'); describe('with isSettingStartDate is true', () => { const isSettingStartDate = true; beforeEach(() => { setup({ initialStartDate, initialEndDate, isSettingStartDate }); }); describe('when click on a date < endDate', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(11).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(11); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); it('keeps end date selected', () => { const day20 = wrapper.find('CalendarDay').at(19); expect(day20.props()).toEqual(expect.objectContaining({ selected: true })); }); }); describe('when click on a date > endDate', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(22).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(22); }); it('deselects original start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); it('deselects end date', () => { const day20 = wrapper.find('CalendarDay').at(19); expect(day20.props()).not.toEqual(expect.objectContaining({ selected: true })); }); }); }); describe('with isSettingEndDate is true', () => { const isSettingEndDate = true; beforeEach(() => { setup({ initialStartDate, initialEndDate, isSettingEndDate }); }); describe('when click on a date > startDate', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(17).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(17); }); it('keeps start date selected', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).toEqual(expect.objectContaining({ selected: true })); }); it('selects the new end date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); it('deselects end date', () => { const day20 = wrapper.find('CalendarDay').at(19); expect(day20.props()).not.toEqual(expect.objectContaining({ selected: true })); }); }); describe('when click on a date < startDate', () => { let newClickedDate; beforeEach(() => { wrapper.find('CalendarDay').at(11).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(11); }); it('deselects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); it('deselects endDate', () => { const day20 = wrapper.find('CalendarDay').at(19); expect(day20.props()).not.toEqual(expect.objectContaining({ selected: true })); }); }); }); describe('with isSettingStartDate is false and isSettingEndDate is false', () => { let newClickedDate; beforeEach(() => { setup({ initialStartDate, initialEndDate }); wrapper.find('CalendarDay').at(22).find('button').simulate('click'); wrapper.update(); newClickedDate = wrapper.find('CalendarDay').at(22); }); it('deselects start date', () => { const day15 = wrapper.find('CalendarDay').at(14); expect(day15.props()).not.toEqual(expect.objectContaining({ selected: true })); }); it('selects the new start date', () => { expect(newClickedDate.props()).toEqual(expect.objectContaining({ selected: true })); }); it('deselects endDate', () => { const day20 = wrapper.find('CalendarDay').at(19); expect(day20.props()).not.toEqual(expect.objectContaining({ selected: true })); }); }); }); });