Simon Egersand
2018-02-07 de3fe15c59e7692eda6058a0dc8d0271acbcf3a3
commit | author | age
7f7ed5 1 /* global it, xit, describe, expect, jasmine, done, jest */
25757d 2
SE 3 import React from 'react'; // eslint-disable-line no-unused-vars
290be5 4 import moment from 'moment';
SE 5 import utils from './testUtils';
7f7ed5 6 import Enzyme from 'enzyme';
SE 7 import Adapter from 'enzyme-adapter-react-15';
8
9 Enzyme.configure({ adapter: new Adapter() });
290be5 10
SE 11 describe('Datetime', () => {
de3fe1 12   it('create component', () => {
SE 13     const component = utils.createDatetime({});
290be5 14
de3fe1 15     expect(component).toBeDefined();
SE 16     expect(component.find('.rdt > .form-control').length).toEqual(1);
17     expect(component.find('.rdt > .rdtPicker').length).toEqual(1);
18   });
25757d 19
de3fe1 20   it('viewMode=days: renders days, week days, month, year', () => {
SE 21     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
22       component = utils.createDatetime({
23         viewMode: 'days',
24         defaultValue: date
25       });
26     utils.openDatepicker(component);
25757d 27
de3fe1 28     // Month and year
SE 29     expect(component.find('.rdtSwitch').text()).toEqual('January 2000');
25757d 30
de3fe1 31     // Week days
SE 32     const expectedWeekDays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
33       actualWeekdays = component
34         .find('.rdtDays .dow')
35         .map((element) => element.text());
36     expect(actualWeekdays).toEqual(expectedWeekDays);
25757d 37
de3fe1 38     // Dates
SE 39     // "Old" dates belonging to prev month
40     const oldDatesIndexes = [0, 1, 2, 3, 4, 5];
41     oldDatesIndexes.forEach((index) => {
42       expect(utils.getNthDay(component, index).hasClass('rdtOld')).toBeTruthy();
43     });
25757d 44
de3fe1 45     // Dates belonging to current month
SE 46     for (let i = 6; i < 37; i++) {
47       expect(utils.getNthDay(component, i).hasClass('rdtDay')).toBeTruthy();
48       expect(utils.getNthDay(component, i).hasClass('rdtOld')).toBeFalsy();
49       expect(utils.getNthDay(component, i).hasClass('rdtNew')).toBeFalsy();
50     }
25757d 51
de3fe1 52     // "New" dates belonging to next month
SE 53     const nextDatesIndexes = [37, 38, 39, 40, 41];
54     nextDatesIndexes.forEach((index) => {
55       expect(utils.getNthDay(component, index).hasClass('rdtNew')).toBeTruthy();
56     });
57   });
290be5 58
de3fe1 59   it('switch from day view to time view and back', () => {
SE 60     const component = utils.createDatetime({});
290be5 61
de3fe1 62     expect(utils.isDayView(component)).toBeTruthy();
SE 63     utils.clickOnElement(component.find('.rdtTimeToggle'));
64     expect(utils.isTimeView(component)).toBeTruthy();
65     utils.clickOnElement(component.find('.rdtSwitch'));
66     expect(utils.isDayView(component)).toBeTruthy();
67   });
290be5 68
de3fe1 69   it('persistent valid months going monthView->yearView->monthView', () => {
SE 70     const dateBefore = '2018-06-01';
71     const component = utils.createDatetime({
72       viewMode: 'months',
73       isValidDate: (current) =>
74         current.isBefore(moment(dateBefore, 'YYYY-MM-DD'))
75     });
290be5 76
de3fe1 77     expect(utils.isMonthView(component)).toBeTruthy();
SE 78     expect(utils.getNthMonth(component, 4).hasClass('rdtDisabled')).toEqual(
79       false
80     );
81     expect(utils.getNthMonth(component, 5).hasClass('rdtDisabled')).toEqual(
82       true
83     );
290be5 84
de3fe1 85     // Go to year view
SE 86     utils.clickOnElement(component.find('.rdtSwitch'));
87     expect(utils.isYearView(component)).toBeTruthy();
290be5 88
de3fe1 89     expect(utils.getNthYear(component, 0).hasClass('rdtDisabled')).toEqual(
SE 90       false
91     );
92     expect(utils.getNthYear(component, 10).hasClass('rdtDisabled')).toEqual(
93       true
94     );
290be5 95
de3fe1 96     utils.clickNthYear(component, 9);
SE 97     expect(utils.getNthMonth(component, 4).hasClass('rdtDisabled')).toEqual(
98       false
99     );
100     expect(utils.getNthMonth(component, 5).hasClass('rdtDisabled')).toEqual(
101       true
102     );
103   });
290be5 104
de3fe1 105   it('step through views', () => {
SE 106     const component = utils.createDatetime({ viewMode: 'time' });
290be5 107
de3fe1 108     expect(utils.isTimeView(component)).toBeTruthy();
SE 109     utils.clickOnElement(component.find('.rdtSwitch'));
110     expect(utils.isDayView(component)).toBeTruthy();
111     utils.clickOnElement(component.find('.rdtSwitch'));
112     expect(utils.isMonthView(component)).toBeTruthy();
113     utils.clickOnElement(component.find('.rdtSwitch'));
114     expect(utils.isYearView(component)).toBeTruthy();
115   });
290be5 116
de3fe1 117   it('toggles calendar when open prop changes', () => {
SE 118     const component = utils.createDatetime({ open: false });
119     expect(utils.isOpen(component)).toBeFalsy();
120     // expect(component.find('.rdtOpen').length).toEqual(0);
121     component.setProps({ open: true });
122     expect(utils.isOpen(component)).toBeTruthy();
123     // expect(component.find('.rdtOpen').length).toEqual(1);
124     component.setProps({ open: false });
125     expect(utils.isOpen(component)).toBeFalsy();
126     // expect(component.find('.rdtOpen').length).toEqual(0);
127   });
d0b63b 128
de3fe1 129   it('selectYear', () => {
SE 130     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
131       component = utils.createDatetime({
132         viewMode: 'years',
133         defaultValue: date
134       });
135     expect(utils.isYearView(component)).toBeTruthy();
136     expect(component.find('.rdtSwitch').text()).toEqual('2000-2009');
290be5 137
de3fe1 138     // Click first year (1999)
SE 139     utils.clickOnElement(component.find('.rdtYear').at(0));
140     expect(utils.isMonthView(component)).toBeTruthy();
141     expect(component.find('.rdtSwitch').text()).toEqual('1999');
142   });
290be5 143
de3fe1 144   it('increase decade', () => {
SE 145     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
146       component = utils.createDatetime({
147         viewMode: 'years',
148         defaultValue: date
149       });
290be5 150
de3fe1 151     expect(component.find('.rdtSwitch').text()).toEqual('2000-2009');
SE 152     utils.clickOnElement(component.find('.rdtNext span').at(0));
153     expect(component.find('.rdtSwitch').text()).toEqual('2010-2019');
154     utils.clickOnElement(component.find('.rdtNext span').at(0));
155     expect(component.find('.rdtSwitch').text()).toEqual('2020-2029');
156   });
290be5 157
de3fe1 158   it('decrease decade', () => {
SE 159     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
160       component = utils.createDatetime({
161         viewMode: 'years',
162         defaultValue: date
163       });
290be5 164
de3fe1 165     expect(component.find('.rdtSwitch').text()).toEqual('2000-2009');
SE 166     utils.clickOnElement(component.find('.rdtPrev span').at(0));
167     expect(component.find('.rdtSwitch').text()).toEqual('1990-1999');
168     utils.clickOnElement(component.find('.rdtPrev span').at(0));
169     expect(component.find('.rdtSwitch').text()).toEqual('1980-1989');
170   });
290be5 171
de3fe1 172   it('select month', () => {
SE 173     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
174       component = utils.createDatetime({
175         viewMode: 'months',
176         defaultValue: date
177       });
290be5 178
de3fe1 179     expect(utils.isMonthView(component)).toBeTruthy();
SE 180     expect(component.find('.rdtSwitch').text()).toEqual('2000');
181     // Click any month to enter day view
182     utils.clickNthMonth(component, 1);
183     expect(utils.isDayView(component)).toBeTruthy();
184     expect(
185       component
186         .find('.rdtSwitch')
187         .getDOMNode()
188         .getAttribute('data-value')
189     ).toEqual('1');
190   });
290be5 191
de3fe1 192   it('increase year', () => {
SE 193     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
194       component = utils.createDatetime({
195         viewMode: 'months',
196         defaultValue: date
197       });
290be5 198
de3fe1 199     expect(component.find('.rdtSwitch').text()).toEqual('2000');
SE 200     utils.clickOnElement(component.find('.rdtNext span').at(0));
201     expect(component.find('.rdtSwitch').text()).toEqual('2001');
202     utils.clickOnElement(component.find('.rdtNext span').at(0));
203     expect(component.find('.rdtSwitch').text()).toEqual('2002');
204   });
290be5 205
de3fe1 206   it('decrease year', () => {
SE 207     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
208       component = utils.createDatetime({
209         viewMode: 'months',
210         defaultValue: date
211       });
290be5 212
de3fe1 213     expect(component.find('.rdtSwitch').text()).toEqual('2000');
SE 214     utils.clickOnElement(component.find('.rdtPrev span').at(0));
215     expect(component.find('.rdtSwitch').text()).toEqual('1999');
216     utils.clickOnElement(component.find('.rdtPrev span').at(0));
217     expect(component.find('.rdtSwitch').text()).toEqual('1998');
218   });
290be5 219
de3fe1 220   it('increase month', () => {
SE 221     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
222       component = utils.createDatetime({ defaultValue: date });
290be5 223
de3fe1 224     expect(component.find('.rdtSwitch').text()).toEqual('January 2000');
SE 225     expect(
226       component
227         .find('.rdtSwitch')
228         .getDOMNode()
229         .getAttribute('data-value')
230     ).toEqual('0');
231     utils.clickOnElement(component.find('.rdtNext span').at(0));
232     expect(component.find('.rdtSwitch').text()).toEqual('February 2000');
233     expect(
234       component
235         .find('.rdtSwitch')
236         .getDOMNode()
237         .getAttribute('data-value')
238     ).toEqual('1');
239     utils.clickOnElement(component.find('.rdtNext span').at(0));
240     expect(component.find('.rdtSwitch').text()).toEqual('March 2000');
241     expect(
242       component
243         .find('.rdtSwitch')
244         .getDOMNode()
245         .getAttribute('data-value')
246     ).toEqual('2');
247   });
290be5 248
de3fe1 249   it('decrease month', () => {
SE 250     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
251       component = utils.createDatetime({ defaultValue: date });
290be5 252
de3fe1 253     expect(component.find('.rdtSwitch').text()).toEqual('January 2000');
SE 254     expect(
255       component
256         .find('.rdtSwitch')
257         .getDOMNode()
258         .getAttribute('data-value')
259     ).toEqual('0');
260     utils.clickOnElement(component.find('.rdtPrev span').at(0));
261     expect(component.find('.rdtSwitch').text()).toEqual('December 1999');
262     expect(
263       component
264         .find('.rdtSwitch')
265         .getDOMNode()
266         .getAttribute('data-value')
267     ).toEqual('11');
268     utils.clickOnElement(component.find('.rdtPrev span').at(0));
269     expect(component.find('.rdtSwitch').text()).toEqual('November 1999');
270     expect(
271       component
272         .find('.rdtSwitch')
273         .getDOMNode()
274         .getAttribute('data-value')
275     ).toEqual('10');
276   });
290be5 277
de3fe1 278   it('open picker', () => {
SE 279     const component = utils.createDatetime();
280     expect(utils.isOpen(component)).toBeFalsy();
281     utils.openDatepicker(component);
282     expect(utils.isOpen(component)).toBeTruthy();
283   });
39e146 284
de3fe1 285   it('opens picker when clicking on input', () => {
SE 286     const component = utils.createDatetime();
287     expect(utils.isOpen(component)).toBeFalsy();
288     component.find('.form-control').simulate('click');
289     expect(utils.isOpen(component)).toBeTruthy();
290   });
f37c3f 291
de3fe1 292   it('sets CSS class on selected item (day)', () => {
SE 293     const component = utils.createDatetime({ viewMode: 'days' });
294     utils.openDatepicker(component);
295     utils.clickNthDay(component, 13);
296     expect(utils.getNthDay(component, 13).hasClass('rdtActive')).toBeTruthy();
297   });
39e146 298
de3fe1 299   it('sets CSS class on selected item (month)', () => {
SE 300     const component = utils.createDatetime({
301       viewMode: 'months',
302       dateFormat: 'YYYY-MM'
303     });
304     utils.openDatepicker(component);
305     utils.clickNthMonth(component, 4);
306     expect(utils.getNthMonth(component, 4).hasClass('rdtActive')).toBeTruthy();
307   });
39e146 308
de3fe1 309   it('sets CSS class on selected item (year)', () => {
SE 310     const component = utils.createDatetime({
311       viewMode: 'years',
312       dateFormat: 'YYYY'
313     });
314     utils.openDatepicker(component);
315     utils.clickNthYear(component, 3);
316     expect(utils.getNthYear(component, 3).hasClass('rdtActive')).toBeTruthy();
317   });
39e146 318
de3fe1 319   it('sets CSS class on days outside of month', () => {
SE 320     const date = new Date(2000, 0, 15, 2, 2, 2, 2),
321       prevMonthDaysIndexes = [0, 1, 2, 3, 4, 5],
322       nextMonthDaysIndexes = [37, 38, 39, 40, 41],
323       component = utils.createDatetime({
324         viewMode: 'days',
325         defaultValue: date
326       });
39e146 327
de3fe1 328     utils.openDatepicker(component);
39e146 329
de3fe1 330     prevMonthDaysIndexes.forEach((index) => {
SE 331       expect(utils.getNthDay(component, index).hasClass('rdtOld')).toBeTruthy();
332     });
333     nextMonthDaysIndexes.forEach((index) => {
334       expect(utils.getNthDay(component, index).hasClass('rdtNew')).toBeTruthy();
335     });
336   });
39e146 337
de3fe1 338   it('selected day persists (in UI) when navigating to prev month', () => {
SE 339     const date = new Date(2000, 0, 3, 2, 2, 2, 2),
340       component = utils.createDatetime({
341         viewMode: 'days',
342         defaultValue: date
343       });
39e146 344
de3fe1 345     utils.openDatepicker(component);
SE 346     expect(utils.getNthDay(component, 8).hasClass('rdtActive')).toBeTruthy();
347     // Go to previous month
348     utils.clickOnElement(component.find('.rdtDays .rdtPrev span'));
349     expect(utils.getNthDay(component, 36).hasClass('rdtActive')).toBeTruthy();
350   });
25757d 351
de3fe1 352   it('sets CSS class on today date', () => {
SE 353     const specificDate = moment('2015-04-19'),
354       component = utils.createDatetime({ defaultValue: specificDate });
25757d 355
de3fe1 356     // Mock the today date
SE 357     jasmine.clock().mockDate(specificDate.toDate());
25757d 358
de3fe1 359     utils.openDatepicker(component);
SE 360     expect(component.find('.rdtDay.rdtToday').text()).toEqual('19');
361   });
39e146 362
de3fe1 363   // Proof of bug [FIXED]
SE 364   it('should show correct selected month when traversing view modes', () => {
365     const date = new Date(2000, 4, 3, 2, 2, 2, 2),
366       component = utils.createDatetime({
367         viewMode: 'days',
368         defaultValue: date
369       });
39e146 370
de3fe1 371     utils.openDatepicker(component);
39e146 372
de3fe1 373     // Go to month view
SE 374     utils.clickOnElement(component.find('.rdtSwitch'));
39e146 375
de3fe1 376     // Here the selected month is _May_, which is correct
SE 377     expect(component.find('.rdtMonth .rdtActive').text()).toEqual('May');
39e146 378
de3fe1 379     // Go to year view
SE 380     utils.clickOnElement(component.find('.rdtSwitch'));
39e146 381
de3fe1 382     // Click the selected year (2000)
SE 383     utils.clickNthYear(component, 1);
39e146 384
de3fe1 385     // The selected month is now _January_
SE 386     expect(component.find('.rdtMonth .rdtActive').text()).toEqual('May');
387   });
290be5 388
de3fe1 389   describe('with custom props', () => {
SE 390     it('input=false', () => {
391       const component = utils.createDatetime({ input: false });
392       expect(component.find('.rdt > .form-control').length).toEqual(0);
393       expect(component.find('.rdt > .rdtPicker').length).toEqual(1);
394     });
290be5 395
de3fe1 396     it('dateFormat', () => {
SE 397       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
398         mDate = moment(date),
399         component = utils.createDatetime({ value: date, dateFormat: 'M&D' });
400       expect(utils.getInputValue(component)).toEqual(mDate.format('M&D LT'));
401     });
290be5 402
de3fe1 403     it('dateFormat=false', () => {
SE 404       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
405         mDate = moment(date),
406         component = utils.createDatetime({ value: date, dateFormat: false });
407       expect(utils.getInputValue(component)).toEqual(mDate.format('LT'));
408       // Make sure time view is active
409       expect(utils.isTimeView(component)).toBeTruthy();
410       // Make sure the date toggle is not rendered
411       expect(component.find('thead').length).toEqual(0);
412     });
290be5 413
de3fe1 414     it('timeFormat', () => {
SE 415       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
416         mDate = moment(date),
417         format = 'HH:mm:ss:SSS',
418         component = utils.createDatetime({ value: date, timeFormat: format });
419       expect(utils.getInputValue(component)).toEqual(
420         mDate.format('L ' + format)
421       );
422     });
290be5 423
de3fe1 424     it('timeFormat=false', () => {
SE 425       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
426         mDate = moment(date),
427         component = utils.createDatetime({ value: date, timeFormat: false });
428       expect(utils.getInputValue(component)).toEqual(mDate.format('L'));
429       // Make sure day view is active
430       expect(utils.isDayView(component)).toBeTruthy();
431       // Make sure the time toggle is not rendered
432       expect(component.find('.timeToggle').length).toEqual(0);
433     });
290be5 434
de3fe1 435     it("timeFormat with lowercase 'am'", () => {
SE 436       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
437         format = 'HH:mm:ss:SSS a',
438         component = utils.createDatetime({ value: date, timeFormat: format });
439       expect(utils.getInputValue(component)).toEqual(
440         expect.stringMatching('.*am$')
441       );
442     });
290be5 443
de3fe1 444     it("timeFormat with uppercase 'AM'", () => {
SE 445       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
446         format = 'HH:mm:ss:SSS A',
447         component = utils.createDatetime({ value: date, timeFormat: format });
448       expect(utils.getInputValue(component)).toEqual(
449         expect.stringMatching('.*AM$')
450       );
451     });
290be5 452
de3fe1 453     it('viewMode=years', () => {
SE 454       const component = utils.createDatetime({ viewMode: 'years' });
455       expect(utils.isYearView(component)).toBeTruthy();
456     });
290be5 457
de3fe1 458     it('viewMode=months', () => {
SE 459       const component = utils.createDatetime({ viewMode: 'months' });
460       expect(utils.isMonthView(component)).toBeTruthy();
461     });
290be5 462
de3fe1 463     it('viewMode=time', () => {
SE 464       const component = utils.createDatetime({ viewMode: 'time' });
465       expect(utils.isTimeView(component)).toBeTruthy();
466     });
290be5 467
de3fe1 468     xit('className -> type string', () => {
SE 469       const component = utils.createDatetime({ className: 'custom-class' });
470       expect(component.find('.custom-class').length).toEqual(1);
471     });
290be5 472
de3fe1 473     it('className -> type string array', () => {
SE 474       const component = utils.createDatetime({
475         className: ['custom-class1', 'custom-class2']
476       });
477       expect(component.find('.custom-class1').length).toEqual(1);
478       expect(component.find('.custom-class2').length).toEqual(1);
479     });
290be5 480
de3fe1 481     it('inputProps', () => {
SE 482       const component = utils.createDatetime({
483         inputProps: {
484           className: 'custom-class',
485           type: 'email',
486           placeholder: 'custom-placeholder'
487         }
488       });
489       expect(component.find('input.custom-class').length).toEqual(1);
490       expect(component.find('input').getDOMNode().type).toEqual('email');
491       expect(component.find('input').getDOMNode().placeholder).toEqual(
492         'custom-placeholder'
493       );
494     });
290be5 495
de3fe1 496     it('renderInput', () => {
SE 497       const renderInput = (props, openCalendar) => {
498         return (
499           <div>
500             <input {...props} />
501             <button className="custom-open" onClick={openCalendar}>
502               open calendar
503             </button>
504           </div>
505         );
506       };
507       const component = utils.createDatetime({ renderInput });
b6f2dd 508
de3fe1 509       expect(component.find('button.custom-open').length).toEqual(1);
SE 510       expect(utils.isOpen(component)).toBeFalsy();
511       utils.clickOnElement(component.find('button.custom-open'));
512       expect(utils.isOpen(component)).toBeTruthy();
513     });
b6f2dd 514
de3fe1 515     it('renderDay', () => {
SE 516       let props = {},
517         currentDate = '',
518         selectedDate = '';
519       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
520         mDate = moment(date),
521         renderDayFn = (fnProps, current, selected) => {
522           props = fnProps;
523           currentDate = current;
524           selectedDate = selected;
290be5 525
de3fe1 526           return <td {...fnProps}>custom-content</td>;
SE 527         };
290be5 528
de3fe1 529       const component = utils.createDatetime({
SE 530         value: mDate,
531         renderDay: renderDayFn
532       });
290be5 533
de3fe1 534       // Last day should be 6th of february
SE 535       expect(currentDate.day()).toEqual(6);
536       expect(currentDate.month()).toEqual(1);
290be5 537
de3fe1 538       // The date must be the same
SE 539       expect(selectedDate.isSame(mDate)).toEqual(true);
290be5 540
de3fe1 541       // There should be a onClick function in the props
SE 542       expect(typeof props.onClick).toEqual('function');
290be5 543
de3fe1 544       // The cell text should match
SE 545       expect(
546         component
547           .find('.rdtDay')
548           .at(0)
549           .text()
550       ).toEqual('custom-content');
551     });
290be5 552
de3fe1 553     it('renderMonth', () => {
SE 554       let props = {},
555         month = '',
556         year = '',
557         selectedDate = '';
558       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
559         mDate = moment(date),
560         renderMonthFn = (fnProps, fnMonth, fnYear, selected) => {
561           props = fnProps;
562           month = fnMonth;
563           year = fnYear;
564           selectedDate = selected;
290be5 565
de3fe1 566           return <td {...fnProps}>custom-content</td>;
SE 567         };
290be5 568
de3fe1 569       const component = utils.createDatetime({
SE 570         value: mDate,
571         viewMode: 'months',
572         renderMonth: renderMonthFn
573       });
290be5 574
de3fe1 575       expect(month).toEqual(11);
SE 576       expect(year).toEqual(2000);
290be5 577
de3fe1 578       // The date must be the same
SE 579       expect(selectedDate.isSame(mDate)).toEqual(true);
290be5 580
de3fe1 581       // There should be a onClick function in the props
SE 582       expect(typeof props.onClick).toEqual('function');
290be5 583
de3fe1 584       // The cell text should match
SE 585       expect(
586         component
587           .find('.rdtMonth')
588           .at(0)
589           .text()
590       ).toEqual('custom-content');
591     });
290be5 592
de3fe1 593     it('renderYear', () => {
SE 594       let props = {},
595         year = '',
596         selectedDate = '';
597       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
598         mDate = moment(date),
599         renderYearFn = (fnProps, fnYear, selected) => {
600           props = fnProps;
601           year = fnYear;
602           selectedDate = selected;
290be5 603
de3fe1 604           return <td {...fnProps}>custom-content</td>;
SE 605         };
290be5 606
de3fe1 607       const component = utils.createDatetime({
SE 608         value: mDate,
609         viewMode: 'years',
610         renderYear: renderYearFn
611       });
290be5 612
de3fe1 613       expect(year).toEqual(2010);
290be5 614
de3fe1 615       // The date must be the same
SE 616       expect(selectedDate.isSame(mDate)).toEqual(true);
290be5 617
de3fe1 618       // There should be a onClick function in the props
SE 619       expect(typeof props.onClick).toEqual('function');
290be5 620
de3fe1 621       // The cell text should match
SE 622       expect(
623         component
624           .find('.rdtYear')
625           .at(0)
626           .text()
627       ).toEqual('custom-content');
628     });
290be5 629
de3fe1 630     it('closeOnTab=true', () => {
SE 631       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
632         component = utils.createDatetime({ value: date });
290be5 633
de3fe1 634       expect(utils.isOpen(component)).toBeFalsy();
SE 635       utils.openDatepicker(component);
636       expect(utils.isOpen(component)).toBeTruthy();
637       component
638         .find('.form-control')
639         .simulate('keyDown', { key: 'Tab', keyCode: 9, which: 9 });
640       expect(utils.isOpen(component)).toBeFalsy();
641     });
290be5 642
de3fe1 643     it('closeOnTab=false', () => {
SE 644       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
645         component = utils.createDatetime({ value: date, closeOnTab: false });
290be5 646
de3fe1 647       expect(utils.isOpen(component)).toBeFalsy();
SE 648       utils.openDatepicker(component);
649       expect(utils.isOpen(component)).toBeTruthy();
650       component
651         .find('.form-control')
652         .simulate('keyDown', { key: 'Tab', keyCode: 9, which: 9 });
653       expect(utils.isOpen(component)).toBeTruthy();
654     });
290be5 655
de3fe1 656     it('increase time', () => {
SE 657       let i = 0;
658       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
659         component = utils.createDatetime({
660           timeFormat: 'HH:mm:ss:SSS',
661           viewMode: 'time',
662           defaultValue: date,
663           onChange: (selected) => {
664             // TODO: Trigger onChange when increasing time
665             i++;
666             if (i > 2) {
667               expect(true).toEqual(false); // Proof that this is not called
668               expect(selected.hour()).toEqual(3);
669               expect(selected.minute()).toEqual(3);
670               expect(selected.second()).toEqual(3);
671               done();
672             }
673           }
674         });
290be5 675
de3fe1 676       // Check hour
SE 677       expect(utils.getHours(component)).toEqual('2');
678       utils.increaseHour(component);
679       expect(utils.getHours(component)).toEqual('3');
290be5 680
de3fe1 681       // Check minute
SE 682       expect(utils.getMinutes(component)).toEqual('02');
683       utils.increaseMinute(component);
684       expect(utils.getMinutes(component)).toEqual('03');
290be5 685
de3fe1 686       // Check second
SE 687       expect(utils.getSeconds(component)).toEqual('02');
688       utils.increaseSecond(component);
689       expect(utils.getSeconds(component)).toEqual('03');
690     });
290be5 691
de3fe1 692     it('decrease time', () => {
SE 693       let i = 0;
694       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
695         component = utils.createDatetime({
696           timeFormat: 'HH:mm:ss:SSS',
697           viewMode: 'time',
698           defaultValue: date,
699           onChange: (selected) => {
700             // TODO: Trigger onChange when increasing time
701             i++;
702             if (i > 2) {
703               expect(true).toEqual(false); // Proof that this is not called
704               expect(selected.hour()).toEqual(1);
705               expect(selected.minute()).toEqual(1);
706               expect(selected.second()).toEqual(1);
707               done();
708             }
709           }
710         });
290be5 711
de3fe1 712       // Check hour
SE 713       expect(utils.getHours(component)).toEqual('2');
714       utils.decreaseHour(component);
715       expect(utils.getHours(component)).toEqual('1');
290be5 716
de3fe1 717       // Check minute
SE 718       expect(utils.getMinutes(component)).toEqual('02');
719       utils.decreaseMinute(component);
720       expect(utils.getMinutes(component)).toEqual('01');
290be5 721
de3fe1 722       // Check second
SE 723       expect(utils.getSeconds(component)).toEqual('02');
724       utils.decreaseSecond(component);
725       expect(utils.getSeconds(component)).toEqual('01');
726     });
290be5 727
de3fe1 728     it('long increase time', (done) => {
SE 729       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
730         component = utils.createDatetime({
731           timeFormat: 'HH:mm:ss:SSS',
732           viewMode: 'time',
733           defaultValue: date
734         });
290be5 735
de3fe1 736       utils.increaseHour(component);
SE 737       setTimeout(() => {
738         expect(utils.getHours(component)).not.toEqual('2');
739         expect(utils.getHours(component)).not.toEqual('3');
740         done();
741       }, 920);
742     });
290be5 743
de3fe1 744     it('long decrease time', (done) => {
SE 745       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
746         component = utils.createDatetime({
747           timeFormat: 'HH:mm:ss:SSS',
748           viewMode: 'time',
749           defaultValue: date
750         });
290be5 751
de3fe1 752       utils.decreaseHour(component);
SE 753       setTimeout(() => {
754         expect(utils.getHours(component)).not.toEqual('1');
755         expect(utils.getHours(component)).not.toEqual('0');
756         done();
757       }, 920);
758     });
290be5 759
de3fe1 760     it('timeConstraints -> increase time', () => {
SE 761       let i = 0;
762       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
763         component = utils.createDatetime({
764           timeFormat: 'HH:mm:ss:SSS',
765           viewMode: 'time',
766           defaultValue: date,
767           timeConstraints: {
768             hours: { max: 6, step: 8 },
769             minutes: { step: 15 }
770           },
771           onChange: (selected) => {
772             // TODO
773             i++;
774             if (i > 2) {
775               expect(selected.minute()).toEqual(17);
776               expect(selected.second()).toEqual(3);
777               done();
778             }
779           }
780         });
290be5 781
de3fe1 782       utils.increaseHour(component);
SE 783       expect(utils.getHours(component)).toEqual('3');
290be5 784
de3fe1 785       utils.increaseMinute(component);
SE 786       expect(utils.getMinutes(component)).toEqual('17');
290be5 787
de3fe1 788       utils.increaseSecond(component);
SE 789       expect(utils.getSeconds(component)).toEqual('03');
790     });
290be5 791
de3fe1 792     it('timeConstraints -> decrease time', () => {
SE 793       let i = 0;
794       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
795         component = utils.createDatetime({
796           timeFormat: 'HH:mm:ss:SSS',
797           viewMode: 'time',
798           defaultValue: date,
799           timeConstraints: { minutes: { step: 15 } },
800           onChange: (selected) => {
801             // TODO
802             i++;
803             if (i > 2) {
804               expect(selected.minute()).toEqual(17);
805               expect(selected.second()).toEqual(3);
806               done();
807             }
808           }
809         });
290be5 810
de3fe1 811       utils.decreaseMinute(component);
SE 812       expect(utils.getMinutes(component)).toEqual('47');
813     });
290be5 814
de3fe1 815     it('strictParsing=true', (done) => {
SE 816       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
817         mDate = moment(date),
818         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
819         invalidStrDate = strDate + 'x',
820         component = utils.createDatetime({
821           defaultValue: '',
822           strictParsing: true,
823           onChange: (updated) => {
824             expect(updated, invalidStrDate);
825             done();
826           }
827         });
290be5 828
de3fe1 829       component
SE 830         .find('.form-control')
831         .simulate('change', { target: { value: invalidStrDate } });
832     });
290be5 833
de3fe1 834     it('strictParsing=false', (done) => {
SE 835       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
836         mDate = moment(date),
837         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
838         invalidStrDate = strDate + 'x',
839         component = utils.createDatetime({
840           defaultValue: '',
841           strictParsing: false,
842           onChange: (updated) => {
843             expect(mDate.format('L LT')).toEqual(updated.format('L LT'));
844             done();
845           }
846         });
290be5 847
de3fe1 848       component
SE 849         .find('.form-control')
850         .simulate('change', { target: { value: invalidStrDate } });
851     });
290be5 852
de3fe1 853     it('isValidDate -> disable months', () => {
SE 854       const dateBefore = new Date().getFullYear() + '-06-01',
855         component = utils.createDatetime({
856           viewMode: 'months',
857           isValidDate: (current) =>
858             current.isBefore(moment(dateBefore, 'YYYY-MM-DD'))
859         });
290be5 860
de3fe1 861       expect(utils.getNthMonth(component, 0).hasClass('rdtDisabled')).toEqual(
SE 862         false
863       );
864       expect(utils.getNthMonth(component, 4).hasClass('rdtDisabled')).toEqual(
865         false
866       );
867       expect(utils.getNthMonth(component, 5).hasClass('rdtDisabled')).toEqual(
868         true
869       );
870       expect(utils.getNthMonth(component, 11).hasClass('rdtDisabled')).toEqual(
871         true
872       );
873     });
290be5 874
de3fe1 875     it('isValidDate -> disable years', () => {
SE 876       const component = utils.createDatetime({
877         viewMode: 'years',
878         isValidDate: (current) =>
879           current.isBefore(moment('2016-01-01', 'YYYY-MM-DD'))
880       });
290be5 881
de3fe1 882       expect(utils.getNthYear(component, 0).hasClass('rdtDisabled')).toEqual(
SE 883         false
884       );
885       expect(utils.getNthYear(component, 6).hasClass('rdtDisabled')).toEqual(
886         false
887       );
888       expect(utils.getNthYear(component, 7).hasClass('rdtDisabled')).toEqual(
889         true
890       );
891     });
290be5 892
de3fe1 893     it('locale', () => {
SE 894       const component = utils.createDatetime({ locale: 'nl' }),
895         expectedWeekDays = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'],
896         actualWeekDays = component
897           .find('.rdtDays .dow')
898           .map((element) => element.text().toLowerCase());
290be5 899
de3fe1 900       expect(actualWeekDays).toEqual(expectedWeekDays);
SE 901     });
290be5 902
de3fe1 903     it('locale with viewMode=months', () => {
SE 904       const component = utils.createDatetime({
905           locale: 'nl',
906           viewMode: 'months'
907         }),
908         expectedMonths = ['Mrt', 'Mei'],
909         actualMonths = [
910           utils.getNthMonth(component, 2).text(),
911           utils.getNthMonth(component, 4).text()
912         ];
290be5 913
de3fe1 914       expect(actualMonths).toEqual(expectedMonths);
SE 915     });
290be5 916
de3fe1 917     it('closeOnSelect=false', (done) => {
SE 918       const component = utils.createDatetime({ closeOnSelect: false });
290be5 919
de3fe1 920       // A unknown race condition is causing this test to fail without this time out,
SE 921       // and when the test fails it says:
922       // 'Timeout - Async callback was not invoked within timeout'
923       // Ideally it would say something else but at least we know the tests are passing now
924       setTimeout(() => {
925         expect(utils.isOpen(component)).toBeFalsy();
926         utils.openDatepicker(component);
927         expect(utils.isOpen(component)).toBeTruthy();
928         utils.clickNthDay(component, 2);
929         expect(utils.isOpen(component)).toBeTruthy();
930         done();
931       }, 0);
932     });
290be5 933
de3fe1 934     it('closeOnSelect=true', (done) => {
SE 935       const component = utils.createDatetime({ closeOnSelect: true });
290be5 936
de3fe1 937       // A unknown race condition is causing this test to fail without this time out,
SE 938       // and when the test fails it says:
939       // 'Timeout - Async callback was not invoked within timeout'
940       // Ideally it would say something else but at least we know the tests are passing now
941       setTimeout(() => {
942         expect(utils.isOpen(component)).toBeFalsy();
943         utils.openDatepicker(component);
944         expect(utils.isOpen(component)).toBeTruthy();
945         utils.clickNthDay(component, 2);
946         expect(utils.isOpen(component)).toBeFalsy();
947         done();
948       }, 0);
949     });
290be5 950
de3fe1 951     describe('defaultValue of type', () => {
SE 952       it('date', () => {
953         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
954           momentDate = moment(date),
955           strDate = momentDate.format('L') + ' ' + momentDate.format('LT'),
956           component = utils.createDatetime({ defaultValue: date });
957         expect(utils.getInputValue(component)).toEqual(strDate);
958       });
290be5 959
de3fe1 960       it('moment', () => {
SE 961         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
962           momentDate = moment(date),
963           strDate = momentDate.format('L') + ' ' + momentDate.format('LT'),
964           component = utils.createDatetime({ defaultValue: momentDate });
965         expect(utils.getInputValue(component)).toEqual(strDate);
966       });
290be5 967
de3fe1 968       it('string', () => {
SE 969         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
970           momentDate = moment(date),
971           strDate = momentDate.format('L') + ' ' + momentDate.format('LT'),
972           component = utils.createDatetime({ defaultValue: strDate });
973         expect(utils.getInputValue(component)).toEqual(strDate);
974       });
975     });
290be5 976
de3fe1 977     describe('timeFormat with', () => {
SE 978       it('milliseconds', () => {
979         const component = utils.createDatetime({
980           viewMode: 'time',
981           timeFormat: 'HH:mm:ss:SSS'
982         });
983         expect(component.find('.rdtCounter').length).toEqual(4);
984         // TODO: Test that you can input a value in milli seconds input
985       });
64fc6a 986
de3fe1 987       it('seconds', () => {
SE 988         const component = utils.createDatetime({
989           viewMode: 'time',
990           timeFormat: 'HH:mm:ss'
991         });
992         expect(component.find('.rdtCounter').length).toEqual(3);
993       });
64fc6a 994
de3fe1 995       it('minutes', () => {
SE 996         const component = utils.createDatetime({
997           viewMode: 'time',
998           timeFormat: 'HH:mm'
999         });
1000         expect(component.find('.rdtCounter').length).toEqual(2);
1001       });
64fc6a 1002
de3fe1 1003       it('hours', () => {
SE 1004         const component = utils.createDatetime({
1005           viewMode: 'time',
1006           timeFormat: 'HH'
1007         });
1008         expect(component.find('.rdtCounter').length).toEqual(1);
1009       });
1010     });
64fc6a 1011
de3fe1 1012     describe('being updated and should trigger update', () => {
SE 1013       it('dateFormat -> value should change format', (done) => {
1014         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1015           component = utils.createDatetime({
1016             dateFormat: 'YYYY-MM-DD',
1017             timeFormat: false,
1018             defaultValue: date
1019           });
64fc6a 1020
de3fe1 1021         const valueBefore = utils.getInputValue(component);
SE 1022         // A unknown race condition is causing this test to fail without this time out,
1023         // and when the test fails it says:
1024         // 'Timeout - Async callback was not invoked within timeout'
1025         // Ideally it would say something else but at least we know the tests are passing now
1026         setTimeout(() => {
1027           component.setProps({ dateFormat: 'DD.MM.YYYY' });
1028           const valueAfter = utils.getInputValue(component);
64fc6a 1029
de3fe1 1030           expect(valueBefore).not.toEqual(valueAfter);
SE 1031           done();
1032         }, 0);
1033       });
64fc6a 1034
de3fe1 1035       it('UTC -> value should change format (true->false)', () => {
SE 1036         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1037           momentDate = moment(date),
1038           component = utils.createDatetime({ value: momentDate, utc: true });
64fc6a 1039
de3fe1 1040         const valueBefore = utils.getInputValue(component);
SE 1041         component.setProps({ utc: false }, () => {
1042           const valueAfter = utils.getInputValue(component);
64fc6a 1043
de3fe1 1044           expect(valueBefore).not.toEqual(valueAfter);
SE 1045         });
1046       });
64fc6a 1047
de3fe1 1048       it('UTC -> value should change format (false->true)', () => {
SE 1049         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1050           momentDate = moment(date),
1051           component = utils.createDatetime({ value: momentDate, utc: false });
64fc6a 1052
de3fe1 1053         const valueBefore = utils.getInputValue(component);
SE 1054         component.setProps({ utc: true }, () => {
1055           const valueAfter = utils.getInputValue(component);
64fc6a 1056
de3fe1 1057           expect(valueBefore).not.toEqual(valueAfter);
SE 1058         });
1059       });
64fc6a 1060
de3fe1 1061       it('locale -> picker should change language (viewMode=days)', () => {
SE 1062         const component = utils.createDatetime({
1063             viewMode: 'days',
1064             locale: 'nl'
1065           }),
1066           weekdaysBefore = component
1067             .find('.rdtDays .dow')
1068             .map((element) => element.text());
64fc6a 1069
de3fe1 1070         component.setProps({ locale: 'sv' });
SE 1071         const weekdaysAfter = component
1072           .find('.rdtDays .dow')
1073           .map((element) => element.text());
64fc6a 1074
de3fe1 1075         expect(weekdaysBefore).not.toEqual(weekdaysAfter);
SE 1076       });
290be5 1077
de3fe1 1078       it('locale -> picker should change language (viewMode=months)', () => {
SE 1079         const component = utils.createDatetime({
1080             viewMode: 'months',
1081             locale: 'nl'
1082           }),
1083           monthsBefore = [
1084             utils.getNthMonth(component, 2).text(),
1085             utils.getNthMonth(component, 4).text()
1086           ];
290be5 1087
de3fe1 1088         component.setProps({ locale: 'sv' });
SE 1089         const monthsAfter = [
1090           utils.getNthMonth(component, 2).text(),
1091           utils.getNthMonth(component, 4).text()
1092         ];
39e146 1093
de3fe1 1094         expect(monthsBefore).not.toEqual(monthsAfter);
SE 1095       });
1096     });
1097   });
39e146 1098
de3fe1 1099   describe('event listeners', () => {
SE 1100     describe('onBlur', () => {
1101       it('when selecting a date', () => {
1102         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1103           onBlurFn = jest.fn(),
1104           component = utils.createDatetime({
1105             value: date,
1106             onBlur: onBlurFn,
1107             closeOnSelect: true
1108           });
39e146 1109
de3fe1 1110         utils.openDatepicker(component);
SE 1111         // Close component by selecting a date
1112         utils.clickNthDay(component, 2);
1113         expect(onBlurFn).toHaveBeenCalledTimes(1);
1114       });
39e146 1115
de3fe1 1116       it('when selecting date (value=null and closeOnSelect=true)', () => {
SE 1117         const onBlurFn = jest.fn(),
1118           component = utils.createDatetime({
1119             value: null,
1120             onBlur: onBlurFn,
1121             closeOnSelect: true
1122           });
794700 1123
de3fe1 1124         utils.openDatepicker(component);
SE 1125         // Close component by selecting a date
1126         utils.clickNthDay(component, 2);
1127         expect(onBlurFn).toHaveBeenCalledTimes(1);
1128       });
290be5 1129
de3fe1 1130       it('when selecting date (value=null and closeOnSelect=false)', () => {
SE 1131         const onBlurFn = jest.fn(),
1132           component = utils.createDatetime({
1133             value: null,
1134             onBlur: onBlurFn,
1135             closeOnSelect: false
1136           });
290be5 1137
de3fe1 1138         utils.openDatepicker(component);
SE 1139         // Close component by selecting a date
1140         utils.clickNthDay(component, 2);
1141         expect(onBlurFn).not.toHaveBeenCalled();
1142       });
1143     });
5377a9 1144
de3fe1 1145     it('onFocus when opening datepicker', () => {
SE 1146       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1147         onFocusFn = jest.fn(),
1148         component = utils.createDatetime({ value: date, onFocus: onFocusFn });
5377a9 1149
de3fe1 1150       utils.openDatepicker(component);
SE 1151       expect(onFocusFn).toHaveBeenCalledTimes(1);
1152     });
5377a9 1153
de3fe1 1154     describe('onViewModeChange', () => {
SE 1155       it('when switch from days to time view mode', () => {
1156         const component = utils.createDatetime({
1157           onViewModeChange: (viewMode) => {
1158             expect(viewMode).toEqual('time');
1159           }
1160         });
1161         expect(utils.isDayView(component)).toBeTruthy();
1162         utils.clickOnElement(component.find('.rdtTimeToggle'));
1163         expect(utils.isTimeView(component)).toBeTruthy();
1164       });
5377a9 1165
de3fe1 1166       it('when switch from time to days view mode', () => {
SE 1167         const component = utils.createDatetime({
1168           viewMode: 'time',
1169           onViewModeChange: (viewMode) => {
1170             expect(viewMode).toEqual('days');
1171           }
1172         });
1173         expect(utils.isTimeView(component)).toBeTruthy();
1174         utils.clickOnElement(component.find('.rdtSwitch'));
1175         expect(utils.isDayView(component)).toBeTruthy();
1176       });
5377a9 1177
de3fe1 1178       it('when switch from days to months view mode', () => {
SE 1179         const component = utils.createDatetime({
1180           onViewModeChange: (viewMode) => {
1181             expect(viewMode).toEqual('months');
1182           }
1183         });
1184         expect(utils.isDayView(component)).toBeTruthy();
1185         utils.clickOnElement(component.find('.rdtSwitch'));
1186         expect(utils.isMonthView(component)).toBeTruthy();
1187       });
5377a9 1188
de3fe1 1189       it('when switch from months to years view mode', () => {
SE 1190         const component = utils.createDatetime({
1191           viewMode: 'months',
1192           onViewModeChange: (viewMode) => {
1193             expect(viewMode).toEqual('years');
1194           }
1195         });
1196         expect(utils.isMonthView(component)).toBeTruthy();
1197         utils.clickOnElement(component.find('.rdtSwitch'));
1198         expect(utils.isYearView(component)).toBeTruthy();
1199       });
290be5 1200
de3fe1 1201       it('only when switch from years to months view mode', () => {
SE 1202         const component = utils.createDatetime({
1203           viewMode: 'years',
1204           onViewModeChange: (viewMode) => {
1205             expect(viewMode).toEqual('months');
1206           }
1207         });
1208         expect(utils.isYearView(component)).toBeTruthy();
1209         utils.clickOnElement(component.find('.rdtSwitch'));
1210         expect(utils.isYearView(component)).toBeTruthy();
1211         utils.clickNthYear(component, 2);
1212         expect(utils.isMonthView(component)).toBeTruthy();
1213       });
290be5 1214
de3fe1 1215       it('when switch from months to days view mode', () => {
SE 1216         const component = utils.createDatetime({
1217           viewMode: 'months',
1218           onViewModeChange: (viewMode) => {
1219             expect(viewMode).toEqual('days');
1220           }
1221         });
1222         expect(utils.isMonthView(component)).toBeTruthy();
1223         utils.clickNthMonth(component, 2);
1224         expect(utils.isDayView(component)).toBeTruthy();
1225       });
1226     });
39e146 1227
de3fe1 1228     describe('onChange', () => {
SE 1229       it('trigger only when last selection type is selected', () => {
1230         // By selection type I mean if you CAN select day, then selecting a month
1231         // should not trigger onChange
1232         const onChangeFn = jest.fn(),
1233           component = utils.createDatetime({
1234             viewMode: 'years',
1235             onChange: onChangeFn
1236           });
39e146 1237
de3fe1 1238         utils.openDatepicker(component);
39e146 1239
de3fe1 1240         utils.clickNthYear(component, 2);
SE 1241         expect(onChangeFn).not.toHaveBeenCalled();
290be5 1242
de3fe1 1243         utils.clickNthMonth(component, 2);
SE 1244         expect(onChangeFn).not.toHaveBeenCalled();
39e146 1245
de3fe1 1246         utils.clickNthDay(component, 2);
SE 1247         expect(onChangeFn).toHaveBeenCalled();
1248       });
39e146 1249
de3fe1 1250       it('when selecting date', (done) => {
SE 1251         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1252           mDate = moment(date),
1253           component = utils.createDatetime({
1254             defaultValue: date,
1255             onChange: (selected) => {
1256               expect(selected.date()).toEqual(2);
1257               expect(selected.month()).toEqual(mDate.month());
1258               expect(selected.year()).toEqual(mDate.year());
1259               done();
1260             }
1261           });
39e146 1262
de3fe1 1263         utils.clickNthDay(component, 7);
SE 1264       });
39e146 1265
de3fe1 1266       it('when selecting multiple date in a row', (done) => {
SE 1267         let i = 0;
1268         const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1269           mDate = moment(date),
1270           component = utils.createDatetime({
1271             defaultValue: date,
1272             onChange: (selected) => {
1273               i++;
1274               if (i > 2) {
1275                 expect(selected.date()).toEqual(4);
1276                 expect(selected.month()).toEqual(mDate.month());
1277                 expect(selected.year()).toEqual(mDate.year());
1278                 done();
1279               }
1280             }
1281           });
39e146 1282
de3fe1 1283         utils.clickNthDay(component, 7);
SE 1284         utils.clickNthDay(component, 8);
1285         utils.clickNthDay(component, 9);
1286       });
39e146 1287
de3fe1 1288       it('when selecting month', () => {
SE 1289         const date = Date.UTC(2000, 0, 15, 2, 2, 2, 2),
1290           onChangeFn = jest.fn(),
1291           component = utils.createDatetime({
1292             defaultValue: date,
1293             dateFormat: 'YYYY-MM',
1294             onChange: onChangeFn
1295           });
39e146 1296
de3fe1 1297         utils.clickNthMonth(component, 2);
SE 1298         expect(onChangeFn).toHaveBeenCalledTimes(1);
1299         expect(onChangeFn.mock.calls[0][0].toJSON()).toEqual(
1300           '2000-03-15T02:02:02.002Z'
1301         );
1302       });
39e146 1303
de3fe1 1304       xit('when selecting year', () => {
SE 1305         const date = Date.UTC(2000, 0, 15, 2, 2, 2, 2),
1306           onChangeFn = jest.fn(),
1307           component = utils.createDatetime({
1308             defaultValue: date,
1309             dateFormat: 'YYYY',
1310             onChange: onChangeFn
1311           });
39e146 1312
de3fe1 1313         utils.clickNthYear(component, 2);
SE 1314         expect(onChangeFn).toHaveBeenCalledTimes(1);
1315         expect(onChangeFn.mock.calls[0][0].toJSON()).toEqual(
1316           '2001-01-15T02:02:02.002Z'
1317         );
1318       });
290be5 1319
de3fe1 1320       it('when selecting time', () => {
SE 1321         // Did not manage to be able to get onChange to trigger, even though I know it does.
1322         // The listener for the time buttons are set up differently because of having to handle both
1323         // onMouseDown and onMouseUp. Not sure how to test it.
1324         expect(true).toEqual(true);
1325       });
1326     });
1327   });
290be5 1328
de3fe1 1329   describe('with set value', () => {
SE 1330     it('date value', () => {
1331       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1332         mDate = moment(date),
1333         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
1334         component = utils.createDatetime({ value: date });
1335       expect(utils.getInputValue(component)).toEqual(strDate);
1336     });
290be5 1337
de3fe1 1338     it('moment value', () => {
SE 1339       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1340         mDate = moment(date),
1341         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
1342         component = utils.createDatetime({ value: mDate });
1343       expect(utils.getInputValue(component)).toEqual(strDate);
1344     });
290be5 1345
de3fe1 1346     it('string value', () => {
SE 1347       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1348         mDate = moment(date),
1349         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
1350         component = utils.createDatetime({ value: strDate });
1351       expect(utils.getInputValue(component)).toEqual(strDate);
1352     });
290be5 1353
de3fe1 1354     it('UTC value from local moment', () => {
SE 1355       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1356         momentDate = moment(date),
1357         momentDateUTC = moment.utc(date),
1358         strDateUTC =
1359           momentDateUTC.format('L') + ' ' + momentDateUTC.format('LT'),
1360         component = utils.createDatetime({ value: momentDate, utc: true });
1361       expect(utils.getInputValue(component)).toEqual(strDateUTC);
1362     });
290be5 1363
de3fe1 1364     it('UTC value from UTC moment', () => {
SE 1365       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1366         momentDateUTC = moment.utc(date),
1367         strDateUTC =
1368           momentDateUTC.format('L') + ' ' + momentDateUTC.format('LT'),
1369         component = utils.createDatetime({ value: momentDateUTC, utc: true });
1370       expect(utils.getInputValue(component)).toEqual(strDateUTC);
1371     });
290be5 1372
de3fe1 1373     it('UTC value from UTC string', () => {
SE 1374       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1375         momentDateUTC = moment.utc(date),
1376         strDateUTC =
1377           momentDateUTC.format('L') + ' ' + momentDateUTC.format('LT'),
1378         component = utils.createDatetime({ value: strDateUTC, utc: true });
1379       expect(utils.getInputValue(component)).toEqual(strDateUTC);
1380     });
290be5 1381
de3fe1 1382     it('invalid string value', (done) => {
SE 1383       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1384         mDate = moment(date),
1385         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
1386         component = utils.createDatetime({
1387           defaultValue: 'invalid-value',
1388           onChange: (updated) => {
1389             expect(mDate.format('L LT')).toEqual(updated.format('L LT'));
1390             done();
1391           }
1392         });
290be5 1393
de3fe1 1394       expect(component.find('.form-control').getDOMNode().value).toEqual(
SE 1395         'invalid-value'
1396       );
1397       component
1398         .find('.form-control')
1399         .simulate('change', { target: { value: strDate } });
1400     });
290be5 1401
de3fe1 1402     it('delete invalid string value', (done) => {
SE 1403       const date = new Date(2000, 0, 15, 2, 2, 2, 2),
1404         component = utils.createDatetime({
1405           defaultValue: date,
1406           onChange: (date) => {
1407             expect(date).toEqual('');
1408             done();
1409           }
1410         });
290be5 1411
de3fe1 1412       component
SE 1413         .find('.form-control')
1414         .simulate('change', { target: { value: '' } });
1415     });
290be5 1416
de3fe1 1417     it('invalid moment object', (done) => {
SE 1418       const invalidValue = moment(null),
1419         date = new Date(2000, 0, 15, 2, 2, 2, 2),
1420         mDate = moment(date),
1421         strDate = mDate.format('L') + ' ' + mDate.format('LT'),
1422         component = utils.createDatetime({
1423           value: invalidValue,
1424           onChange: (updated) => {
1425             expect(mDate.format('L LT')).toEqual(updated.format('L LT'));
1426             done();
1427           }
1428         });
290be5 1429
de3fe1 1430       expect(component.find('.form-control').getDOMNode().value).toEqual('');
SE 1431       component
1432         .find('.form-control')
1433         .simulate('change', { target: { value: strDate } });
1434     });
1435   });
290be5 1436 });