import React from 'react';
import { mount } from 'enzyme';
import Calendar from '../Calendar';
import { getBeginOfMonth } from '../shared/dates';
/* eslint-disable comma-dangle */
const { format } = new Intl.DateTimeFormat('en-US', { day: 'numeric', month: 'long', year: 'numeric' });
describe('Calendar', () => {
it('renders navigation', () => {
const component = mount(
);
const navigation = component.find('.react-calendar__navigation');
expect(navigation).toHaveLength(1);
});
it('does not render navigation when showNavigation flag is set to false', () => {
const component = mount(
);
const navigation = component.find('.react-calendar__navigation');
expect(navigation).toHaveLength(0);
});
it('renders month view by default', () => {
const component = mount(
);
const monthView = component.find('.react-calendar__month-view');
expect(monthView).toHaveLength(1);
});
it('renders maximum allowed view when given maxDetail', () => {
const component = mount(
);
const yearView = component.find('.react-calendar__year-view');
expect(yearView).toHaveLength(1);
});
it('renders maximum allowed view when given view that is not allowed', () => {
const component = mount(
);
const yearView = component.find('.react-calendar__year-view');
expect(yearView).toHaveLength(1);
});
it('renders maximum allowed view when attempting to externally switch to a view that is not allowed', () => {
const component = mount(
);
component.setProps({ view: 'month' });
component.update();
const yearView = component.find('.react-calendar__year-view');
expect(yearView).toHaveLength(1);
});
it('renders maximum allowed view when given changed maxDetail', () => {
const component = mount(
);
component.setProps({ maxDetail: 'year' });
component.update();
const yearView = component.find('.react-calendar__year-view');
expect(yearView).toHaveLength(1);
});
it('renders month view when given view = "month"', () => {
const component = mount(
);
const monthView = component.find('.react-calendar__month-view');
expect(monthView).toHaveLength(1);
});
it('renders month view with week numbers when given view = "month" and showWeekNumbers flag set to true', () => {
const component = mount(
);
const monthView = component.find('.react-calendar__month-view--weekNumbers');
expect(monthView).toHaveLength(1);
});
it('renders year view when given view = "year"', () => {
const component = mount(
);
const yearView = component.find('.react-calendar__year-view');
expect(yearView).toHaveLength(1);
});
it('renders decade view when given view = "decade"', () => {
const component = mount(
);
const decadeView = component.find('.react-calendar__decade-view');
expect(decadeView).toHaveLength(1);
});
it('renders century view when given view = "century"', () => {
const component = mount(
);
const centuryView = component.find('.react-calendar__century-view');
expect(centuryView).toHaveLength(1);
});
it('displays a view with a given value when value is given', () => {
const value = new Date(2017, 0, 1);
const component = mount(
);
const monthView = component.find('.react-calendar__month-view');
const firstDayTile = monthView.find('.react-calendar__tile').first();
const firstDayTileTimeAbbr = firstDayTile.find('abbr').prop('aria-label');
expect(firstDayTileTimeAbbr).toBe(format(value));
});
it('displays a view with activeStartDate when no value is given and activeStartDate is given', () => {
const activeStartDate = new Date(2017, 0, 1);
const component = mount(
);
const monthView = component.find('.react-calendar__month-view');
const firstDayTile = monthView.find('.react-calendar__tile').first();
const firstDayTileTimeAbbr = firstDayTile.find('abbr').prop('aria-label');
expect(firstDayTileTimeAbbr).toBe(format(activeStartDate));
});
it('displays a view with today\'s date when no value and no activeStartDate is given', () => {
const today = new Date();
const beginOfCurrentMonth = getBeginOfMonth(today);
const component = mount(
);
const monthView = component.find('.react-calendar__month-view');
const firstDayTile = monthView.find('.react-calendar__tile').first();
const firstDayTileTimeAbbr = firstDayTile.find('abbr').prop('aria-label');
expect(firstDayTileTimeAbbr).toBe(format(beginOfCurrentMonth));
});
it('drills up when allowed', () => {
const component = mount(
);
component.instance().drillUp();
expect(component.state().view).toBe('year');
});
it('calls onDrillUp on drill up', () => {
const onDrillUp = jest.fn();
const component = mount(
);
component.instance().drillUp();
expect(onDrillUp).toHaveBeenCalledWith({
activeStartDate: new Date(2017, 0, 1),
view: 'year',
});
});
it('refuses to drill up when already on minimum allowed detail', () => {
const onDrillUp = jest.fn();
const component = mount(
);
component.instance().drillUp();
expect(onDrillUp).not.toHaveBeenCalled();
});
it('drills down when allowed', () => {
const component = mount(
);
component.instance().drillDown(new Date(2011, 0, 1));
expect(component.state().view).toBe('decade');
});
it('calls onDrillDown on drill down', () => {
const onDrillDown = jest.fn();
const component = mount(
);
component.instance().drillDown(new Date(2011, 0, 1));
expect(onDrillDown).toHaveBeenCalledWith({
activeStartDate: new Date(2011, 0, 1),
view: 'decade',
});
});
it('refuses to drill down when already on minimum allowed detail', () => {
const onDrillDown = jest.fn();
const component = mount(
);
component.instance().drillUp();
expect(onDrillDown).not.toHaveBeenCalled();
});
it('calls onChange function returning the beginning of selected period by default', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1));
});
it('calls onChange function returning the beginning of the selected period when returnValue is set to "start"', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1));
});
it('calls onChange function returning the beginning of the selected period when returnValue is set to "start"', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1));
});
it('calls onChange function returning the end of the selected period when returnValue is set to "end"', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1, 23, 59, 59, 999));
});
it('calls onChange function returning the beginning of selected period when returnValue is set to "range"', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith([
new Date(2017, 0, 1),
new Date(2017, 0, 1, 23, 59, 59, 999),
]);
});
it('calls onChange function returning the beginning of selected period, but no earlier than minDate', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1, 12));
});
it('calls onChange function returning the beginning of selected period, but no later than maxDate', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 2));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1, 12));
});
it('calls onChange function returning the end of selected period, but no earlier than minDate', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 1));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 2, 12));
});
it('calls onChange function returning the end of selected period, but no later than maxDate', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2017, 0, 2));
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1, 12));
});
it('calls onChange function returning a range when selected two pieces of a range', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2018, 0, 1));
component.instance().onChange(new Date(2018, 6, 1));
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith([
new Date(2018, 0, 1),
new Date(2018, 6, 1, 23, 59, 59, 999),
]);
});
it('calls onChange function returning a range when selected reversed two pieces of a range', () => {
const onChange = jest.fn();
const component = mount(
);
component.instance().onChange(new Date(2018, 6, 1));
component.instance().onChange(new Date(2018, 0, 1));
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith([
new Date(2018, 0, 1),
new Date(2018, 6, 1, 23, 59, 59, 999),
]);
});
it('calls onActiveDateChange on activeStartDate change', () => {
const activeStartDate = new Date(2017, 0, 1);
const newActiveStartDate = new Date(2018, 0, 1);
const onActiveDateChange = jest.fn();
const component = mount(
);
component.instance().setActiveStartDate(newActiveStartDate);
expect(onActiveDateChange).toHaveBeenCalledWith({
activeStartDate: newActiveStartDate,
view: 'year',
});
});
it('changes Calendar view given new activeStartDate value', () => {
const activeStartDate = new Date(2017, 0, 1);
const newActiveStartDate = new Date(2018, 0, 1);
const component = mount(
);
component.setProps({ activeStartDate: newActiveStartDate });
const monthView = component.find('.react-calendar__month-view');
const firstDayTile = monthView.find('.react-calendar__tile').first();
const firstDayTileTimeAbbr = firstDayTile.find('abbr').prop('aria-label');
expect(firstDayTileTimeAbbr).toBe(format(newActiveStartDate));
});
it('displays calendar with custom weekdays formatting', () => {
const component = mount(
'Weekday'}
/>
);
const monthView = component.find('.react-calendar__month-view');
const firstWeekdayTile = monthView.find('.react-calendar__month-view__weekdays__weekday').first();
expect(firstWeekdayTile.text()).toBe('Weekday');
});
it('displays calendar with custom month year navigation label', () => {
const component = mount(
'MonthYear'}
/>
);
const navigationLabel = component.find('.react-calendar__navigation__label').first();
expect(navigationLabel.text()).toBe('MonthYear');
});
});