From 6bc2cae6ce4790ee1655a23070fa5f72ce2e1749 Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Fri, 17 Jan 2020 13:30:52 +0200 Subject: [PATCH 1/3] test(calendar): refactoring calendar tests #6453 --- .../src/lib/calendar/calendar-helper-utils.ts | 145 +++ .../calendar-multi-view.component.spec.ts | 230 ++--- .../lib/calendar/calendar.component.spec.ts | 824 ++++++++---------- 3 files changed, 565 insertions(+), 634 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts b/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts new file mode 100644 index 00000000000..2bc4085d77c --- /dev/null +++ b/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts @@ -0,0 +1,145 @@ +import { By } from '@angular/platform-browser'; + +export class HelperTestFunctions { + public static DAYS_VIEW = 'igx-days-view'; + public static CALENDAR = 'igx-calendar'; + public static ICON_CSSCLASS = '.igx-icon'; + public static OVERLAY_CSSCLASS = '.igx-overlay'; + public static MODAL_OVERLAY_CSSCLASS = 'igx-overlay__wrapper--modal'; + + public static CALENDAR_CSSCLASS = '.igx-calendar'; + public static CALENDAR_HEADER_CSSCLASS = '.igx-calendar__header'; + public static CALENDAR_HEADER_YEAR_CSSCLASS = '.igx-calendar__header-year'; + public static CALENDAR_HEADER_DATE_CSSCLASS = '.igx-calendar__header-date'; + public static WEEKSTART_LABEL_CSSCLASS = '.igx-calendar__label'; + public static VERTICAL_CALENDAR_CSSCLASS = '.igx-calendar--vertical'; + public static DAY_CSSCLASS = '.igx-calendar__date'; + public static CURRENT_DATE_CSSCLASS = '.igx-calendar__date--current'; + public static INACTIVE_DAYS_CSSCLASS = '.igx-calendar__date--inactive'; + public static HIDDEN_DAYS_CSSCLASS = '.igx-calendar__date--hidden'; + public static SELECTED_DATE_CSSCLASS = '.igx-calendar__date--selected'; + public static RANGE_CSSCLASS = 'igx-calendar__date--range'; + public static CALENDAR_ROW_CSSCLASS = '.igx-calendar__body-row'; + public static CALENDAR_ROW_WRAP_CSSCLASS = '.igx-calendar__body-row--wrap'; + public static CALENDAR_COLUMN_CSSCLASS = '.igx-calendar__body-column'; + public static MONTH_CSSCLASS = '.igx-calendar__month'; + public static CURRENT_MONTH_CSSCLASS = '.igx-calendar__month--current'; + public static YEAR_CSSCLASS = '.igx-calendar__year'; + public static CURRENT_YEAR_CSSCLASS = '.igx-calendar__year--current'; + + public static CALENDAR_PREV_BUTTON_CSSCLASS = '.igx-calendar-picker__prev'; + public static CALENDAR_NEXT_BUTTON_CSSCLASS = '.igx-calendar-picker__next'; + public static CALENDAR_DATE_CSSCLASS = '.igx-calendar-picker__date'; + + public static CALENDAR_SUBHEADERS_SELECTOR = + 'div:not(' + HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS + '):not(' + HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS + ')'; + + public static verifyMonthsViewNumber(fixture, monthsView: number, checkCurrentDate = false) { + const el = fixture.nativeElement ? fixture.nativeElement : fixture; + const daysView = el.querySelectorAll(HelperTestFunctions.DAYS_VIEW); + expect(daysView).toBeDefined(); + expect(daysView.length).toBe(monthsView); + const monthPickers = HelperTestFunctions.getCalendarSubHeader(el).querySelectorAll('div'); + expect(monthPickers.length).toBe(monthsView + 2); // plus the navigation arrows + if (checkCurrentDate) { + const currentDate = el.querySelector(HelperTestFunctions.CURRENT_DATE_CSSCLASS); + expect(currentDate).not.toBeNull(); + } + } + + public static verifyCalendarHeader(fixture, selectedDate: Date) { + const daysView = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_CSSCLASS); + expect(daysView).not.toBeNull(); + const year = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS); + expect(year).not.toBeNull(); + expect(Number(year.innerText)).toEqual(selectedDate.getFullYear()); + const date = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS); + expect(date).not.toBeNull(); + const dateParts = selectedDate.toUTCString().split(' '); // (weekday, date month year) + expect(date.children[0].innerText.trim()).toEqual(dateParts[0]); + expect(date.children[1].innerText.trim()).toEqual(dateParts[2] + ' ' + Number(dateParts[1])); + } + + public static verifyNoRangeSelectionCreated(fixture, monthNumber: number) { + expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--range')).toBeNull(); + expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--first')).toBeNull(); + expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--last')).toBeNull(); + } + + public static verifyCalendarSubHeader(fixture, monthNumber: number, viewDate: Date) { + const monthPickers = HelperTestFunctions.getCalendarSubHeader(fixture).querySelectorAll('div'); + const dateParts = viewDate.toString().split(' '); // weekday month day year + expect(monthPickers[monthNumber].children[0].innerHTML.trim()).toEqual(dateParts[1]); + expect(monthPickers[monthNumber].children[1].innerHTML.trim()).toEqual(dateParts[3]); + } + + public static verifyCalendarSubHeaders(fixture, viewDates: Date[]) { + const dom = fixture.nativeElement ? fixture.nativeElement : fixture; + const monthPickers = HelperTestFunctions.getCalendarSubHeader(dom).querySelectorAll(this.CALENDAR_SUBHEADERS_SELECTOR); + expect(monthPickers.length).toEqual(viewDates.length); + for (let index = 0; index < viewDates.length; index++) { + const dateParts = viewDates[index].toString().split(' '); // weekday month day year + expect(monthPickers[index].children[0].innerHTML.trim()).toEqual(dateParts[1]); + expect(monthPickers[index].children[1].innerHTML.trim()).toEqual(dateParts[3]); + } + } + + public static getHiddenDays(fixture, monthNumber: number) { + const monthView = HelperTestFunctions.getMonthView(fixture, monthNumber); + return monthView.querySelectorAll(HelperTestFunctions.HIDDEN_DAYS_CSSCLASS); + } + + public static getInactiveDays(fixture, monthNumber: number) { + const monthView = HelperTestFunctions.getMonthView(fixture, monthNumber); + return monthView.querySelectorAll(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS); + } + + public static getCalendarSubHeader(fixture): HTMLElement { + const element = fixture.nativeElement ? fixture.nativeElement : fixture; + return element.querySelector('div.igx-calendar-picker'); + } + + public static getMonthView(fixture, monthsViewNumber: number) { + const domEL = fixture.nativeElement ? fixture.nativeElement : fixture; + return domEL.querySelectorAll('igx-days-view')[monthsViewNumber]; + } + + public static getMonthViewDates(fixture, monthsViewNumber: number) { + const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); + return month.querySelectorAll(HelperTestFunctions.DAY_CSSCLASS); + } + + public static getMonthViewInactiveDates(fixture, monthsViewNumber: number) { + const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); + return month.querySelectorAll(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS); + } + + public static getMonthViewSelectedDates(fixture, monthsViewNumber: number) { + const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); + return month.querySelectorAll(HelperTestFunctions.SELECTED_DATE_CSSCLASS + + `:not(${HelperTestFunctions.HIDDEN_DAYS_CSSCLASS})`); + } + + public static getMonthsFromMonthView(fixture) { + return fixture.nativeElement.querySelector('igx-months-view') + .querySelectorAll('.igx-calendar__month, .igx-calendar__month--current'); + } + + public static getYearsFromYearView(fixture) { + return fixture.nativeElement.querySelector('igx-years-view') + .querySelectorAll('.igx-calendar__year, .igx-calendar__year--current'); + } + + public static getCurrentYearsFromYearView(fixture) { + return fixture.nativeElement.querySelector('igx-years-view') + .querySelector('.igx-calendar__year--current'); + } + + public static getNexArrowElement(fixture) { + return fixture.debugElement.query(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS)).nativeElement; + } + + public static getPreviousArrowElement(fixture) { + return fixture.debugElement.query(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS)).nativeElement; + } +} diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-multi-view.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar-multi-view.component.spec.ts index c6736f16b4a..533e0ff67ad 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-multi-view.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-multi-view.component.spec.ts @@ -3,12 +3,11 @@ import { TestBed, async, fakeAsync, tick } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { configureTestSuite } from '../test-utils/configure-suite'; -import { UIInteractions, wait } from '../test-utils/ui-interactions.spec'; -import { IgxCalendarComponent, IgxCalendarModule, WEEKDAYS } from './index'; +import { UIInteractions } from '../test-utils/ui-interactions.spec'; +import { IgxCalendarComponent, IgxCalendarModule } from './index'; import { IgxDatePickerComponent, IgxDatePickerModule } from '../date-picker/date-picker.component'; import { DateRangeType } from '../core/dates'; -import { By } from '@angular/platform-browser'; - +import { HelperTestFunctions } from './calendar-helper-utils'; describe('Multi-View Calendar - ', () => { let fixture, calendar; @@ -92,15 +91,15 @@ describe('Multi-View Calendar - ', () => { expect(calendar.monthsViewNumber).toBe(2); expect(HelperTestFunctions.getInactiveDays(fixture, 0).length).toBeGreaterThan(1); - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(0); expect(HelperTestFunctions.getInactiveDays(fixture, 1).length).toBeGreaterThan(1); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(0); calendar.hideOutsideDays = true; fixture.detectChanges(); - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(HelperTestFunctions.getInactiveDays(fixture, 0).length); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(HelperTestFunctions.getInactiveDays(fixture, 1).length); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(HelperTestFunctions.getInactiveDays(fixture, 0).length); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(HelperTestFunctions.getInactiveDays(fixture, 1).length); }); it('weekStart should be properly set to all month views', () => { @@ -125,7 +124,7 @@ describe('Multi-View Calendar - ', () => { calendar.vertical = true; fixture.detectChanges(); - const verticalCalendar = fixture.nativeElement.querySelector(HelperTestFunctions.VERICAL_CALENDAR_CSSCLASS); + const verticalCalendar = fixture.nativeElement.querySelector(HelperTestFunctions.VERTICAL_CALENDAR_CSSCLASS); expect(verticalCalendar).not.toBeNull(); const today = new Date(Date.now()); @@ -763,9 +762,9 @@ describe('Multi-View Calendar - ', () => { expect(document.activeElement).toEqual(monthDates[10]); })); - it('Verify that months increment/decrement continuously on enter keydown', (async () => { + it('Verify that months increment/decrement continuously on enter keydown', (fakeAsync(() => { calendar.monthsViewNumber = 2; - await wait(); + tick(100); fixture.detectChanges(); const dates = [new Date('2019-10-15'), new Date('2019-11-15'), new Date('2019-12-15'), new Date('2020-1-15'), new Date('2020-2-15'), new Date('2020-3-15'), new Date('2020-4-15')]; @@ -775,7 +774,7 @@ describe('Multi-View Calendar - ', () => { for (let i = 1; i < dates.length - 1; i++) { const arrowRight = HelperTestFunctions.getNexArrowElement(fixture); UIInteractions.simulateKeyDownEvent(arrowRight, 'Enter'); - await wait(300); + tick(100); fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [dates[i], dates[i + 1]]); @@ -783,16 +782,16 @@ describe('Multi-View Calendar - ', () => { for (let index = dates.length - 2; index > 0; index--) { const arrowLeft = HelperTestFunctions.getPreviousArrowElement(fixture); UIInteractions.simulateKeyDownEvent(arrowLeft, 'Enter'); - await wait(300); + tick(100); fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [dates[index - 1], dates[index]]); } - })); + }))); - it('Verify that months increment/decrement continiously on mouse down', (async () => { + it('Verify that months increment/decrement continuously on mouse down', (fakeAsync(() => { calendar.monthsViewNumber = 2; - await wait(); + tick(100); fixture.detectChanges(); const dates = [new Date('2019-10-15'), new Date('2019-11-15'), new Date('2019-12-15'), new Date('2020-1-15'), new Date('2020-2-15'), new Date('2020-3-15'), new Date('2020-4-15')]; @@ -802,7 +801,7 @@ describe('Multi-View Calendar - ', () => { for (let i = 1; i < dates.length - 1; i++) { const arrowRight = HelperTestFunctions.getNexArrowElement(fixture); UIInteractions.simulateMouseEvent('mousedown', arrowRight, 0, 0); - await wait(300); + tick(100); fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [dates[i], dates[i + 1]]); @@ -810,16 +809,16 @@ describe('Multi-View Calendar - ', () => { for (let index = dates.length - 2; index > 0; index--) { const arrowLeft = HelperTestFunctions.getPreviousArrowElement(fixture); UIInteractions.simulateMouseEvent('mousedown', arrowLeft, 0, 0); - await wait(300); + tick(100); fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [dates[index - 1], dates[index]]); } - })); + }))); - it('When navigating to a new month the selected date should not steal the focus', (async () => { + it('When navigating to a new month the selected date should not steal the focus', (fakeAsync (() => { calendar.monthsViewNumber = 2; - await wait(); + tick(100); fixture.detectChanges(); const dates = [new Date('2019-10-15'), new Date('2019-11-15'), new Date('2019-12-15')]; @@ -834,15 +833,16 @@ describe('Multi-View Calendar - ', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(arrowRight, 'Enter'); - await wait(600); + tick(100); fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [dates[1], dates[2]]); expect(document.activeElement).toEqual(arrowRight); - })); + }))); it('When select a new month - should come at correct position', fakeAsync(() => { - const monthPicker = HelperTestFunctions.getCalendarSubHeader(fixture).querySelectorAll('.igx-calendar-picker__date')[2]; + const monthPicker = HelperTestFunctions.getCalendarSubHeader(fixture) + .querySelectorAll(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)[2]; UIInteractions.simulateKeyDownEvent(monthPicker, 'Enter'); fixture.detectChanges(); tick(100); @@ -887,7 +887,8 @@ describe('Multi-View Calendar - ', () => { fixture.detectChanges(); HelperTestFunctions.verifyCalendarSubHeaders(fixture, [new Date('2019-12-12'), new Date('2020-1-1'), new Date('2020-2-2')]); - const monthPicker = HelperTestFunctions.getCalendarSubHeader(fixture).querySelectorAll('.igx-calendar-picker__date')[3]; + const monthPicker = HelperTestFunctions.getCalendarSubHeader(fixture) + .querySelectorAll(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)[3]; UIInteractions.simulateKeyDownEvent(monthPicker, 'Enter'); fixture.detectChanges(); tick(150); @@ -1011,7 +1012,7 @@ describe('Multi-View Calendar - ', () => { expect(HelperTestFunctions.getMonthViewSelectedDates(fixture, 1).length).toBe(0); }); - it('Multi/Single Selecion - select multiple dates should not create range', () => { + it('Multi/Single Selection - select multiple dates should not create range', () => { expect(calendar.hideOutsideDays).toBe(false); calendar.selection = 'multi'; fixture.detectChanges(); @@ -1042,26 +1043,26 @@ describe('Multi-View Calendar - ', () => { fixture.detectChanges(); expect(calendar.hideOutsideDays).toBe(false); - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(0); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(0); calendar.hideOutsideDays = true; fixture.detectChanges(); const firstMonthInactiveDays = HelperTestFunctions.getInactiveDays(fixture, 0).length; const secondMonthInactiveDays = HelperTestFunctions.getInactiveDays(fixture, 1).length; - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(firstMonthInactiveDays); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(secondMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(firstMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(secondMonthInactiveDays); calendar.selection = 'multi'; fixture.detectChanges(); - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(firstMonthInactiveDays); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(secondMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(firstMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(secondMonthInactiveDays); calendar.selection = 'range'; fixture.detectChanges(); - expect(HelperTestFunctions.getHiidenDays(fixture, 0).length).toBe(firstMonthInactiveDays); - expect(HelperTestFunctions.getHiidenDays(fixture, 1).length).toBe(secondMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 0).length).toBe(firstMonthInactiveDays); + expect(HelperTestFunctions.getHiddenDays(fixture, 1).length).toBe(secondMonthInactiveDays); }); it('should change days view when selecting an outside day', () => { @@ -1154,7 +1155,7 @@ describe('Multi-View Calendar - ', () => { expect(HelperTestFunctions.getMonthViewSelectedDates(fixture, 2).length).toBe(0); // november }); - it('ouside days should NOT be selected in all month views, when hideOutsideDays is false and selection is range', () => { + it('outside days should NOT be selected in all month views, when hideOutsideDays is false and selection is range', () => { spyOn(calendar.onSelection, 'emit'); calendar.selection = 'range'; fixture.detectChanges(); @@ -1232,17 +1233,17 @@ describe('Multi-View Calendar - ', () => { }); it('Verify opening Multi View Calendar from datepicker', fakeAsync(() => { - let target = fixture.nativeElement.querySelector('.igx-icon'); + let target = fixture.nativeElement.querySelector(HelperTestFunctions.ICON_CSSCLASS); UIInteractions.clickElement(target); tick(400); fixture.detectChanges(); - let overlay = document.querySelector('.igx-overlay'); + let overlay = document.querySelector(HelperTestFunctions.OVERLAY_CSSCLASS); HelperTestFunctions.verifyMonthsViewNumber(overlay, 3); HelperTestFunctions.verifyCalendarSubHeaders(overlay, [new Date('2019-09-16'), new Date('2019-10-16'), new Date('2019-11-16')]); // close the datePicker - const overlayDiv = document.getElementsByClassName('igx-overlay__wrapper--modal')[0]; + const overlayDiv = document.getElementsByClassName(HelperTestFunctions.MODAL_OVERLAY_CSSCLASS)[0]; UIInteractions.clickElement(overlayDiv); tick(400); fixture.detectChanges(); @@ -1252,30 +1253,30 @@ describe('Multi-View Calendar - ', () => { tick(); fixture.detectChanges(); - target = fixture.nativeElement.querySelector('.igx-icon'); + target = fixture.nativeElement.querySelector(HelperTestFunctions.ICON_CSSCLASS); UIInteractions.clickElement(target); tick(400); fixture.detectChanges(); - overlay = document.querySelector('.igx-overlay'); + overlay = document.querySelector(HelperTestFunctions.OVERLAY_CSSCLASS); HelperTestFunctions.verifyMonthsViewNumber(overlay, 2); HelperTestFunctions.verifyCalendarSubHeaders(overlay, [new Date('2019-09-16'), new Date('2019-10-16')]); })); it('Verify setting hideOutsideDays and monthsViewNumber from datepicker', fakeAsync(() => { - const target = fixture.nativeElement.querySelector('.igx-icon'); + const target = fixture.nativeElement.querySelector(HelperTestFunctions.ICON_CSSCLASS); UIInteractions.clickElement(target); tick(400); fixture.detectChanges(); expect(datePicker.hideOutsideDays).toBe(true); - let overlay = document.querySelector('.igx-overlay'); - expect(HelperTestFunctions.getHiidenDays(overlay, 0).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 0).length); - expect(HelperTestFunctions.getHiidenDays(overlay, 1).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 1).length); - expect(HelperTestFunctions.getHiidenDays(overlay, 2).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 2).length); + let overlay = document.querySelector(HelperTestFunctions.OVERLAY_CSSCLASS); + expect(HelperTestFunctions.getHiddenDays(overlay, 0).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 0).length); + expect(HelperTestFunctions.getHiddenDays(overlay, 1).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 1).length); + expect(HelperTestFunctions.getHiddenDays(overlay, 2).length).toBe(HelperTestFunctions.getInactiveDays(overlay, 2).length); // close the datePicker - const overlayDiv = document.getElementsByClassName('igx-overlay__wrapper--modal')[0]; + const overlayDiv = document.getElementsByClassName(HelperTestFunctions.MODAL_OVERLAY_CSSCLASS)[0]; UIInteractions.clickElement(overlayDiv); tick(400); fixture.detectChanges(); @@ -1289,144 +1290,15 @@ describe('Multi-View Calendar - ', () => { fixture.detectChanges(); expect(datePicker.hideOutsideDays).toBe(false); - overlay = document.querySelector('.igx-overlay'); - expect(HelperTestFunctions.getHiidenDays(overlay, 0).length).toBe(0); - expect(HelperTestFunctions.getHiidenDays(overlay, 1).length).toBe(0); - expect(HelperTestFunctions.getHiidenDays(overlay, 2).length).toBe(0); + overlay = document.querySelector(HelperTestFunctions.OVERLAY_CSSCLASS); + expect(HelperTestFunctions.getHiddenDays(overlay, 0).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(overlay, 1).length).toBe(0); + expect(HelperTestFunctions.getHiddenDays(overlay, 2).length).toBe(0); })); }); }); -class HelperTestFunctions { - public static CURRENT_DATE_CSSCLASS = '.igx-calendar__date--current'; - public static DAYS_VIEW = 'igx-days-view'; - public static CALENDAR = 'igx-calendar'; - public static CALENDAR_HEADER_CSSCLASS = '.igx-calendar__header'; - public static CALENDAR_HEADER_YEAR_CSSCLASS = '.igx-calendar__header-year'; - public static CALENDAR_HEADER_DATE_CSSCLASS = '.igx-calendar__header-date'; - public static INACTIVE_DAYS_CSSCLASS = '.igx-calendar__date--inactive'; - public static HIDDEN_DAYS_CSSCLASS = '.igx-calendar__date--hidden'; - public static WEEKSTART_LABEL_CSSCLASS = '.igx-calendar__label'; - public static VERICAL_CALENDAR_CSSCLASS = '.igx-calendar--vertical'; - public static DAY_CSSCLASS = '.igx-calendar__date'; - public static SELECTED_DATE = '.igx-calendar__date--selected'; - public static RANGE_CSSCLASS = 'igx-calendar__date--range'; - public static CALENDAR_PREV_BUTTON_CSSCLASS = '.igx-calendar-picker__prev'; - public static CALENDAR_NEXT_BUTTON_CSSCLASS = '.igx-calendar-picker__next'; - public static CALENDAR_SUBHEADERS_SELECTOR = - 'div:not(' + HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS + '):not(' + HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS + ')'; - - public static verifyMonthsViewNumber(fixture, monthsView: number, checkCurrentDate = false) { - const el = fixture.nativeElement ? fixture.nativeElement : fixture; - const daysView = el.querySelectorAll(HelperTestFunctions.DAYS_VIEW); - expect(daysView).toBeDefined(); - expect(daysView.length).toBe(monthsView); - const monthPickers = HelperTestFunctions.getCalendarSubHeader(el).querySelectorAll('div'); - expect(monthPickers.length).toBe(monthsView + 2); // plus the navigation arrows - if (checkCurrentDate) { - const currentDate = el.querySelector(HelperTestFunctions.CURRENT_DATE_CSSCLASS); - expect(currentDate).not.toBeNull(); - } - } - - public static verifyCalendarHeader(fixture, selectedDate: Date) { - const daysView = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_CSSCLASS); - expect(daysView).not.toBeNull(); - const year = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS); - expect(year).not.toBeNull(); - expect(Number(year.innerText)).toEqual(selectedDate.getFullYear()); - const date = fixture.nativeElement.querySelector(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS); - expect(date).not.toBeNull(); - const dateParts = selectedDate.toUTCString().split(' '); // (weekday, date month year) - expect(date.children[0].innerText.trim()).toEqual(dateParts[0]); - expect(date.children[1].innerText.trim()).toEqual(dateParts[2] + ' ' + Number(dateParts[1])); - } - - public static verifyNoRangeSelectionCreated(fixture, monthNumber: number) { - expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--range')).toBeNull(); - expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--first')).toBeNull(); - expect(HelperTestFunctions.getMonthView(fixture, monthNumber).querySelector('.igx-calendar__date--last')).toBeNull(); - } - - public static verifyCalendarSubHeader(fixture, monthNumber: number, viewDate: Date) { - const monthPickers = HelperTestFunctions.getCalendarSubHeader(fixture).querySelectorAll('div'); - const dateParts = viewDate.toString().split(' '); // weekday month day year - expect(monthPickers[monthNumber].children[0].innerHTML.trim()).toEqual(dateParts[1]); - expect(monthPickers[monthNumber].children[1].innerHTML.trim()).toEqual(dateParts[3]); - } - - public static verifyCalendarSubHeaders(fixture, viewDates: Date[]) { - const dom = fixture.nativeElement ? fixture.nativeElement : fixture; - const monthPickers = HelperTestFunctions.getCalendarSubHeader(dom).querySelectorAll(this.CALENDAR_SUBHEADERS_SELECTOR); - expect(monthPickers.length).toEqual(viewDates.length); - for (let index = 0; index < viewDates.length; index++) { - const dateParts = viewDates[index].toString().split(' '); // weekday month day year - expect(monthPickers[index].children[0].innerHTML.trim()).toEqual(dateParts[1]); - expect(monthPickers[index].children[1].innerHTML.trim()).toEqual(dateParts[3]); - } - } - - public static getHiidenDays(fixture, monthNumber: number) { - const monthView = HelperTestFunctions.getMonthView(fixture, monthNumber); - return monthView.querySelectorAll(HelperTestFunctions.HIDDEN_DAYS_CSSCLASS); - } - - public static getInactiveDays(fixture, monthNumber: number) { - const monthView = HelperTestFunctions.getMonthView(fixture, monthNumber); - return monthView.querySelectorAll(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS); - } - - public static getCalendarSubHeader(fixture): HTMLElement { - const element = fixture.nativeElement ? fixture.nativeElement : fixture; - return element.querySelector('div.igx-calendar-picker'); - } - - public static getMonthView(fixture, monthsViewNumber: number) { - const domEL = fixture.nativeElement ? fixture.nativeElement : fixture; - return domEL.querySelectorAll('igx-days-view')[monthsViewNumber]; - } - - public static getMonthViewDates(fixture, monthsViewNumber: number) { - const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); - return month.querySelectorAll(HelperTestFunctions.DAY_CSSCLASS); - } - - public static getMonthViewInactiveDates(fixture, monthsViewNumber: number) { - const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); - return month.querySelectorAll(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS); - } - - public static getMonthViewSelectedDates(fixture, monthsViewNumber: number) { - const month = HelperTestFunctions.getMonthView(fixture, monthsViewNumber); - return month.querySelectorAll(HelperTestFunctions.SELECTED_DATE + - `:not(${HelperTestFunctions.HIDDEN_DAYS_CSSCLASS})`); - } - - public static getMonthsFromMonthView(fixture) { - return fixture.nativeElement.querySelector('igx-months-view') - .querySelectorAll('.igx-calendar__month, .igx-calendar__month--current'); - } - - public static getYearsFromYearView(fixture) { - return fixture.nativeElement.querySelector('igx-years-view') - .querySelectorAll('.igx-calendar__year, .igx-calendar__year--current'); - } - - public static getCurrentYearsFromYearView(fixture) { - return fixture.nativeElement.querySelector('igx-years-view') - .querySelector('.igx-calendar__year--current'); - } - - public static getNexArrowElement(fixture) { - return fixture.debugElement.query(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS)).nativeElement; - } - - public static getPreviousArrowElement(fixture) { - return fixture.debugElement.query(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS)).nativeElement; - } -} - @Component({ template: ` diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 0d0833d3816..c50277ab43c 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1,5 +1,5 @@ import { Component, ViewChild } from '@angular/core'; -import { async, TestBed } from '@angular/core/testing'; +import { async, TestBed, tick, fakeAsync, flush } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -7,23 +7,23 @@ import { Calendar, IgxCalendarComponent, IgxCalendarModule, isLeap, monthRange, weekDay, WEEKDAYS } from './index'; -import { UIInteractions, wait } from '../test-utils/ui-interactions.spec'; +import { UIInteractions } from '../test-utils/ui-interactions.spec'; import { DateRangeDescriptor, DateRangeType } from '../core/dates/dateRange'; import { configureTestSuite } from '../test-utils/configure-suite'; import { IgxDayItemComponent } from './days-view/day-item.component'; +import { HelperTestFunctions } from './calendar-helper-utils'; -describe('IgxCalendar', () => { +describe('IgxCalendar - ', () => { configureTestSuite(); beforeEach(() => { TestBed.configureTestingModule({ - declarations: [IgxCalendarSampleComponent, IgxCalendaRangeComponent, IgxCalendarDisabledSpecialDatesComponent], + declarations: [IgxCalendarSampleComponent, IgxCalendarRangeComponent, IgxCalendarDisabledSpecialDatesComponent], imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] - }); + }).compileComponents(); }); - // Calendar Model Tests - it('should create proper calendar model', () => { + it('Should create proper calendar model', () => { const calendar = new Calendar(); expect(calendar.firstWeekDay).toEqual(WEEKDAYS.SUNDAY); expect(calendar.weekdays()).toEqual([0, 1, 2, 3, 4, 5, 6]); @@ -85,7 +85,7 @@ describe('IgxCalendar', () => { expect(dates.length).toEqual(35); }); - it('should receive correct values from utility functions', () => { + it('Should receive correct values from utility functions', () => { const calendar = new Calendar(); // Leap year @@ -175,32 +175,23 @@ describe('IgxCalendar', () => { expect(() => calendar.timedelta(startDate, 'nope', 1)).toThrow(); }); - describe('Rendered Component', () => { - configureTestSuite(); - let fixture; - let calendar; - let dom; + describe('Rendered Component - ', () => { + let fixture, calendar, dom; beforeEach( async(() => { - TestBed.configureTestingModule({ - declarations: [IgxCalendarSampleComponent], - imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] - }).compileComponents() - .then(() => { fixture = TestBed.createComponent(IgxCalendarSampleComponent); fixture.detectChanges(); calendar = fixture.componentInstance.calendar; dom = fixture.debugElement; - }); }) ); - it('should initialize a calendar component', () => { + it('Should initialize a calendar component', () => { expect(fixture.componentInstance).toBeDefined(); }); - it('should initialize a calendar component with `id` property', () => { - const domCalendar = dom.query(By.css('igx-calendar')).nativeElement; + it('Should initialize a calendar component with `id` property', () => { + const domCalendar = dom.query(By.css(HelperTestFunctions.CALENDAR)).nativeElement; expect(calendar.id).toContain('igx-calendar-'); expect(domCalendar.id).toContain('igx-calendar-'); @@ -212,7 +203,7 @@ describe('IgxCalendar', () => { expect(domCalendar.id).toBe('customCalendar'); }); - it('should properly set @Input properties and setters', () => { + it('Should properly set @Input properties and setters', () => { expect(calendar.weekStart).toEqual(WEEKDAYS.SUNDAY); expect(calendar.selection).toEqual('single'); @@ -235,7 +226,7 @@ describe('IgxCalendar', () => { expect(() => (calendar.selection = 'non-existant')).toThrow(); }); - it('should properly set formatOptions and formatViews', () => { + it('Should properly set formatOptions and formatViews', () => { fixture.componentInstance.viewDate = new Date(2018, 8, 17); fixture.componentInstance.model = new Date(); fixture.detectChanges(); @@ -247,11 +238,11 @@ describe('IgxCalendar', () => { year: 'numeric' }; const defaultViews = { day: false, month: true, year: false }; - const bodyMonth = dom.query(By.css('.igx-calendar-picker__date')); - const headerYear = dom.query(By.css('.igx-calendar__header-year')); - const bodyYear = dom.queryAll(By.css('.igx-calendar-picker__date'))[1]; - const headerWeekday = dom.queryAll(By.css('.igx-calendar__header-date span'))[0]; - const headerDate = dom.queryAll(By.css('.igx-calendar__header-date span'))[1]; + const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); + const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); + const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; + const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; + const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; calendar.selectDate(calendar.viewDate); fixture.detectChanges(); @@ -296,17 +287,17 @@ describe('IgxCalendar', () => { expect(bodyMonth.nativeElement.textContent.trim()).toMatch('8'); }); - it('should properly set locale', () => { + it('Should properly set locale', () => { fixture.componentInstance.viewDate = new Date(2018, 8, 17); fixture.componentInstance.model = new Date(); fixture.detectChanges(); - const bodyMonth = dom.query(By.css('.igx-calendar-picker__date')); - const headerYear = dom.query(By.css('.igx-calendar__header-year')); - const bodyYear = dom.queryAll(By.css('.igx-calendar-picker__date'))[1]; - const headerWeekday = dom.queryAll(By.css('.igx-calendar__header-date span'))[0]; - const headerDate = dom.queryAll(By.css('.igx-calendar__header-date span'))[1]; - let bodyWeekday = dom.query(By.css('.igx-calendar__label')); + const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); + const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); + const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; + const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; + const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; + let bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); calendar.selectDate(calendar.viewDate); fixture.detectChanges(); @@ -323,7 +314,7 @@ describe('IgxCalendar', () => { calendar.locale = locale; fixture.detectChanges(); - bodyWeekday = dom.query(By.css('.igx-calendar__label')); + bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); expect(calendar.locale).toEqual(locale); expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); expect(headerWeekday.nativeElement.textContent.trim()).toMatch('lun.,'); @@ -333,28 +324,27 @@ describe('IgxCalendar', () => { expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Dim.'); }); - it('should properly render calendar DOM structure', () => { + it('Should properly render calendar DOM structure', () => { const today = new Date(Date.now()); calendar.viewDate = today; fixture.detectChanges(); - const calendarRows = dom.queryAll(By.css('.igx-calendar__body-row')); - + const calendarRows = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS)); // 6 weeks + week header expect(calendarRows.length).toEqual(7); // 7 calendar rows * 7 elements in each expect( - dom.queryAll(By.css('.igx-calendar__body-row > igx-day-item')).length + dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > igx-day-item`)).length ).toEqual(42); expect( - dom.queryAll(By.css('.igx-calendar__body-row > span')).length + dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > span`)).length ).toEqual(7); // Today class applied expect( dom - .query(By.css('.igx-calendar__date--current')) + .query(By.css(HelperTestFunctions.CURRENT_DATE_CSSCLASS)) .nativeElement.textContent.trim() ).toMatch(today.getDate().toString()); @@ -362,17 +352,17 @@ describe('IgxCalendar', () => { calendar.selection = 'multi'; fixture.detectChanges(); - const calendarHeader = dom.query(By.css('.igx-calendar__header')); + const calendarHeader = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_CSSCLASS)); expect(calendarHeader).toBeFalsy(); }); it('Calendar DOM structure - year view | month view', () => { - dom.queryAll(By.css('.igx-calendar-picker__date'))[0].nativeElement.click(); + dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0].nativeElement.click(); fixture.detectChanges(); - expect(dom.query(By.css('.igx-calendar__body-row--wrap'))).toBeDefined(); - const months = dom.queryAll(By.css('.igx-calendar__month')); - const currentMonth = dom.query(By.css('.igx-calendar__month--current')); + expect(dom.query(By.css(HelperTestFunctions.CALENDAR_ROW_WRAP_CSSCLASS))).toBeDefined(); + const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); + const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); expect(months.length).toEqual(11); expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); @@ -382,12 +372,12 @@ describe('IgxCalendar', () => { expect(calendar.viewDate.getMonth()).toEqual(0); - dom.queryAll(By.css('.igx-calendar-picker__date'))[1].nativeElement.click(); + dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1].nativeElement.click(); fixture.detectChanges(); - expect(dom.query(By.css('.igx-calendar__body-column'))).toBeDefined(); - const years = dom.queryAll(By.css('.igx-calendar__year')); - const currentYear = dom.query(By.css('.igx-calendar__year--current')); + expect(dom.query(By.css(HelperTestFunctions.CALENDAR_COLUMN_CSSCLASS))).toBeDefined(); + const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); + const currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); expect(years.length).toEqual(6); expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); @@ -401,9 +391,9 @@ describe('IgxCalendar', () => { it('Calendar selection - single with event', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); const nextDay = new Date(2017, 5, 14); @@ -438,9 +428,8 @@ describe('IgxCalendar', () => { }); it('Calendar selection - outside of current month - 1', () => { - fixture.detectChanges(); const parent = dom.query( - By.css('.igx-calendar__body-row:last-child') + By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}:last-child`) ); const target = parent.childNodes.pop(); @@ -452,15 +441,14 @@ describe('IgxCalendar', () => { ).toMatch(new Date(2017, 6, 8).toDateString()); expect( dom - .query(By.css('.igx-calendar__header-date')) + .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) .nativeElement.textContent.includes('Jul') ).toBe(true); }); it('Calendar selection - outside of current month - 2', () => { - fixture.detectChanges(); - const parent = dom.queryAll(By.css('.igx-calendar__body-row'))[1]; - const target = parent.queryAll(By.css('.igx-calendar__date--inactive'))[0]; + const parent = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS))[1]; + const target = parent.queryAll(By.css(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS))[0]; target.nativeElement.click(); fixture.detectChanges(); @@ -470,7 +458,7 @@ describe('IgxCalendar', () => { ).toMatch(new Date(2017, 4, 28).toDateString()); expect( dom - .query(By.css('.igx-calendar__header-date')) + .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) .nativeElement.textContent.includes('May') ).toBe(true); }); @@ -478,9 +466,9 @@ describe('IgxCalendar', () => { it('Calendar selection - single through API', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); const nextDay = new Date(2017, 5, 14); expect((calendar.value as Date).toDateString()).toMatch( @@ -511,9 +499,9 @@ describe('IgxCalendar', () => { it('Calendar selection - multiple with event', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); calendar.selection = 'multi'; fixture.detectChanges(); @@ -562,9 +550,9 @@ describe('IgxCalendar', () => { it('Calendar selection - multiple through API', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); calendar.selection = 'multi'; fixture.detectChanges(); @@ -611,9 +599,10 @@ describe('IgxCalendar', () => { it('Calendar selection - range with event', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); calendar.selection = 'range'; fixture.detectChanges(); @@ -683,9 +672,10 @@ describe('IgxCalendar', () => { it('Calendar selection - range through API', () => { fixture.detectChanges(); - const target = dom.query(By.css('.igx-calendar__date--selected')); + + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css('.igx-calendar__date')); + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); calendar.selection = 'range'; fixture.detectChanges(); @@ -778,7 +768,7 @@ describe('IgxCalendar', () => { }); it('Calendar keyboard navigation - PageUp/PageDown', () => { - const component = dom.query(By.css('.igx-calendar')); + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); UIInteractions.simulateKeyDownEvent(component.nativeElement, 'PageUp'); fixture.detectChanges(); @@ -805,8 +795,7 @@ describe('IgxCalendar', () => { }); it('Calendar keyboard navigation - Home/End/Enter', () => { - fixture.detectChanges(); - const component = dom.query(By.css('.igx-calendar')); + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); const firstDay = days[0]; @@ -831,7 +820,7 @@ describe('IgxCalendar', () => { }); it('Calendar keyboard navigation - Arrow keys', () => { - const component = dom.query(By.css('.igx-calendar')); + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); const firstDay = days[0]; @@ -863,17 +852,17 @@ describe('IgxCalendar', () => { expect(document.activeElement.textContent.trim()).toMatch('1'); }); - it('Calendar date should persist the focus when select date in the (next/prev) month.', async () => { - const component = dom.query(By.css('.igx-calendar')); + it('Calendar date should persist the focus when select date in the (next/prev) month.', fakeAsync (() => { + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); const calendarMonth = calendar.daysView.getCalendarMonth; let value = calendarMonth[0][4]; UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement, true); - fixture.detectChanges(); let date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; UIInteractions.simulateKeyDownEvent(date, 'Enter'); fixture.detectChanges(); + flush(); expect(document.activeElement).toBe(date); @@ -882,62 +871,61 @@ describe('IgxCalendar', () => { UIInteractions.simulateKeyDownEvent(date, 'Enter'); fixture.detectChanges(); - await wait(500); + flush(); date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; expect(document.activeElement).toBe(date); UIInteractions.triggerKeyDownEvtUponElem('ArrowRight', document.activeElement, true); - fixture.detectChanges(); expect(document.activeElement.textContent.trim()).toMatch('2'); - }); + })); - it('Should navigate to first enabled date when using "home" key.', async () => { + it('Should navigate to first enabled date when using "home" key.', fakeAsync (() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [new Date(2017, 5, 1), new Date(2017, 5, 2)]; dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, { type: DateRangeType.Weekends }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); fixture.detectChanges(); const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 5).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); - it('Should navigate to last enabled date when using "end" key.', async () => { + it('Should navigate to last enabled date when using "end" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const rangeDates = [new Date(2017, 5, 28), new Date(2017, 5, 30)]; dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }, { type: DateRangeType.Specific, dateRange: [new Date(2017, 5, 27)] }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); fixture.detectChanges(); const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 26).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); - it('Should navigate to first enabled date when using "arrow up" key.', async () => { + it('Should navigate to first enabled date when using "arrow up" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [new Date(2017, 5, 23), new Date(2017, 5, 16)]; dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, { type: DateRangeType.Weekends }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); fixture.detectChanges(); @@ -947,18 +935,18 @@ describe('IgxCalendar', () => { const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 9).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); - it('Should navigate to first enabled date when using "arrow down" key.', async () => { + it('Should navigate to first enabled date when using "arrow down" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [new Date(2017, 5, 8), new Date(2017, 5, 15)]; dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, { type: DateRangeType.Weekends }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); fixture.detectChanges(); @@ -968,17 +956,17 @@ describe('IgxCalendar', () => { const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 22).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); - it('Should navigate to first enabled date when using "arrow left" key.', async () => { + it('Should navigate to first enabled date when using "arrow left" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); fixture.detectChanges(); @@ -988,17 +976,17 @@ describe('IgxCalendar', () => { const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 1).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); - it('Should navigate to first enabled date when using "arrow right" key.', async () => { + it('Should navigate to first enabled date when using "arrow right" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); fixture.detectChanges(); @@ -1008,7 +996,7 @@ describe('IgxCalendar', () => { const date = calendar.daysView.dates.filter( d => getDate(d).getTime() === new Date(2017, 5, 30).getTime())[0]; expect(date.nativeElement).toBe(document.activeElement); - }); + })); it('Should not select disabled dates when having "range" selection', () => { const dateRangeDescriptors: DateRangeDescriptor[] = []; @@ -1052,264 +1040,259 @@ describe('IgxCalendar', () => { }); }); - it('Should be able to set disabled and active dates as @Input', () => { - const fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); - fixture.detectChanges(); - const calendar = fixture.componentInstance.calendar; - expect(calendar.specialDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); - expect(calendar.disabledDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 23), new Date(2017, 5, 29)]}]); - let specialDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 1).getTime() && - dateTime <= new Date(2017, 5, 6).getTime()); + describe('Disabled dates - ', () => { + it('Should disable date when using "After" date descriptor.', () => { + DateRangesPropertiesTester.testAfter( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates); }); - specialDates.forEach(d => { - expect(d.isSpecial).toBe(true); + it('Should disable date when using "Before" date descriptor.', () => { + DateRangesPropertiesTester.testBefore( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - let disabledDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 23).getTime() && - dateTime <= new Date(2017, 5, 29).getTime()); + it('Should disable date when using "Between" date descriptor with min date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMinDateFirst( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - disabledDates.forEach(d => { - expect(d.isDisabled).toBe(true); - expect(d.isDisabledCSS).toBe(true); + it('Should disable date when using "Between" date descriptor with max date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMaxDateFirst( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - // change Inputs - fixture.componentInstance.disabledDates = [{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]; - fixture.componentInstance.specialDates = [{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]; - fixture.detectChanges(); + it('Should disable date when using "Between" date descriptor with min and max the same.', () => { + DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - expect(calendar.disabledDates).toEqual([{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]); - expect(calendar.specialDates).toEqual([{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]); - specialDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 20).getTime()); + it('Should disable date when using overlapping "Between" ranges.', () => { + DateRangesPropertiesTester.testOverlappingBetweens( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - specialDates.forEach(d => { - expect(d.isSpecial).toBe(true); + it('Should disable date when using "Specific" date descriptor.', () => { + DateRangesPropertiesTester.testSpecific( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - disabledDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime <= new Date(2017, 5, 9).getTime()); + it('Should disable date when using "Weekdays" date descriptor.', () => { + DateRangesPropertiesTester.testWeekdays( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - disabledDates.forEach(d => { - expect(d.isDisabled).toBe(true); - expect(d.isDisabledCSS).toBe(true); + it('Should disable date when using "Weekends" date descriptor.', () => { + DateRangesPropertiesTester.testWeekends( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - }); - it('Should disable date when using "After" date descriptor.', () => { - DateRangesPropertiesTester.testAfter( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates); - }); + it('Should disable dates when using multiple ranges.', () => { + DateRangesPropertiesTester.testMultipleRanges( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Before" date descriptor.', () => { - DateRangesPropertiesTester.testBefore( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable previous month with "before" date descriptor', () => { + DateRangesPropertiesTester.testPreviousMonthRange( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Between" date descriptor with min date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMinDateFirst( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); + it('Should be able to change disable dates runtime.', () => { + DateRangesPropertiesTester.testRangeUpdateRuntime( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); }); - it('Should disable date when using "Between" date descriptor with max date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMaxDateFirst( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + describe('Special dates - ', () => { + it('Should mark date as special when using "After" date descriptor.', () => { + DateRangesPropertiesTester.testAfter( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable date when using "Between" date descriptor with min and max the same.', () => { - DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Before" date descriptor.', () => { + DateRangesPropertiesTester.testBefore( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable date when using overlapping "Between" ranges.', () => { - DateRangesPropertiesTester.testOverlappingBetweens( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Between" date descriptor with min date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMinDateFirst( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable date when using "Specific" date descriptor.', () => { - DateRangesPropertiesTester.testSpecific( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Between" date descriptor with max date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMaxDateFirst( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable date when using "Weekdays" date descriptor.', () => { - DateRangesPropertiesTester.testWeekdays( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Between" date descriptor with min and max the same.', () => { + DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable date when using "Weekends" date descriptor.', () => { - DateRangesPropertiesTester.testWeekends( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using overlapping "Between" ranges.', () => { + DateRangesPropertiesTester.testOverlappingBetweens( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable dates when using multiple ranges.', () => { - DateRangesPropertiesTester.testMultipleRanges( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Specific" date descriptor.', () => { + DateRangesPropertiesTester.testSpecific( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable previous month with "before" date descriptor', () => { - DateRangesPropertiesTester.testPreviousMonthRange( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Weekdays" date descriptor.', () => { + DateRangesPropertiesTester.testWeekdays( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should be able to change disable dates runtime.', () => { - DateRangesPropertiesTester.testRangeUpdateRuntime( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Weekends" date descriptor.', () => { + DateRangesPropertiesTester.testWeekends( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "After" date descriptor.', () => { - DateRangesPropertiesTester.testAfter( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark dates as special when using multiple ranges.', () => { + DateRangesPropertiesTester.testMultipleRanges( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Before" date descriptor.', () => { - DateRangesPropertiesTester.testBefore( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark as special previous month with "before" date descriptor', () => { + DateRangesPropertiesTester.testPreviousMonthRange( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Between" date descriptor with min date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMinDateFirst( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); + it('Should be able to change special dates runtime.', () => { + DateRangesPropertiesTester.testRangeUpdateRuntime( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); }); - it('Should mark date as special when using "Between" date descriptor with max date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMaxDateFirst( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + describe('Disabled special dates - ', () => { + let fixture, calendar; - it('Should mark date as special when using "Between" date descriptor with min and max the same.', () => { - DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + beforeEach(async(() => { + fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); + fixture.detectChanges(); + calendar = fixture.componentInstance.calendar; + })); - it('Should mark date as special when using overlapping "Between" ranges.', () => { - DateRangesPropertiesTester.testOverlappingBetweens( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should be able to set disabled and active dates as @Input', () => { + expect(calendar.specialDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); + expect(calendar.disabledDates).toEqual( + [{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 23), new Date(2017, 5, 29)]}]); + let specialDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 1).getTime() && + dateTime <= new Date(2017, 5, 6).getTime()); + }); - it('Should mark date as special when using "Specific" date descriptor.', () => { - DateRangesPropertiesTester.testSpecific( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + specialDates.forEach(d => { + expect(d.isSpecial).toBe(true); + }); - it('Should mark date as special when using "Weekdays" date descriptor.', () => { - DateRangesPropertiesTester.testWeekdays( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + let disabledDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 23).getTime() && + dateTime <= new Date(2017, 5, 29).getTime()); + }); - it('Should mark date as special when using "Weekends" date descriptor.', () => { - DateRangesPropertiesTester.testWeekends( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + disabledDates.forEach(d => { + expect(d.isDisabled).toBe(true); + expect(d.isDisabledCSS).toBe(true); + }); - it('Should mark dates as special when using multiple ranges.', () => { - DateRangesPropertiesTester.testMultipleRanges( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + // change Inputs + fixture.componentInstance.disabledDates = [{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]; + fixture.componentInstance.specialDates = [{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]; + fixture.detectChanges(); - it('Should mark as special previous month with "before" date descriptor', () => { - DateRangesPropertiesTester.testPreviousMonthRange( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + expect(calendar.disabledDates).toEqual([{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]); + expect(calendar.specialDates).toEqual([{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]); + specialDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 20).getTime()); + }); - it('Should be able to change special dates runtime.', () => { - DateRangesPropertiesTester.testRangeUpdateRuntime( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + specialDates.forEach(d => { + expect(d.isSpecial).toBe(true); + }); - it('Should not select date from model, if it is part of disabled dates', async () => { - const fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); - const calendar = fixture.componentInstance.calendar; - fixture.detectChanges(); - await (500); + disabledDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime <= new Date(2017, 5, 9).getTime()); + }); - expect(calendar.value).toBeFalsy(); - }); + disabledDates.forEach(d => { + expect(d.isDisabled).toBe(true); + expect(d.isDisabledCSS).toBe(true); + }); + }); - it('Should not select date from model in range selection, if model passes null', async () => { - const fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); - const calendar = fixture.componentInstance.calendar; - calendar.selection = 'range'; - fixture.componentInstance.model = null; - fixture.detectChanges(); - await (500); + it('Should not select date from model, if it is part of disabled dates', () => { + expect(calendar.value).toBeFalsy(); + }); - expect((calendar.value as Date[]).length).toEqual(0); + it('Should not select date from model in range selection, if model passes null', () => { + calendar.selection = 'range'; + fixture.componentInstance.model = null; + fixture.detectChanges(); + + expect((calendar.value as Date[]).length).toEqual(0); + }); }); - describe('Select and deselect dates', () => { - configureTestSuite(); - let fixture; - let calendar; - let ci; + describe('Select and deselect dates - ', () => { + let fixture, calendar, ci; beforeEach( async(() => { - TestBed.configureTestingModule({ - declarations: [IgxCalendarSampleComponent], - imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] - }).compileComponents() - .then(() => { fixture = TestBed.createComponent(IgxCalendarSampleComponent); fixture.detectChanges(); ci = fixture.componentInstance; calendar = ci.calendar; - }); }) ); @@ -1327,7 +1310,7 @@ describe('IgxCalendar', () => { selectedDate = calendar.value; expect(selectedDate).toBe(null); - // Deselect with date diffrent than selected date + // Deselect with date different than selected date calendar.selectDate(date); fixture.detectChanges(); @@ -1621,58 +1604,45 @@ describe('IgxCalendar', () => { }); }); - describe('Advanced KB Navigation', () => { - configureTestSuite(); - - beforeEach( - async(() => { - TestBed.configureTestingModule({ - declarations: [IgxCalendarSampleComponent], - imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] - }).compileComponents(); - }) - ); + describe('Advanced KB Navigation - ', () => { + let fixture, calendar, dom; - it('AKB - should navigate to the previous/next month via KB.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); + beforeEach(async(() => { + fixture = TestBed.createComponent(IgxCalendarSampleComponent); fixture.detectChanges(); + calendar = fixture.componentInstance.calendar; + dom = fixture.debugElement; + })); - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; - - const prev = dom.queryAll(By.css('.igx-calendar-picker__prev'))[0]; + it('Should navigate to the previous/next month via KB.', fakeAsync(() => { + const prev = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0]; prev.nativeElement.focus(); expect(prev.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(prev.nativeElement, 'Enter'); - await wait(200); + tick(100); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(4); - const next = dom.queryAll(By.css('.igx-calendar-picker__next'))[0]; + const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; next.nativeElement.focus(); - expect(next.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); - await wait(200); - UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); - await wait(200); + tick(100); fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(6); - }); - - it('AKB - should open years view, navigate through and select an year via KB.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); + UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); + tick(100); fixture.detectChanges(); - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; + expect(calendar.viewDate.getMonth()).toEqual(6); + })); - const year = dom.queryAll(By.css('.igx-calendar-picker__date'))[1]; + it('Should open years view, navigate through and select an year via KB.', () => { + const year = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; year.nativeElement.focus(); expect(year.nativeElement).toBe(document.activeElement); @@ -1680,8 +1650,8 @@ describe('IgxCalendar', () => { UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); fixture.detectChanges(); - const years = dom.queryAll(By.css('.igx-calendar__year')); - let currentYear = dom.query(By.css('.igx-calendar__year--current')); + const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); + let currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); expect(years.length).toEqual(6); expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); @@ -1689,14 +1659,14 @@ describe('IgxCalendar', () => { UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowDown'); fixture.detectChanges(); - currentYear = dom.query(By.css('.igx-calendar__year--current')); + currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); expect(currentYear.nativeElement.textContent.trim()).toMatch('2018'); UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); fixture.detectChanges(); - currentYear = dom.query(By.css('.igx-calendar__year--current')); + currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); expect(currentYear.nativeElement.textContent.trim()).toMatch('2016'); UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'Enter'); @@ -1705,14 +1675,8 @@ describe('IgxCalendar', () => { expect(calendar.viewDate.getFullYear()).toEqual(2016); }); - it('AKB - should open months view, navigate through and select a month via KB.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; - - const month = dom.queryAll(By.css('.igx-calendar-picker__date'))[0]; + it('Should open months view, navigate through and select a month via KB.', () => { + const month = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0]; month.nativeElement.focus(); expect(month.nativeElement).toBe(document.activeElement); @@ -1720,8 +1684,8 @@ describe('IgxCalendar', () => { UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); fixture.detectChanges(); - const months = dom.queryAll(By.css('.igx-calendar__month')); - const currentMonth = dom.query(By.css('.igx-calendar__month--current')); + const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); + const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); expect(months.length).toEqual(11); expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); @@ -1753,13 +1717,7 @@ describe('IgxCalendar', () => { expect(calendar.viewDate.getMonth()).toEqual(8); }); - it('AKB - should navigate to the first enabled date from the previous month when using "arrow up" key.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; - + it('Should navigate to the first enabled date from the previous month when using "arrow up" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [ new Date(2017, 4, 25), @@ -1770,16 +1728,15 @@ describe('IgxCalendar', () => { calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); fixture.detectChanges(); - await wait(400); + flush(); let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 18).getTime()); expect(date.nativeElement).toBe(document.activeElement); @@ -1788,19 +1745,13 @@ describe('IgxCalendar', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 27).getTime()); expect(date.nativeElement).toBe(document.activeElement); - }); - - it('AKB - should navigate to the first enabled date from the previous month when using "arrow left" key.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; + })); + it('Should navigate to the first enabled date from the previous month when using "arrow left" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [ new Date(2017, 4, 27), @@ -1811,47 +1762,37 @@ describe('IgxCalendar', () => { calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); + flush(); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); fixture.detectChanges(); - await wait(400); + flush(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); fixture.detectChanges(); - await wait(400); + flush(); let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 26).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); fixture.detectChanges(); - await wait(400); + flush(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 29).getTime()); expect(date.nativeElement).toBe(document.activeElement); - }); - - it('AKB - should navigate to the first enabled date from the next month when using "arrow down" key.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; + })); + it('Should navigate to the first enabled date from the next month when using "arrow down" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [ new Date(2017, 6, 14), @@ -1862,41 +1803,32 @@ describe('IgxCalendar', () => { calendar.disabledDates = dateRangeDescriptors; fixture.detectChanges(); - await wait(50); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); - await wait(400); + flush(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); - await wait(400); + flush(); let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 21).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); - await wait(400); + flush(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 11).getTime()); expect(date.nativeElement).toBe(document.activeElement); - }); - - it('AKB - should navigate to the first enabled date from the next month when using "arrow right" key.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; + })); + it('Should navigate to the first enabled date from the next month when using "arrow right" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; const specificDates = [ new Date(2017, 6, 9), @@ -1906,135 +1838,117 @@ describe('IgxCalendar', () => { dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - await wait(50); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); - await wait(400); + flush(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); fixture.detectChanges(); - await wait(400); + flush(); let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 11).getTime()); expect(date.nativeElement).toBe(document.activeElement); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 5).getTime()); date.nativeElement.focus(); - fixture.detectChanges(); - await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 6).getTime()); expect(date.nativeElement).toBe(document.activeElement); - }); - - it('AKB - should preserve the active date on (shift) pageup and pagedown.', async () => { - const fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - - const calendar = fixture.componentInstance.calendar; - const dom = fixture.debugElement; + })); - const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement; + it('Should preserve the active date on (shift) pageup and pagedown.', fakeAsync(() => { + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageUp'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 1).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageDown'); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('PageUp', document.activeElement, true, false, true); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2016, 5, 1).getTime()); expect(date.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('PageDown', document.activeElement, true, false, true); fixture.detectChanges(); - await wait(400); + flush(); date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); expect(date.nativeElement).toBe(document.activeElement); - }); + })); }); - describe('Continuous month increment/decrement', () => { - // configureTestSuite(); - - let fixture; - let dom; - let calendar; - let prevMonthBtn; - let nextMonthBtn; + describe('Continuous month increment/decrement - ', () => { + let fixture, dom, calendar, prevMonthBtn, nextMonthBtn; beforeEach(async(() => { fixture = TestBed.createComponent(IgxCalendarSampleComponent); fixture.detectChanges(); - dom = fixture.debugElement; calendar = fixture.componentInstance.calendar; - prevMonthBtn = dom.queryAll(By.css('.igx-calendar-picker__prev'))[0].nativeElement; - nextMonthBtn = dom.queryAll(By.css('.igx-calendar-picker__next'))[0].nativeElement; + + prevMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0].nativeElement; + nextMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0].nativeElement; })); - it('Should increment/decrement months continuously on mousedown.', async () => { + it('Should increment/decrement months continuously on mousedown.', fakeAsync(() => { expect(calendar.viewDate.getMonth()).toEqual(5); // Have no idea how this test worked before, // changing expectation based on my udnerstanding of that the test does UIInteractions.simulateMouseEvent('mousedown', prevMonthBtn, 0, 0); - await wait(900); + tick(900); UIInteractions.simulateMouseEvent('mouseup', prevMonthBtn, 0, 0); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(4); UIInteractions.simulateMouseEvent('mousedown', nextMonthBtn, 0, 0); - await wait(900); + tick(900); UIInteractions.simulateMouseEvent('mouseup', nextMonthBtn, 0, 0); fixture.detectChanges(); + flush(); expect(calendar.viewDate.getMonth()).toEqual(5); - }); + })); - it('Should increment/decrement months continuously on enter keydwon.', async () => { + it('Should increment/decrement months continuously on enter keydown.', fakeAsync(() => { expect(calendar.viewDate.getMonth()).toEqual(5); prevMonthBtn.focus(); UIInteractions.simulateKeyDownEvent(prevMonthBtn, 'Enter'); - await wait(800); + tick(800); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(4); nextMonthBtn.focus(); UIInteractions.simulateKeyDownEvent(nextMonthBtn, 'Enter'); - await wait(800); + tick(800); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(5); - }); + })); }); }); @@ -2054,7 +1968,7 @@ export class IgxCalendarSampleComponent { ` }) -export class IgxCalendaRangeComponent { +export class IgxCalendarRangeComponent { public viewDate = new Date(2017, 5, 13); @ViewChild(IgxCalendarComponent, { static: true }) public calendar: IgxCalendarComponent; } @@ -2312,7 +2226,7 @@ class DateRangesPropertiesTester { assignFunc(calendar, dateRangeDescriptors); fixture.detectChanges(); const debugEl = fixture.debugElement; - const calendarNativeElement = debugEl.query(By.css('.igx-calendar')).nativeElement; + const calendarNativeElement = debugEl.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'PageUp'); fixture.detectChanges(); testRangesFunc(calendar.daysView.dates.toArray(), []); From 120d5593a72808139c45345fa9397af1f679b0b9 Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Wed, 22 Jan 2020 16:20:37 +0200 Subject: [PATCH 2/3] test(calendar): extracted helper methods and new describe added #6453 --- .../src/lib/calendar/calendar-helper-utils.ts | 17 + .../lib/calendar/calendar.component.spec.ts | 3000 ++++++++--------- 2 files changed, 1486 insertions(+), 1531 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts b/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts index 2bc4085d77c..efbd0c585e6 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-helper-utils.ts @@ -3,6 +3,7 @@ import { By } from '@angular/platform-browser'; export class HelperTestFunctions { public static DAYS_VIEW = 'igx-days-view'; public static CALENDAR = 'igx-calendar'; + public static SELECTED_DATE = 'igx-calendar__date--selected'; public static ICON_CSSCLASS = '.igx-icon'; public static OVERLAY_CSSCLASS = '.igx-overlay'; public static MODAL_OVERLAY_CSSCLASS = 'igx-overlay__wrapper--modal'; @@ -142,4 +143,20 @@ export class HelperTestFunctions { public static getPreviousArrowElement(fixture) { return fixture.debugElement.query(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS)).nativeElement; } + + public static verifyDateSelected(el) { + expect( + el.nativeElement.classList.contains( + HelperTestFunctions.SELECTED_DATE + ) + ).toBe(true); + } + + public static verifyDateNotSelected(el) { + expect( + el.nativeElement.classList.contains( + HelperTestFunctions.SELECTED_DATE + ) + ).toBe(false); + } } diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index c50277ab43c..b8951d9f5c6 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -15,13 +15,6 @@ import { IgxDayItemComponent } from './days-view/day-item.component'; import { HelperTestFunctions } from './calendar-helper-utils'; describe('IgxCalendar - ', () => { - configureTestSuite(); - beforeEach(() => { - TestBed.configureTestingModule({ - declarations: [IgxCalendarSampleComponent, IgxCalendarRangeComponent, IgxCalendarDisabledSpecialDatesComponent], - imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] - }).compileComponents(); - }); it('Should create proper calendar model', () => { const calendar = new Calendar(); @@ -175,1780 +168,1725 @@ describe('IgxCalendar - ', () => { expect(() => calendar.timedelta(startDate, 'nope', 1)).toThrow(); }); - describe('Rendered Component - ', () => { - let fixture, calendar, dom; - beforeEach( - async(() => { - fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - calendar = fixture.componentInstance.calendar; - dom = fixture.debugElement; - }) - ); - - it('Should initialize a calendar component', () => { - expect(fixture.componentInstance).toBeDefined(); + describe('', () => { + configureTestSuite(); + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [IgxCalendarSampleComponent, IgxCalendarRangeComponent, IgxCalendarDisabledSpecialDatesComponent], + imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule] + }).compileComponents(); }); - it('Should initialize a calendar component with `id` property', () => { - const domCalendar = dom.query(By.css(HelperTestFunctions.CALENDAR)).nativeElement; + describe('Rendered Component - ', () => { + let fixture, calendar, dom; + beforeEach( + async(() => { + fixture = TestBed.createComponent(IgxCalendarSampleComponent); + fixture.detectChanges(); + calendar = fixture.componentInstance.calendar; + dom = fixture.debugElement; + }) + ); - expect(calendar.id).toContain('igx-calendar-'); - expect(domCalendar.id).toContain('igx-calendar-'); + it('Should initialize a calendar component', () => { + expect(fixture.componentInstance).toBeDefined(); + }); - calendar.id = 'customCalendar'; - fixture.detectChanges(); + it('Should initialize a calendar component with `id` property', () => { + const domCalendar = dom.query(By.css(HelperTestFunctions.CALENDAR)).nativeElement; - expect(calendar.id).toBe('customCalendar'); - expect(domCalendar.id).toBe('customCalendar'); - }); + expect(calendar.id).toContain('igx-calendar-'); + expect(domCalendar.id).toContain('igx-calendar-'); - it('Should properly set @Input properties and setters', () => { - expect(calendar.weekStart).toEqual(WEEKDAYS.SUNDAY); - expect(calendar.selection).toEqual('single'); + calendar.id = 'customCalendar'; + fixture.detectChanges(); - const today = new Date(Date.now()); - calendar.viewDate = today; - fixture.detectChanges(); + expect(calendar.id).toBe('customCalendar'); + expect(domCalendar.id).toBe('customCalendar'); + }); - calendar.weekStart = WEEKDAYS.MONDAY; - expect(calendar.weekStart).toEqual(1); + it('Should properly set @Input properties and setters', () => { + expect(calendar.weekStart).toEqual(WEEKDAYS.SUNDAY); + expect(calendar.selection).toEqual('single'); - calendar.value = new Date(today); - fixture.detectChanges(); - expect( - (fixture.componentInstance.model as Date).toDateString() - ).toMatch(today.toDateString()); - expect((calendar.value as Date).toDateString()).toMatch( - today.toDateString() - ); + const today = new Date(Date.now()); + calendar.viewDate = today; + fixture.detectChanges(); - expect(() => (calendar.selection = 'non-existant')).toThrow(); - }); + calendar.weekStart = WEEKDAYS.MONDAY; + expect(calendar.weekStart).toEqual(1); - it('Should properly set formatOptions and formatViews', () => { - fixture.componentInstance.viewDate = new Date(2018, 8, 17); - fixture.componentInstance.model = new Date(); - fixture.detectChanges(); - - const defaultOptions = { - day: 'numeric', - month: 'short', - weekday: 'short', - year: 'numeric' - }; - const defaultViews = { day: false, month: true, year: false }; - const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); - const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); - const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; - const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; - const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; - - calendar.selectDate(calendar.viewDate); - fixture.detectChanges(); - - expect(calendar.formatOptions).toEqual(jasmine.objectContaining(defaultOptions)); - expect(calendar.formatViews).toEqual(jasmine.objectContaining(defaultViews)); - expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); - expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); - - // change formatOptions and formatViews - const formatOptions: any = { month: 'long', year: '2-digit' }; - const formatViews: any = { month: true, year: true }; - calendar.formatOptions = formatOptions; - calendar.formatViews = formatViews; - fixture.detectChanges(); - - expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); - expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); - expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); - expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); - expect(bodyMonth.nativeElement.textContent.trim()).toMatch('September'); - - // change formatOptions and formatViews - formatOptions.year = 'numeric'; - formatViews.day = true; - formatViews.month = false; - calendar.formatOptions = formatOptions; - calendar.formatViews = formatViews; - fixture.detectChanges(); - - expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); - expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); - expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); - expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(bodyMonth.nativeElement.textContent.trim()).toMatch('8'); - }); + calendar.value = new Date(today); + fixture.detectChanges(); + expect( + (fixture.componentInstance.model as Date).toDateString() + ).toMatch(today.toDateString()); + expect((calendar.value as Date).toDateString()).toMatch( + today.toDateString() + ); - it('Should properly set locale', () => { - fixture.componentInstance.viewDate = new Date(2018, 8, 17); - fixture.componentInstance.model = new Date(); - fixture.detectChanges(); - - const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); - const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); - const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; - const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; - const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; - let bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); - - calendar.selectDate(calendar.viewDate); - fixture.detectChanges(); - - expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); - expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); - expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Sun'); - - // change formatOptions and formatViews - const locale = 'fr'; - calendar.locale = locale; - fixture.detectChanges(); - - bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); - expect(calendar.locale).toEqual(locale); - expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('lun.,'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('17 sept.'); - expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); - expect(bodyMonth.nativeElement.textContent.trim()).toMatch('sept.'); - expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Dim.'); - }); + expect(() => (calendar.selection = 'non-existant')).toThrow(); + }); - it('Should properly render calendar DOM structure', () => { - const today = new Date(Date.now()); - calendar.viewDate = today; - fixture.detectChanges(); - const calendarRows = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS)); - - // 6 weeks + week header - expect(calendarRows.length).toEqual(7); - - // 7 calendar rows * 7 elements in each - expect( - dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > igx-day-item`)).length - ).toEqual(42); - expect( - dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > span`)).length - ).toEqual(7); - - // Today class applied - expect( - dom - .query(By.css(HelperTestFunctions.CURRENT_DATE_CSSCLASS)) - .nativeElement.textContent.trim() - ).toMatch(today.getDate().toString()); - - // Hide calendar header when not single selection - calendar.selection = 'multi'; - fixture.detectChanges(); - - const calendarHeader = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_CSSCLASS)); - expect(calendarHeader).toBeFalsy(); - }); + it('Should properly set formatOptions and formatViews', () => { + fixture.componentInstance.viewDate = new Date(2018, 8, 17); + fixture.componentInstance.model = new Date(); + fixture.detectChanges(); - it('Calendar DOM structure - year view | month view', () => { - dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0].nativeElement.click(); - fixture.detectChanges(); + const defaultOptions = { + day: 'numeric', + month: 'short', + weekday: 'short', + year: 'numeric' + }; + const defaultViews = { day: false, month: true, year: false }; + const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); + const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); + const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; + const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; + const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; + + calendar.selectDate(calendar.viewDate); + fixture.detectChanges(); - expect(dom.query(By.css(HelperTestFunctions.CALENDAR_ROW_WRAP_CSSCLASS))).toBeDefined(); - const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); - const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); + expect(calendar.formatOptions).toEqual(jasmine.objectContaining(defaultOptions)); + expect(calendar.formatViews).toEqual(jasmine.objectContaining(defaultViews)); + expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); + expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); + + // change formatOptions and formatViews + const formatOptions: any = { month: 'long', year: '2-digit' }; + const formatViews: any = { month: true, year: true }; + calendar.formatOptions = formatOptions; + calendar.formatViews = formatViews; + fixture.detectChanges(); - expect(months.length).toEqual(11); - expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); + expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); + expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); + expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); + expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); + expect(bodyMonth.nativeElement.textContent.trim()).toMatch('September'); + + // change formatOptions and formatViews + formatOptions.year = 'numeric'; + formatViews.day = true; + formatViews.month = false; + calendar.formatOptions = formatOptions; + calendar.formatViews = formatViews; + fixture.detectChanges(); - months[0].nativeElement.click(); - fixture.detectChanges(); + expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); + expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); + expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); + expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(bodyMonth.nativeElement.textContent.trim()).toMatch('8'); + }); - expect(calendar.viewDate.getMonth()).toEqual(0); + it('Should properly set locale', () => { + fixture.componentInstance.viewDate = new Date(2018, 8, 17); + fixture.componentInstance.model = new Date(); + fixture.detectChanges(); - dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1].nativeElement.click(); - fixture.detectChanges(); + const bodyMonth = dom.query(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS)); + const headerYear = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_YEAR_CSSCLASS)); + const bodyYear = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; + const headerWeekday = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[0]; + const headerDate = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS} span`))[1]; + let bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); - expect(dom.query(By.css(HelperTestFunctions.CALENDAR_COLUMN_CSSCLASS))).toBeDefined(); - const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); - const currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); + calendar.selectDate(calendar.viewDate); + fixture.detectChanges(); - expect(years.length).toEqual(6); - expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); + expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); + expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); + expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); + expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Sun'); - years[0].triggerEventHandler('click', { target: years[0].nativeElement }); - fixture.detectChanges(); + // change formatOptions and formatViews + const locale = 'fr'; + calendar.locale = locale; + fixture.detectChanges(); - expect(calendar.viewDate.getFullYear()).toEqual(2014); - }); + bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); + expect(calendar.locale).toEqual(locale); + expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('lun.,'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('17 sept.'); + expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); + expect(bodyMonth.nativeElement.textContent.trim()).toMatch('sept.'); + expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Dim.'); + }); - it('Calendar selection - single with event', () => { - fixture.detectChanges(); + it('Should properly render calendar DOM structure', () => { + const today = new Date(Date.now()); + calendar.viewDate = today; + fixture.detectChanges(); + const calendarRows = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS)); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + // 6 weeks + week header + expect(calendarRows.length).toEqual(7); - const nextDay = new Date(2017, 5, 14); + // 7 calendar rows * 7 elements in each + expect( + dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > igx-day-item`)).length + ).toEqual(42); + expect( + dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > span`)).length + ).toEqual(7); - expect((calendar.value as Date).toDateString()).toMatch( - new Date(2017, 5, 13).toDateString() - ); + // Today class applied + expect( + dom + .query(By.css(HelperTestFunctions.CURRENT_DATE_CSSCLASS)) + .nativeElement.textContent.trim() + ).toMatch(today.getDate().toString()); - spyOn(calendar.onSelection, 'emit'); + // Hide calendar header when not single selection + calendar.selection = 'multi'; + fixture.detectChanges(); - // Select 14th - weekDays[3].nativeElement.click(); - fixture.detectChanges(); + const calendarHeader = dom.query(By.css(HelperTestFunctions.CALENDAR_HEADER_CSSCLASS)); + expect(calendarHeader).toBeFalsy(); + }); + it('Calendar DOM structure - year view | month view', () => { + dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0].nativeElement.click(); + fixture.detectChanges(); - expect(calendar.onSelection.emit).toHaveBeenCalled(); - expect((calendar.value as Date).toDateString()).toMatch( - nextDay.toDateString() - ); - expect( - weekDays[3].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - expect( - (fixture.componentInstance.model as Date).toDateString() - ).toMatch(nextDay.toDateString()); - expect( - target.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(false); - }); + expect(dom.query(By.css(HelperTestFunctions.CALENDAR_ROW_WRAP_CSSCLASS))).toBeDefined(); + const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); + const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); - it('Calendar selection - outside of current month - 1', () => { - const parent = dom.query( - By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}:last-child`) - ); - const target = parent.childNodes.pop(); - - target.nativeElement.click(); - fixture.detectChanges(); - - expect( - (fixture.componentInstance.model as Date).toDateString() - ).toMatch(new Date(2017, 6, 8).toDateString()); - expect( - dom - .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) - .nativeElement.textContent.includes('Jul') - ).toBe(true); - }); + expect(months.length).toEqual(11); + expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); - it('Calendar selection - outside of current month - 2', () => { - const parent = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS))[1]; - const target = parent.queryAll(By.css(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS))[0]; - - target.nativeElement.click(); - fixture.detectChanges(); - - expect( - (fixture.componentInstance.model as Date).toDateString() - ).toMatch(new Date(2017, 4, 28).toDateString()); - expect( - dom - .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) - .nativeElement.textContent.includes('May') - ).toBe(true); - }); + months[0].nativeElement.click(); + fixture.detectChanges(); - it('Calendar selection - single through API', () => { - fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(0); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); - const nextDay = new Date(2017, 5, 14); + dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1].nativeElement.click(); + fixture.detectChanges(); - expect((calendar.value as Date).toDateString()).toMatch( - new Date(2017, 5, 13).toDateString() - ); + expect(dom.query(By.css(HelperTestFunctions.CALENDAR_COLUMN_CSSCLASS))).toBeDefined(); + const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); + const currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); - calendar.selectDate(new Date(2017, 5, 14)); - fixture.detectChanges(); + expect(years.length).toEqual(6); + expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); - expect((calendar.value as Date).toDateString()).toMatch( - nextDay.toDateString() - ); - expect( - weekDays[3].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - expect( - (fixture.componentInstance.model as Date).toDateString() - ).toMatch(nextDay.toDateString()); - expect( - target.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(false); - }); + years[0].triggerEventHandler('click', { target: years[0].nativeElement }); + fixture.detectChanges(); - it('Calendar selection - multiple with event', () => { - fixture.detectChanges(); + expect(calendar.viewDate.getFullYear()).toEqual(2014); + }); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + it('Calendar selection - single with event', () => { + fixture.detectChanges(); - calendar.selection = 'multi'; - fixture.detectChanges(); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); - expect(calendar.value instanceof Array).toBeTruthy(); - expect( - fixture.componentInstance.model instanceof Array - ).toBeTruthy(); - expect((calendar.value as Date[]).length).toEqual(0); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 0 - ); + const nextDay = new Date(2017, 5, 14); - for (let index = 0; index < weekDays.length; index++) { - weekDays[index].nativeElement.click(); + expect((calendar.value as Date).toDateString()).toMatch( + new Date(2017, 5, 13).toDateString() + ); + + spyOn(calendar.onSelection, 'emit'); + + // Select 14th + weekDays[3].nativeElement.click(); fixture.detectChanges(); - } - expect((calendar.value as Date[]).length).toEqual(7); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 7 - ); - weekDays.forEach((el) => { + expect(calendar.onSelection.emit).toHaveBeenCalled(); + expect((calendar.value as Date).toDateString()).toMatch( + nextDay.toDateString() + ); + HelperTestFunctions.verifyDateSelected(weekDays[3]); expect( - el.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) + (fixture.componentInstance.model as Date).toDateString() + ).toMatch(nextDay.toDateString()); + HelperTestFunctions.verifyDateNotSelected(target); + }); + + it('Calendar selection - outside of current month - 1', () => { + const parent = dom.query( + By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}:last-child`) + ); + const target = parent.childNodes.pop(); + + target.nativeElement.click(); + fixture.detectChanges(); + + expect( + (fixture.componentInstance.model as Date).toDateString() + ).toMatch(new Date(2017, 6, 8).toDateString()); + expect( + dom + .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) + .nativeElement.textContent.includes('Jul') ).toBe(true); }); - // Deselect last day - weekDays[weekDays.length - 1].nativeElement.click(); - fixture.detectChanges(); + it('Calendar selection - outside of current month - 2', () => { + const parent = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS))[1]; + const target = parent.queryAll(By.css(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS))[0]; - expect((calendar.value as Date[]).length).toEqual(6); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 6 - ); - expect( - weekDays[weekDays.length - 1].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(false); - }); + target.nativeElement.click(); + fixture.detectChanges(); - it('Calendar selection - multiple through API', () => { - fixture.detectChanges(); + expect( + (fixture.componentInstance.model as Date).toDateString() + ).toMatch(new Date(2017, 4, 28).toDateString()); + expect( + dom + .query(By.css(HelperTestFunctions.CALENDAR_HEADER_DATE_CSSCLASS)) + .nativeElement.textContent.includes('May') + ).toBe(true); + }); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + it('Calendar selection - single through API', () => { + fixture.detectChanges(); - calendar.selection = 'multi'; - fixture.detectChanges(); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + const nextDay = new Date(2017, 5, 14); - const lastDay = new Date(2017, 5, 17); + expect((calendar.value as Date).toDateString()).toMatch( + new Date(2017, 5, 13).toDateString() + ); - // Single date - calendar.selectDate(lastDay); - fixture.detectChanges(); + calendar.selectDate(new Date(2017, 5, 14)); + fixture.detectChanges(); - expect( - (fixture.componentInstance.model as Date[])[0].toDateString() - ).toMatch(lastDay.toDateString()); - expect(calendar.value[0].toDateString()).toMatch( - lastDay.toDateString() - ); - expect( - weekDays[weekDays.length - 1].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - - // Multiple dates - calendar.selectDate([new Date(2017, 5, 11), new Date(2017, 5, 12)]); - fixture.detectChanges(); - - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 3 - ); - expect((calendar.value as Date[]).length).toEqual(3); - // 11th June - expect( - weekDays[0].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - // 12th June - expect( - weekDays[1].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - }); + expect((calendar.value as Date).toDateString()).toMatch( + nextDay.toDateString() + ); + HelperTestFunctions.verifyDateSelected(weekDays[3]); + expect( + (fixture.componentInstance.model as Date).toDateString() + ).toMatch(nextDay.toDateString()); + HelperTestFunctions.verifyDateNotSelected(target); + }); - it('Calendar selection - range with event', () => { - fixture.detectChanges(); + it('Calendar selection - multiple with event', () => { + fixture.detectChanges(); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); - calendar.selection = 'range'; - fixture.detectChanges(); + calendar.selection = 'multi'; + fixture.detectChanges(); - const lastDay = new Date(2017, 5, 17); - const firstDay = new Date(2017, 5, 11); + expect(calendar.value instanceof Array).toBeTruthy(); + expect( + fixture.componentInstance.model instanceof Array + ).toBeTruthy(); + expect((calendar.value as Date[]).length).toEqual(0); + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 0 + ); + + for (let index = 0; index < weekDays.length; index++) { + weekDays[index].nativeElement.click(); + fixture.detectChanges(); + } + + expect((calendar.value as Date[]).length).toEqual(7); + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 7 + ); + weekDays.forEach((el) => { + HelperTestFunctions.verifyDateSelected(el); + }); + + // Deselect last day + weekDays[weekDays.length - 1].nativeElement.click(); + fixture.detectChanges(); - // Toggle range selection... - weekDays[0].nativeElement.click(); - fixture.detectChanges(); + expect((calendar.value as Date[]).length).toEqual(6); + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 6 + ); + HelperTestFunctions.verifyDateNotSelected(weekDays[weekDays.length - 1]); + }); + + it('Calendar selection - multiple through API', () => { + fixture.detectChanges(); + + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + + calendar.selection = 'multi'; + fixture.detectChanges(); + + const lastDay = new Date(2017, 5, 17); + + // Single date + calendar.selectDate(lastDay); + fixture.detectChanges(); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 1 - ); - expect((calendar.value as Date[]).length).toEqual(1); - expect( - (fixture.componentInstance.model as Date[])[0].toDateString() - ).toMatch(firstDay.toDateString()); - expect( - weekDays[0].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - - // ...and cancel it - weekDays[0].nativeElement.click(); - fixture.detectChanges(); - - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 0 - ); - expect((calendar.value as Date[]).length).toEqual(0); - expect( - weekDays[0].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(false); - - // Toggle range selection... - weekDays[0].nativeElement.click(); - fixture.detectChanges(); - - // ...and complete it - weekDays[weekDays.length - 1].nativeElement.click(); - fixture.detectChanges(); - - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 7 - ); - expect((calendar.value as Date[]).length).toEqual(7); - expect(calendar.value[0].toDateString()).toMatch( - firstDay.toDateString() - ); - expect( - calendar.value[ - (calendar.value as Date[]).length - 1 - ].toDateString() - ).toMatch(lastDay.toDateString()); - weekDays.forEach((el) => { expect( - el.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); + (fixture.componentInstance.model as Date[])[0].toDateString() + ).toMatch(lastDay.toDateString()); + expect(calendar.value[0].toDateString()).toMatch( + lastDay.toDateString() + ); + HelperTestFunctions.verifyDateSelected(weekDays[weekDays.length - 1]); + + // Multiple dates + calendar.selectDate([new Date(2017, 5, 11), new Date(2017, 5, 12)]); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 3 + ); + expect((calendar.value as Date[]).length).toEqual(3); + // 11th June + HelperTestFunctions.verifyDateSelected(weekDays[0]); + // 12th June + HelperTestFunctions.verifyDateSelected(weekDays[1]); }); - }); - it('Calendar selection - range through API', () => { - fixture.detectChanges(); + it('Calendar selection - range with event', () => { + fixture.detectChanges(); - const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); - const weekDiv = target.parent; - const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); - calendar.selection = 'range'; - fixture.detectChanges(); + calendar.selection = 'range'; + fixture.detectChanges(); - const lastDay = new Date(2017, 5, 17); - const midDay = new Date(2017, 5, 14); - const firstDay = new Date(2017, 5, 11); + const lastDay = new Date(2017, 5, 17); + const firstDay = new Date(2017, 5, 11); - calendar.selectDate([firstDay, lastDay]); - fixture.detectChanges(); + // Toggle range selection... + weekDays[0].nativeElement.click(); + fixture.detectChanges(); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 7 - ); - expect((calendar.value as Date[]).length).toEqual(7); - expect(calendar.value[0].toDateString()).toMatch( - firstDay.toDateString() - ); - expect( - calendar.value[ - (calendar.value as Date[]).length - 1 - ].toDateString() - ).toMatch(lastDay.toDateString()); - weekDays.forEach((el) => { + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 1 + ); + expect((calendar.value as Date[]).length).toEqual(1); expect( - el.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); + (fixture.componentInstance.model as Date[])[0].toDateString() + ).toMatch(firstDay.toDateString()); + HelperTestFunctions.verifyDateSelected(weekDays[0]); + + // ...and cancel it + weekDays[0].nativeElement.click(); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 0 + ); + expect((calendar.value as Date[]).length).toEqual(0); + HelperTestFunctions.verifyDateNotSelected(weekDays[0]); + + // Toggle range selection... + weekDays[0].nativeElement.click(); + fixture.detectChanges(); + + // ...and complete it + weekDays[weekDays.length - 1].nativeElement.click(); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 7 + ); + expect((calendar.value as Date[]).length).toEqual(7); + expect(calendar.value[0].toDateString()).toMatch( + firstDay.toDateString() + ); + expect( + calendar.value[ + (calendar.value as Date[]).length - 1 + ].toDateString() + ).toMatch(lastDay.toDateString()); + weekDays.forEach((el) => { + HelperTestFunctions.verifyDateSelected(el); + }); }); - calendar.selectDate([firstDay, midDay]); - fixture.detectChanges(); + it('Calendar selection - range through API', () => { + fixture.detectChanges(); - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 4 - ); - expect((calendar.value as Date[]).length).toEqual(4); - expect(calendar.value[0].toDateString()).toMatch( - firstDay.toDateString() - ); - expect( - calendar.value[ - (calendar.value as Date[]).length - 1 - ].toDateString() - ).toMatch(midDay.toDateString()); - for (const i of [0, 1, 2, 3]) { + const target = dom.query(By.css(HelperTestFunctions.SELECTED_DATE_CSSCLASS)); + const weekDiv = target.parent; + const weekDays = weekDiv.queryAll(By.css(HelperTestFunctions.DAY_CSSCLASS)); + + calendar.selection = 'range'; + fixture.detectChanges(); + + const lastDay = new Date(2017, 5, 17); + const midDay = new Date(2017, 5, 14); + const firstDay = new Date(2017, 5, 11); + + calendar.selectDate([firstDay, lastDay]); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 7 + ); + expect((calendar.value as Date[]).length).toEqual(7); + expect(calendar.value[0].toDateString()).toMatch( + firstDay.toDateString() + ); expect( - weekDays[i].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - } - - // Select with only one day - calendar.selectDate([lastDay]); - fixture.detectChanges(); - - expect((calendar.value as Date[]).length).toEqual(1); - expect(calendar.value[0].toDateString()).toMatch(lastDay.toDateString()); - expect( - weekDays[6].nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); - - // Select with array of 3 days - calendar.selectDate([midDay, lastDay, firstDay]); - fixture.detectChanges(); - - expect((fixture.componentInstance.model as Date[]).length).toEqual( - 7 - ); - expect((calendar.value as Date[]).length).toEqual(7); - expect(calendar.value[0].toDateString()).toMatch( - firstDay.toDateString() - ); - expect( - calendar.value[ - (calendar.value as Date[]).length - 1 - ].toDateString() - ).toMatch(lastDay.toDateString()); - weekDays.forEach((el) => { + calendar.value[ + (calendar.value as Date[]).length - 1 + ].toDateString() + ).toMatch(lastDay.toDateString()); + weekDays.forEach((el) => { + HelperTestFunctions.verifyDateSelected(el); + }); + + calendar.selectDate([firstDay, midDay]); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 4 + ); + expect((calendar.value as Date[]).length).toEqual(4); + expect(calendar.value[0].toDateString()).toMatch( + firstDay.toDateString() + ); expect( - el.nativeElement.classList.contains( - 'igx-calendar__date--selected' - ) - ).toBe(true); + calendar.value[ + (calendar.value as Date[]).length - 1 + ].toDateString() + ).toMatch(midDay.toDateString()); + for (const i of [0, 1, 2, 3]) { + HelperTestFunctions.verifyDateSelected(weekDays[i]); + } + + // Select with only one day + calendar.selectDate([lastDay]); + fixture.detectChanges(); + + expect((calendar.value as Date[]).length).toEqual(1); + expect(calendar.value[0].toDateString()).toMatch(lastDay.toDateString()); + HelperTestFunctions.verifyDateSelected(weekDays[6]); + + // Select with array of 3 days + calendar.selectDate([midDay, lastDay, firstDay]); + fixture.detectChanges(); + + expect((fixture.componentInstance.model as Date[]).length).toEqual( + 7 + ); + expect((calendar.value as Date[]).length).toEqual(7); + expect(calendar.value[0].toDateString()).toMatch( + firstDay.toDateString() + ); + expect( + calendar.value[ + (calendar.value as Date[]).length - 1 + ].toDateString() + ).toMatch(lastDay.toDateString()); + weekDays.forEach((el) => { + HelperTestFunctions.verifyDateSelected(el); + }); }); - }); - it('Calendar keyboard navigation - PageUp/PageDown', () => { - const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); + it('Calendar keyboard navigation - PageUp/PageDown', () => { + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); + + UIInteractions.simulateKeyDownEvent(component.nativeElement, 'PageUp'); + fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(4); + + calendar.viewDate = new Date(2017, 5, 13); + fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(component.nativeElement, 'PageDown'); + fixture.detectChanges(); + + expect(calendar.viewDate.getMonth()).toEqual(6); + UIInteractions.triggerKeyDownEvtUponElem('PageUp', component.nativeElement, true, false, true); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(component.nativeElement, 'PageUp'); - fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(4); + expect(calendar.viewDate.getFullYear()).toEqual(2016); - calendar.viewDate = new Date(2017, 5, 13); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(component.nativeElement, 'PageDown'); - fixture.detectChanges(); + calendar.viewDate = new Date(2017, 5, 13); + fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(6); - UIInteractions.triggerKeyDownEvtUponElem('PageUp', component.nativeElement, true, false, true); - fixture.detectChanges(); + UIInteractions.triggerKeyDownEvtUponElem('PageDown', component.nativeElement, true, false, true); + fixture.detectChanges(); - expect(calendar.viewDate.getFullYear()).toEqual(2016); + expect(calendar.viewDate.getFullYear()).toEqual(2018); + }); - calendar.viewDate = new Date(2017, 5, 13); - fixture.detectChanges(); + it('Calendar keyboard navigation - Home/End/Enter', () => { + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); - UIInteractions.triggerKeyDownEvtUponElem('PageDown', component.nativeElement, true, false, true); - fixture.detectChanges(); + const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); + const firstDay = days[0]; + const lastDay = days[days.length - 1]; - expect(calendar.viewDate.getFullYear()).toEqual(2018); - }); + UIInteractions.simulateKeyDownEvent(component.nativeElement, 'Home'); + fixture.detectChanges(); - it('Calendar keyboard navigation - Home/End/Enter', () => { - const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); + expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); + expect(document.activeElement.textContent.trim()).toMatch('1'); - const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); - const firstDay = days[0]; - const lastDay = days[days.length - 1]; + UIInteractions.simulateKeyDownEvent(component.nativeElement, 'End'); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(component.nativeElement, 'Home'); - fixture.detectChanges(); + expect(document.activeElement.textContent).toMatch(lastDay.nativeElement.textContent); + expect(document.activeElement.textContent.trim()).toMatch('30'); - expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); - expect(document.activeElement.textContent.trim()).toMatch('1'); + UIInteractions.simulateKeyDownEvent(firstDay.nativeElement, 'Enter'); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(component.nativeElement, 'End'); - fixture.detectChanges(); + expect((calendar.value as Date).toDateString()).toMatch(new Date(2017, 5, 1).toDateString()); + }); - expect(document.activeElement.textContent).toMatch(lastDay.nativeElement.textContent); - expect(document.activeElement.textContent.trim()).toMatch('30'); + it('Calendar keyboard navigation - Arrow keys', () => { + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); - UIInteractions.simulateKeyDownEvent(firstDay.nativeElement, 'Enter'); - fixture.detectChanges(); + const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); + const firstDay = days[0]; - expect((calendar.value as Date).toDateString()).toMatch(new Date(2017, 5, 1).toDateString()); - }); + UIInteractions.simulateKeyDownEvent(component.nativeElement, 'Home'); + fixture.detectChanges(); + + expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); + expect(document.activeElement.textContent.trim()).toMatch('1'); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + + expect(document.activeElement.textContent.trim()).toMatch('8'); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + + expect(document.activeElement.textContent.trim()).toMatch('7'); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + fixture.detectChanges(); + + expect(document.activeElement.textContent.trim()).toMatch('8'); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); + + expect(document.activeElement.textContent.trim()).toMatch('1'); + }); + + it('Calendar date should persist the focus when select date in the (next/prev) month.', fakeAsync (() => { + const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); + const calendarMonth = calendar.daysView.getCalendarMonth; + let value = calendarMonth[0][4]; - it('Calendar keyboard navigation - Arrow keys', () => { - const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); + UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement, true); - const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); - const firstDay = days[0]; + let date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; + UIInteractions.simulateKeyDownEvent(date, 'Enter'); + fixture.detectChanges(); + flush(); + + expect(document.activeElement).toBe(date); + + value = calendarMonth[4][6]; + date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; + + UIInteractions.simulateKeyDownEvent(date, 'Enter'); + fixture.detectChanges(); + flush(); + + date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; + expect(document.activeElement).toBe(date); + UIInteractions.triggerKeyDownEvtUponElem('ArrowRight', document.activeElement, true); + + expect(document.activeElement.textContent.trim()).toMatch('2'); + })); + + it('Should navigate to first enabled date when using "home" key.', fakeAsync (() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [new Date(2017, 5, 1), new Date(2017, 5, 2)]; + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, + { type: DateRangeType.Weekends }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + fixture.detectChanges(); + + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 5).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); + + it('Should navigate to last enabled date when using "end" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const rangeDates = [new Date(2017, 5, 28), new Date(2017, 5, 30)]; + dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }, + { type: DateRangeType.Specific, dateRange: [new Date(2017, 5, 27)] }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); + fixture.detectChanges(); + + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 26).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); + + it('Should navigate to first enabled date when using "arrow up" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [new Date(2017, 5, 23), new Date(2017, 5, 16)]; + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, + { type: DateRangeType.Weekends }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); + fixture.detectChanges(); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); + + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 9).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); + + it('Should navigate to first enabled date when using "arrow down" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [new Date(2017, 5, 8), new Date(2017, 5, 15)]; + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, + { type: DateRangeType.Weekends }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + fixture.detectChanges(); + + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(component.nativeElement, 'Home'); - fixture.detectChanges(); + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 22).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); - expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); - expect(document.activeElement.textContent.trim()).toMatch('1'); + it('Should navigate to first enabled date when using "arrow left" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; + dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); - expect(document.activeElement.textContent.trim()).toMatch('8'); + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 1).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); + it('Should navigate to first enabled date when using "arrow right" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; + dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); + + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + fixture.detectChanges(); - expect(document.activeElement.textContent.trim()).toMatch('7'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - fixture.detectChanges(); + const date = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 30).getTime())[0]; + expect(date.nativeElement).toBe(document.activeElement); + })); + + it('Should not select disabled dates when having "range" selection', () => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const rangeDates = [new Date(2017, 5, 10), new Date(2017, 5, 15)]; + dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); + calendar.disabledDates = dateRangeDescriptors; + calendar.selection = 'range'; + fixture.detectChanges(); - expect(document.activeElement.textContent.trim()).toMatch('8'); + const fromDate = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 5).getTime())[0]; + fromDate.nativeElement.click(); + fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); + const toDate = calendar.daysView.dates.filter( + d => getDate(d).getTime() === new Date(2017, 5, 20).getTime())[0]; + toDate.nativeElement.click(); + fixture.detectChanges(); - expect(document.activeElement.textContent.trim()).toMatch('1'); + const selectedDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 5).getTime() && + dateTime <= new Date(2017, 5, 9).getTime()) || + (dateTime >= new Date(2017, 5, 16).getTime() && + dateTime <= new Date(2017, 5, 20).getTime()); + }); + + selectedDates.forEach(d => { + expect(d.selected).toBe(true); + }); + + const notSelectedDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return dateTime >= new Date(2017, 5, 10).getTime() && + dateTime <= new Date(2017, 5, 15).getTime(); + }); + + notSelectedDates.forEach(d => { + expect(d.selected).toBe(false); + }); + }); }); - it('Calendar date should persist the focus when select date in the (next/prev) month.', fakeAsync (() => { - const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); - const calendarMonth = calendar.daysView.getCalendarMonth; - let value = calendarMonth[0][4]; - - UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement, true); - - let date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; - UIInteractions.simulateKeyDownEvent(date, 'Enter'); - fixture.detectChanges(); - flush(); - - expect(document.activeElement).toBe(date); - - value = calendarMonth[4][6]; - date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; - - UIInteractions.simulateKeyDownEvent(date, 'Enter'); - fixture.detectChanges(); - flush(); - - date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; - expect(document.activeElement).toBe(date); - UIInteractions.triggerKeyDownEvtUponElem('ArrowRight', document.activeElement, true); - - expect(document.activeElement.textContent.trim()).toMatch('2'); - })); - - it('Should navigate to first enabled date when using "home" key.', fakeAsync (() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [new Date(2017, 5, 1), new Date(2017, 5, 2)]; - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, - { type: DateRangeType.Weekends }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 5).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to last enabled date when using "end" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const rangeDates = [new Date(2017, 5, 28), new Date(2017, 5, 30)]; - dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }, - { type: DateRangeType.Specific, dateRange: [new Date(2017, 5, 27)] }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 26).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to first enabled date when using "arrow up" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [new Date(2017, 5, 23), new Date(2017, 5, 16)]; - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, - { type: DateRangeType.Weekends }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - fixture.detectChanges(); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 9).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to first enabled date when using "arrow down" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [new Date(2017, 5, 8), new Date(2017, 5, 15)]; - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }, - { type: DateRangeType.Weekends }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 22).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to first enabled date when using "arrow left" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; - dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - fixture.detectChanges(); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 1).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to first enabled date when using "arrow right" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const rangeDates = [new Date(2017, 5, 2), new Date(2017, 5, 29)]; - dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - fixture.detectChanges(); - - const date = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 30).getTime())[0]; - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should not select disabled dates when having "range" selection', () => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const rangeDates = [new Date(2017, 5, 10), new Date(2017, 5, 15)]; - dateRangeDescriptors.push({ type: DateRangeType.Between, dateRange: rangeDates }); - calendar.disabledDates = dateRangeDescriptors; - calendar.selection = 'range'; - fixture.detectChanges(); - - const fromDate = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 5).getTime())[0]; - fromDate.nativeElement.click(); - fixture.detectChanges(); - - const toDate = calendar.daysView.dates.filter( - d => getDate(d).getTime() === new Date(2017, 5, 20).getTime())[0]; - toDate.nativeElement.click(); - fixture.detectChanges(); - - const selectedDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 5).getTime() && - dateTime <= new Date(2017, 5, 9).getTime()) || - (dateTime >= new Date(2017, 5, 16).getTime() && - dateTime <= new Date(2017, 5, 20).getTime()); + describe('Disabled dates - ', () => { + it('Should disable date when using "After" date descriptor.', () => { + DateRangesPropertiesTester.testAfter( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates); }); - selectedDates.forEach(d => { - expect(d.selected).toBe(true); + it('Should disable date when using "Before" date descriptor.', () => { + DateRangesPropertiesTester.testBefore( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - const notSelectedDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return dateTime >= new Date(2017, 5, 10).getTime() && - dateTime <= new Date(2017, 5, 15).getTime(); + it('Should disable date when using "Between" date descriptor with min date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMinDateFirst( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - notSelectedDates.forEach(d => { - expect(d.selected).toBe(false); + it('Should disable date when using "Between" date descriptor with max date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMaxDateFirst( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); }); - }); - }); - describe('Disabled dates - ', () => { - it('Should disable date when using "After" date descriptor.', () => { - DateRangesPropertiesTester.testAfter( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates); - }); + it('Should disable date when using "Between" date descriptor with min and max the same.', () => { + DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Before" date descriptor.', () => { - DateRangesPropertiesTester.testBefore( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable date when using overlapping "Between" ranges.', () => { + DateRangesPropertiesTester.testOverlappingBetweens( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Between" date descriptor with min date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMinDateFirst( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable date when using "Specific" date descriptor.', () => { + DateRangesPropertiesTester.testSpecific( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Between" date descriptor with max date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMaxDateFirst( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable date when using "Weekdays" date descriptor.', () => { + DateRangesPropertiesTester.testWeekdays( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Between" date descriptor with min and max the same.', () => { - DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable date when using "Weekends" date descriptor.', () => { + DateRangesPropertiesTester.testWeekends( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using overlapping "Between" ranges.', () => { - DateRangesPropertiesTester.testOverlappingBetweens( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable dates when using multiple ranges.', () => { + DateRangesPropertiesTester.testMultipleRanges( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Specific" date descriptor.', () => { - DateRangesPropertiesTester.testSpecific( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should disable previous month with "before" date descriptor', () => { + DateRangesPropertiesTester.testPreviousMonthRange( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); - it('Should disable date when using "Weekdays" date descriptor.', () => { - DateRangesPropertiesTester.testWeekdays( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); + it('Should be able to change disable dates runtime.', () => { + DateRangesPropertiesTester.testRangeUpdateRuntime( + DateRangesPropertiesTester.assignDisableDatesDescriptors, + DateRangesPropertiesTester.testDisabledDates + ); + }); }); - it('Should disable date when using "Weekends" date descriptor.', () => { - DateRangesPropertiesTester.testWeekends( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + describe('Special dates - ', () => { + it('Should mark date as special when using "After" date descriptor.', () => { + DateRangesPropertiesTester.testAfter( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable dates when using multiple ranges.', () => { - DateRangesPropertiesTester.testMultipleRanges( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Before" date descriptor.', () => { + DateRangesPropertiesTester.testBefore( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should disable previous month with "before" date descriptor', () => { - DateRangesPropertiesTester.testPreviousMonthRange( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); + it('Should mark date as special when using "Between" date descriptor with min date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMinDateFirst( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should be able to change disable dates runtime.', () => { - DateRangesPropertiesTester.testRangeUpdateRuntime( - DateRangesPropertiesTester.assignDisableDatesDescriptors, - DateRangesPropertiesTester.testDisabledDates - ); - }); - }); + it('Should mark date as special when using "Between" date descriptor with max date declared first.', () => { + DateRangesPropertiesTester.testBetweenWithMaxDateFirst( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - describe('Special dates - ', () => { - it('Should mark date as special when using "After" date descriptor.', () => { - DateRangesPropertiesTester.testAfter( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark date as special when using "Between" date descriptor with min and max the same.', () => { + DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Before" date descriptor.', () => { - DateRangesPropertiesTester.testBefore( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark date as special when using overlapping "Between" ranges.', () => { + DateRangesPropertiesTester.testOverlappingBetweens( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Between" date descriptor with min date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMinDateFirst( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark date as special when using "Specific" date descriptor.', () => { + DateRangesPropertiesTester.testSpecific( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Between" date descriptor with max date declared first.', () => { - DateRangesPropertiesTester.testBetweenWithMaxDateFirst( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark date as special when using "Weekdays" date descriptor.', () => { + DateRangesPropertiesTester.testWeekdays( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Between" date descriptor with min and max the same.', () => { - DateRangesPropertiesTester.testBetweenWithMinMaxTheSame( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark date as special when using "Weekends" date descriptor.', () => { + DateRangesPropertiesTester.testWeekends( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using overlapping "Between" ranges.', () => { - DateRangesPropertiesTester.testOverlappingBetweens( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark dates as special when using multiple ranges.', () => { + DateRangesPropertiesTester.testMultipleRanges( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Specific" date descriptor.', () => { - DateRangesPropertiesTester.testSpecific( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + it('Should mark as special previous month with "before" date descriptor', () => { + DateRangesPropertiesTester.testPreviousMonthRange( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); - it('Should mark date as special when using "Weekdays" date descriptor.', () => { - DateRangesPropertiesTester.testWeekdays( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); + it('Should be able to change special dates runtime.', () => { + DateRangesPropertiesTester.testRangeUpdateRuntime( + DateRangesPropertiesTester.assignSpecialDatesDescriptors, + DateRangesPropertiesTester.testSpecialDates + ); + }); }); - it('Should mark date as special when using "Weekends" date descriptor.', () => { - DateRangesPropertiesTester.testWeekends( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + describe('Disabled special dates - ', () => { + let fixture, calendar; - it('Should mark dates as special when using multiple ranges.', () => { - DateRangesPropertiesTester.testMultipleRanges( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); - }); + beforeEach(async(() => { + fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); + fixture.detectChanges(); + calendar = fixture.componentInstance.calendar; + })); + + it('Should be able to set disabled and active dates as @Input', () => { + expect(calendar.specialDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); + expect(calendar.disabledDates).toEqual( + [{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 23), new Date(2017, 5, 29)]}]); + let specialDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 1).getTime() && + dateTime <= new Date(2017, 5, 6).getTime()); + }); + + specialDates.forEach(d => { + expect(d.isSpecial).toBe(true); + }); + + let disabledDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 23).getTime() && + dateTime <= new Date(2017, 5, 29).getTime()); + }); + + disabledDates.forEach(d => { + expect(d.isDisabled).toBe(true); + expect(d.isDisabledCSS).toBe(true); + }); + + // change Inputs + fixture.componentInstance.disabledDates = [{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]; + fixture.componentInstance.specialDates = [{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]; + fixture.detectChanges(); - it('Should mark as special previous month with "before" date descriptor', () => { - DateRangesPropertiesTester.testPreviousMonthRange( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates - ); + expect(calendar.disabledDates).toEqual([{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]); + expect(calendar.specialDates).toEqual([{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]); + specialDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime >= new Date(2017, 5, 20).getTime()); + }); + + specialDates.forEach(d => { + expect(d.isSpecial).toBe(true); + }); + + disabledDates = calendar.daysView.dates.toArray().filter(d => { + const dateTime = getDate(d).getTime(); + return (dateTime <= new Date(2017, 5, 9).getTime()); + }); + + disabledDates.forEach(d => { + expect(d.isDisabled).toBe(true); + expect(d.isDisabledCSS).toBe(true); + }); + }); + + it('Should not select date from model, if it is part of disabled dates', () => { + expect(calendar.value).toBeFalsy(); + }); + + it('Should not select date from model in range selection, if model passes null', () => { + calendar.selection = 'range'; + fixture.componentInstance.model = null; + fixture.detectChanges(); + + expect((calendar.value as Date[]).length).toEqual(0); + }); }); - it('Should be able to change special dates runtime.', () => { - DateRangesPropertiesTester.testRangeUpdateRuntime( - DateRangesPropertiesTester.assignSpecialDatesDescriptors, - DateRangesPropertiesTester.testSpecialDates + describe('Select and deselect dates - ', () => { + let fixture, calendar, ci; + beforeEach( + async(() => { + fixture = TestBed.createComponent(IgxCalendarSampleComponent); + fixture.detectChanges(); + ci = fixture.componentInstance; + calendar = ci.calendar; + }) ); - }); - }); - describe('Disabled special dates - ', () => { - let fixture, calendar; - - beforeEach(async(() => { - fixture = TestBed.createComponent(IgxCalendarDisabledSpecialDatesComponent); - fixture.detectChanges(); - calendar = fixture.componentInstance.calendar; - })); - - it('Should be able to set disabled and active dates as @Input', () => { - expect(calendar.specialDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); - expect(calendar.disabledDates).toEqual( - [{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 23), new Date(2017, 5, 29)]}]); - let specialDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 1).getTime() && - dateTime <= new Date(2017, 5, 6).getTime()); + it('Deselect using API. Should deselect in "single" selection mode.', () => { + const date = calendar.viewDate; + calendar.selectDate(date); + fixture.detectChanges(); + + let selectedDate = calendar.value; + expect(selectedDate).toEqual(date); + + calendar.deselectDate(date); + fixture.detectChanges(); + + selectedDate = calendar.value; + expect(selectedDate).toBe(null); + + // Deselect with date different than selected date + calendar.selectDate(date); + fixture.detectChanges(); + + selectedDate = calendar.value; + expect(selectedDate).toEqual(date); + + const dateToDeselect = new Date(date); + dateToDeselect.setDate(dateToDeselect.getDate() + 5); + + calendar.deselectDate(dateToDeselect); + fixture.detectChanges(); + + selectedDate = calendar.value; + expect(selectedDate).toEqual(date); }); - specialDates.forEach(d => { - expect(d.isSpecial).toBe(true); + it('Deselect using API. Should deselect in "multi" selection mode.', () => { + calendar.selection = 'multi'; + fixture.detectChanges(); + + const year = calendar.viewDate.getFullYear(); + const month = calendar.viewDate.getMonth(); + const dates = []; + const datesCount = 10; + for (let i = 0; i < datesCount; i++) { + dates.push(new Date(year, month, i + 1)); + } + + fixture.detectChanges(); + calendar.selectDate(dates); + + fixture.detectChanges(); + const evenDates = dates.filter(d => d.getDate() % 2 === 0); + calendar.deselectDate(evenDates); + + fixture.detectChanges(); + const oddDates = dates.filter(d => d.getDate() % 2 !== 0); + let selectedDates: Date[] = calendar.value as Date[]; + expect(selectedDates.length).toBe(5); + for (const selectedDate of selectedDates) { + const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); + expect(fdate).toBeTruthy(); + } + + // Deselect with array not included in the selected dates + calendar.deselectDate(evenDates); + fixture.detectChanges(); + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(5); + for (const selectedDate of selectedDates) { + const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); + expect(fdate).toBeTruthy(); + } + + // Deselect one date included in the selected dates + calendar.deselectDate([oddDates[0]]); + fixture.detectChanges(); + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(4); + for (const selectedDate of selectedDates) { + const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); + expect(fdate).toBeTruthy(); + } + + // Deselect with array with all dates included in the selected dates + calendar.deselectDate(oddDates); + fixture.detectChanges(); + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); }); - let disabledDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 23).getTime() && - dateTime <= new Date(2017, 5, 29).getTime()); + it('Deselect using API. Should deselect in "range" selection mode when period is not included in the selected dates', () => { + ci.model = []; + calendar.selection = 'range'; + fixture.detectChanges(); + + const startDate = calendar.viewDate; + const endDate = new Date(calendar.viewDate); + endDate.setDate(endDate.getDate() + 5); + const startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() - 7); + const endDateDeselect = new Date(endDate); + endDateDeselect.setDate(startDate.getDate() - 3); + + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + let selectedDates: Date[] = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + expect(selectedDates[0]).toEqual(startDate); + expect(selectedDates[5]).toEqual(endDate); + + // Deselect with range which is not included in the selected dates + calendar.deselectDate([startDateDeselect, endDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + expect(selectedDates[0]).toEqual(startDate); + expect(selectedDates[5]).toEqual(endDate); }); - disabledDates.forEach(d => { - expect(d.isDisabled).toBe(true); - expect(d.isDisabledCSS).toBe(true); + it('Deselect using API. Should deselect in "range" selection mode when period is not included.', () => { + ci.model = []; + calendar.selection = 'range'; + fixture.detectChanges(); + + const startDate = calendar.viewDate; + const endDate = new Date(calendar.viewDate); + endDate.setDate(endDate.getDate() + 5); + + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + let selectedDates: Date[] = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + expect(selectedDates[0]).toEqual(startDate); + expect(selectedDates[5]).toEqual(endDate); + + // Deselect with range is includes the selection + let startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() - 7); + let endDateDeselect = new Date(endDate); + endDateDeselect.setDate(endDate.getDate() + 5); + + calendar.deselectDate([startDateDeselect, endDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); + + // Deselect with range which includes the beginning of the selection + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() - 7); + endDateDeselect = new Date(endDate); + endDateDeselect.setDate(endDate.getDate() - 2); + calendar.deselectDate([startDateDeselect, endDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); + + // Deselect with range which includes the end of the selection + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() + 2); + endDateDeselect = new Date(endDate); + endDateDeselect.setDate(endDate.getDate() + 5); + calendar.deselectDate([startDateDeselect, endDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); + + // Deselect with range which is inside the selection + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() + 1); + endDateDeselect = new Date(endDate); + endDateDeselect.setDate(endDate.getDate() - 1); + calendar.deselectDate([startDateDeselect, endDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); }); - // change Inputs - fixture.componentInstance.disabledDates = [{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]; - fixture.componentInstance.specialDates = [{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]; - fixture.detectChanges(); + it('Deselect using API. Should deselect in "range" with array of dates.', () => { + ci.model = []; + calendar.selection = 'range'; + fixture.detectChanges(); + + const startDate = calendar.viewDate; + const endDate = new Date(calendar.viewDate); + endDate.setDate(endDate.getDate() + 5); + const endDateDeselect = new Date(endDate); + endDateDeselect.setDate(endDate.getDate() - 1); + const midDateDeselect = new Date(endDate); + + // Deselect with range with only one date + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + let selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + let startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() - 5); + calendar.deselectDate([startDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() + 2); + calendar.deselectDate([startDateDeselect]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); + + // Deselect with array of dates + calendar.selectDate([startDate, endDate]); + fixture.detectChanges(); + + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(6); + + startDateDeselect = new Date(startDate); + startDateDeselect.setDate(startDate.getDate() - 10); + + midDateDeselect.setDate(endDate.getDate() + 3); + calendar.deselectDate([midDateDeselect, endDateDeselect, startDateDeselect]); + fixture.detectChanges(); - expect(calendar.disabledDates).toEqual([{type: DateRangeType.Before, dateRange: [new Date(2017, 5, 10)]}]); - expect(calendar.specialDates).toEqual([{type: DateRangeType.After, dateRange: [new Date(2017, 5, 19)]}]); - specialDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime >= new Date(2017, 5, 20).getTime()); + selectedDates = calendar.value as Date[]; + expect(selectedDates.length).toBe(0); }); - specialDates.forEach(d => { - expect(d.isSpecial).toBe(true); + it('Deselect using API. Should deselect all in "single" mode.', () => { + const date = calendar.viewDate; + calendar.selectDate(date); + fixture.detectChanges(); + + let selectedDate = calendar.value; + expect(selectedDate).toEqual(date); + + calendar.deselectDate(); + fixture.detectChanges(); + + selectedDate = calendar.value; + expect(selectedDate).toBe(null); }); - disabledDates = calendar.daysView.dates.toArray().filter(d => { - const dateTime = getDate(d).getTime(); - return (dateTime <= new Date(2017, 5, 9).getTime()); + it('Deselect using API. Should deselect all in "multi" mode.', () => { + calendar.selection = 'multi'; + fixture.detectChanges(); + + const year = calendar.viewDate.getFullYear(); + const month = calendar.viewDate.getMonth(); + const dates = []; + const datesCount = 10; + for (let i = 0; i < datesCount; i++) { + dates.push(new Date(year, month, i + 1)); + } + + calendar.selectDate(dates); + fixture.detectChanges(); + + calendar.deselectDate(); + fixture.detectChanges(); + + expect(calendar.value).toEqual([]); }); - disabledDates.forEach(d => { - expect(d.isDisabled).toBe(true); - expect(d.isDisabledCSS).toBe(true); + it('Deselect using API. Should deselect all in "range" mode.', () => { + calendar.selection = 'range'; + fixture.detectChanges(); + + const startDate = calendar.viewDate; + const endDate = new Date(calendar.viewDate); + endDate.setDate(endDate.getDate() + 7); + + calendar.selectDate(startDate); + fixture.detectChanges(); + + calendar.selectDate(endDate); + fixture.detectChanges(); + + calendar.deselectDate(); + fixture.detectChanges(); + + expect(calendar.value).toEqual([]); }); }); - it('Should not select date from model, if it is part of disabled dates', () => { - expect(calendar.value).toBeFalsy(); - }); + describe('Advanced KB Navigation - ', () => { + let fixture, calendar, dom; - it('Should not select date from model in range selection, if model passes null', () => { - calendar.selection = 'range'; - fixture.componentInstance.model = null; - fixture.detectChanges(); + beforeEach(async(() => { + fixture = TestBed.createComponent(IgxCalendarSampleComponent); + fixture.detectChanges(); + calendar = fixture.componentInstance.calendar; + dom = fixture.debugElement; + })); - expect((calendar.value as Date[]).length).toEqual(0); - }); - }); + it('Should navigate to the previous/next month via KB.', fakeAsync(() => { + const prev = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0]; + prev.nativeElement.focus(); - describe('Select and deselect dates - ', () => { - let fixture, calendar, ci; - beforeEach( - async(() => { - fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - ci = fixture.componentInstance; - calendar = ci.calendar; - }) - ); + expect(prev.nativeElement).toBe(document.activeElement); - it('Deselect using API. Should deselect in "single" selection mode.', () => { - const date = calendar.viewDate; - calendar.selectDate(date); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(prev.nativeElement, 'Enter'); + tick(100); + fixture.detectChanges(); - let selectedDate = calendar.value; - expect(selectedDate).toEqual(date); + expect(calendar.viewDate.getMonth()).toEqual(4); - calendar.deselectDate(date); - fixture.detectChanges(); + const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; + next.nativeElement.focus(); + expect(next.nativeElement).toBe(document.activeElement); - selectedDate = calendar.value; - expect(selectedDate).toBe(null); + UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); + tick(100); + fixture.detectChanges(); - // Deselect with date different than selected date - calendar.selectDate(date); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); + tick(100); + fixture.detectChanges(); - selectedDate = calendar.value; - expect(selectedDate).toEqual(date); + expect(calendar.viewDate.getMonth()).toEqual(6); + })); - const dateToDeselect = new Date(date); - dateToDeselect.setDate(dateToDeselect.getDate() + 5); + it('Should open years view, navigate through and select an year via KB.', () => { + const year = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; + year.nativeElement.focus(); - calendar.deselectDate(dateToDeselect); - fixture.detectChanges(); + expect(year.nativeElement).toBe(document.activeElement); - selectedDate = calendar.value; - expect(selectedDate).toEqual(date); - }); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); + fixture.detectChanges(); - it('Deselect using API. Should deselect in "multi" selection mode.', () => { - calendar.selection = 'multi'; - fixture.detectChanges(); - - const year = calendar.viewDate.getFullYear(); - const month = calendar.viewDate.getMonth(); - const dates = []; - const datesCount = 10; - for (let i = 0; i < datesCount; i++) { - dates.push(new Date(year, month, i + 1)); - } - - fixture.detectChanges(); - calendar.selectDate(dates); - - fixture.detectChanges(); - const evenDates = dates.filter(d => d.getDate() % 2 === 0); - calendar.deselectDate(evenDates); - - fixture.detectChanges(); - const oddDates = dates.filter(d => d.getDate() % 2 !== 0); - let selectedDates: Date[] = calendar.value as Date[]; - expect(selectedDates.length).toBe(5); - for (const selectedDate of selectedDates) { - const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); - expect(fdate).toBeTruthy(); - } - - // Deselect with array not included in the selected dates - calendar.deselectDate(evenDates); - fixture.detectChanges(); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(5); - for (const selectedDate of selectedDates) { - const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); - expect(fdate).toBeTruthy(); - } - - // Deselect one date included in the selected dates - calendar.deselectDate([oddDates[0]]); - fixture.detectChanges(); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(4); - for (const selectedDate of selectedDates) { - const fdate = oddDates.some((date: Date) => date.getTime() === selectedDate.getTime()); - expect(fdate).toBeTruthy(); - } - - // Deselect with array with all dates included in the selected dates - calendar.deselectDate(oddDates); - fixture.detectChanges(); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - }); + const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); + let currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); - it('Deselect using API. Should deselect in "range" selection mode when period is not included in the selected dates', () => { - ci.model = []; - calendar.selection = 'range'; - fixture.detectChanges(); - - const startDate = calendar.viewDate; - const endDate = new Date(calendar.viewDate); - endDate.setDate(endDate.getDate() + 5); - const startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() - 7); - const endDateDeselect = new Date(endDate); - endDateDeselect.setDate(startDate.getDate() - 3); - - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); - - let selectedDates: Date[] = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - expect(selectedDates[0]).toEqual(startDate); - expect(selectedDates[5]).toEqual(endDate); - - // Deselect with range which is not included in the selected dates - calendar.deselectDate([startDateDeselect, endDateDeselect]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - expect(selectedDates[0]).toEqual(startDate); - expect(selectedDates[5]).toEqual(endDate); - }); + expect(years.length).toEqual(6); + expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); - it('Deselect using API. Should deselect in "range" selection mode when period is not included.', () => { - ci.model = []; - calendar.selection = 'range'; - fixture.detectChanges(); - - const startDate = calendar.viewDate; - const endDate = new Date(calendar.viewDate); - endDate.setDate(endDate.getDate() + 5); - - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); - - let selectedDates: Date[] = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - expect(selectedDates[0]).toEqual(startDate); - expect(selectedDates[5]).toEqual(endDate); - - // Deselect with range is includes the selection - let startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() - 7); - let endDateDeselect = new Date(endDate); - endDateDeselect.setDate(endDate.getDate() + 5); - - calendar.deselectDate([startDateDeselect, endDateDeselect]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - - // Deselect with range which includes the beginning of the selection - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - - startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() - 7); - endDateDeselect = new Date(endDate); - endDateDeselect.setDate(endDate.getDate() - 2); - calendar.deselectDate([startDateDeselect, endDateDeselect]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - - // Deselect with range which includes the end of the selection - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - - startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() + 2); - endDateDeselect = new Date(endDate); - endDateDeselect.setDate(endDate.getDate() + 5); - calendar.deselectDate([startDateDeselect, endDateDeselect]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - - // Deselect with range which is inside the selection - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); - - startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() + 1); - endDateDeselect = new Date(endDate); - endDateDeselect.setDate(endDate.getDate() - 1); - calendar.deselectDate([startDateDeselect, endDateDeselect]); - fixture.detectChanges(); - - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - }); + UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowDown'); + fixture.detectChanges(); - it('Deselect using API. Should deselect in "range" with array of dates.', () => { - ci.model = []; - calendar.selection = 'range'; - fixture.detectChanges(); + currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); + expect(currentYear.nativeElement.textContent.trim()).toMatch('2018'); - const startDate = calendar.viewDate; - const endDate = new Date(calendar.viewDate); - endDate.setDate(endDate.getDate() + 5); - const endDateDeselect = new Date(endDate); - endDateDeselect.setDate(endDate.getDate() - 1); - const midDateDeselect = new Date(endDate); + UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); + UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); + fixture.detectChanges(); - // Deselect with range with only one date - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); + currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); + expect(currentYear.nativeElement.textContent.trim()).toMatch('2016'); - let selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); + UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'Enter'); + fixture.detectChanges(); - let startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() - 5); - calendar.deselectDate([startDateDeselect]); - fixture.detectChanges(); + expect(calendar.viewDate.getFullYear()).toEqual(2016); + }); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); + it('Should open months view, navigate through and select a month via KB.', () => { + const month = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0]; + month.nativeElement.focus(); - startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() + 2); - calendar.deselectDate([startDateDeselect]); - fixture.detectChanges(); + expect(month.nativeElement).toBe(document.activeElement); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); + fixture.detectChanges(); - // Deselect with array of dates - calendar.selectDate([startDate, endDate]); - fixture.detectChanges(); + const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); + const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(6); + expect(months.length).toEqual(11); + expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); - startDateDeselect = new Date(startDate); - startDateDeselect.setDate(startDate.getDate() - 10); + UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'Home'); + fixture.detectChanges(); - midDateDeselect.setDate(endDate.getDate() + 3); - calendar.deselectDate([midDateDeselect, endDateDeselect, startDateDeselect]); - fixture.detectChanges(); + expect(document.activeElement.textContent.trim()).toMatch('Jan'); - selectedDates = calendar.value as Date[]; - expect(selectedDates.length).toBe(0); - }); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'End'); + fixture.detectChanges(); - it('Deselect using API. Should deselect all in "single" mode.', () => { - const date = calendar.viewDate; - calendar.selectDate(date); - fixture.detectChanges(); + expect(document.activeElement.textContent.trim()).toMatch('Dec'); - let selectedDate = calendar.value; - expect(selectedDate).toEqual(date); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); - calendar.deselectDate(); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); - selectedDate = calendar.value; - expect(selectedDate).toBe(null); - }); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + fixture.detectChanges(); - it('Deselect using API. Should deselect all in "multi" mode.', () => { - calendar.selection = 'multi'; - fixture.detectChanges(); + expect(document.activeElement.textContent.trim()).toMatch('Sep'); - const year = calendar.viewDate.getFullYear(); - const month = calendar.viewDate.getMonth(); - const dates = []; - const datesCount = 10; - for (let i = 0; i < datesCount; i++) { - dates.push(new Date(year, month, i + 1)); - } + UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); + fixture.detectChanges(); - calendar.selectDate(dates); - fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(8); + }); - calendar.deselectDate(); - fixture.detectChanges(); + it('Should navigate to the first enabled date from the previous month when using "arrow up" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [ + new Date(2017, 4, 25), + new Date(2017, 4, 11) + ]; - expect(calendar.value).toEqual([]); - }); + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - it('Deselect using API. Should deselect all in "range" mode.', () => { - calendar.selection = 'range'; - fixture.detectChanges(); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); - const startDate = calendar.viewDate; - const endDate = new Date(calendar.viewDate); - endDate.setDate(endDate.getDate() + 7); + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - calendar.selectDate(startDate); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); + flush(); - calendar.selectDate(endDate); - fixture.detectChanges(); + let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 18).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - calendar.deselectDate(); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); + fixture.detectChanges(); + flush(); - expect(calendar.value).toEqual([]); - }); - }); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 27).getTime()); + expect(date.nativeElement).toBe(document.activeElement); + })); - describe('Advanced KB Navigation - ', () => { - let fixture, calendar, dom; + it('Should navigate to the first enabled date from the previous month when using "arrow left" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [ + new Date(2017, 4, 27), + new Date(2017, 4, 25) + ]; - beforeEach(async(() => { - fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - calendar = fixture.componentInstance.calendar; - dom = fixture.debugElement; - })); + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - it('Should navigate to the previous/next month via KB.', fakeAsync(() => { - const prev = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0]; - prev.nativeElement.focus(); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); + flush(); - expect(prev.nativeElement).toBe(document.activeElement); + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(prev.nativeElement, 'Enter'); - tick(100); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + flush(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + flush(); - expect(calendar.viewDate.getMonth()).toEqual(4); + let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 26).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; - next.nativeElement.focus(); - expect(next.nativeElement).toBe(document.activeElement); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + flush(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + flush(); - UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); - tick(100); - fixture.detectChanges(); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 29).getTime()); + expect(date.nativeElement).toBe(document.activeElement); + })); - UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Enter'); - tick(100); - fixture.detectChanges(); + it('Should navigate to the first enabled date from the next month when using "arrow down" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [ + new Date(2017, 6, 14), + new Date(2017, 6, 28) + ]; - expect(calendar.viewDate.getMonth()).toEqual(6); - })); + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - it('Should open years view, navigate through and select an year via KB.', () => { - const year = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; - year.nativeElement.focus(); + calendar.disabledDates = dateRangeDescriptors; + fixture.detectChanges(); - expect(year.nativeElement).toBe(document.activeElement); + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + flush(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + flush(); - const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); - let currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); + let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 21).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - expect(years.length).toEqual(6); - expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + flush(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + flush(); - UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowDown'); - fixture.detectChanges(); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 11).getTime()); + expect(date.nativeElement).toBe(document.activeElement); + })); - currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); - expect(currentYear.nativeElement.textContent.trim()).toMatch('2018'); + it('Should navigate to the first enabled date from the next month when using "arrow right" key.', fakeAsync(() => { + const dateRangeDescriptors: DateRangeDescriptor[] = []; + const specificDates = [ + new Date(2017, 6, 9), + new Date(2017, 6, 10) + ]; - UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); - UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp'); - fixture.detectChanges(); + dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); - expect(currentYear.nativeElement.textContent.trim()).toMatch('2016'); + calendar.disabledDates = dateRangeDescriptors; - UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'Enter'); - fixture.detectChanges(); + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - expect(calendar.viewDate.getFullYear()).toEqual(2016); - }); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + flush(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + fixture.detectChanges(); + flush(); - it('Should open months view, navigate through and select a month via KB.', () => { - const month = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0]; - month.nativeElement.focus(); + let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 11).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - expect(month.nativeElement).toBe(document.activeElement); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 5).getTime()); + date.nativeElement.focus(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); + fixture.detectChanges(); + flush(); - const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); - const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 6).getTime()); + expect(date.nativeElement).toBe(document.activeElement); + })); - expect(months.length).toEqual(11); - expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); + it('Should preserve the active date on (shift) pageup and pagedown.', fakeAsync(() => { + const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'Home'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - expect(document.activeElement.textContent.trim()).toMatch('Jan'); + let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'End'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageUp'); + fixture.detectChanges(); + flush(); - expect(document.activeElement.textContent.trim()).toMatch('Dec'); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 1).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); + UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageDown'); + fixture.detectChanges(); + flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - fixture.detectChanges(); + UIInteractions.triggerKeyDownEvtUponElem('PageUp', document.activeElement, true, false, true); + fixture.detectChanges(); + flush(); - expect(document.activeElement.textContent.trim()).toMatch('Sep'); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2016, 5, 1).getTime()); + expect(date.nativeElement).toBe(document.activeElement); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter'); - fixture.detectChanges(); + UIInteractions.triggerKeyDownEvtUponElem('PageDown', document.activeElement, true, false, true); + fixture.detectChanges(); + flush(); - expect(calendar.viewDate.getMonth()).toEqual(8); + date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); + expect(date.nativeElement).toBe(document.activeElement); + })); }); - it('Should navigate to the first enabled date from the previous month when using "arrow up" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [ - new Date(2017, 4, 25), - new Date(2017, 4, 11) - ]; - - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); - flush(); - - let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 18).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp'); - fixture.detectChanges(); - flush(); - - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 27).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to the first enabled date from the previous month when using "arrow left" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [ - new Date(2017, 4, 27), - new Date(2017, 4, 25) - ]; - - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - flush(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); - flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); - flush(); - - let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 26).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); - flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); - fixture.detectChanges(); - flush(); - - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 29).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to the first enabled date from the next month when using "arrow down" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [ - new Date(2017, 6, 14), - new Date(2017, 6, 28) - ]; - - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - - calendar.disabledDates = dateRangeDescriptors; - fixture.detectChanges(); - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - flush(); - - let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 21).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - flush(); - - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 11).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should navigate to the first enabled date from the next month when using "arrow right" key.', fakeAsync(() => { - const dateRangeDescriptors: DateRangeDescriptor[] = []; - const specificDates = [ - new Date(2017, 6, 9), - new Date(2017, 6, 10) - ]; - - dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates }); - - calendar.disabledDates = dateRangeDescriptors; - - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); - fixture.detectChanges(); - flush(); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - fixture.detectChanges(); - flush(); - - let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 11).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 5).getTime()); - date.nativeElement.focus(); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); - fixture.detectChanges(); - flush(); - - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 6).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - })); - - it('Should preserve the active date on (shift) pageup and pagedown.', fakeAsync(() => { - const calendarNativeElement = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)).nativeElement; - - UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home'); - - let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - - UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageUp'); - fixture.detectChanges(); - flush(); + describe('Continuous month increment/decrement - ', () => { + let fixture, dom, calendar, prevMonthBtn, nextMonthBtn; - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 1).getTime()); - expect(date.nativeElement).toBe(document.activeElement); + beforeEach(async(() => { + fixture = TestBed.createComponent(IgxCalendarSampleComponent); + fixture.detectChanges(); + dom = fixture.debugElement; + calendar = fixture.componentInstance.calendar; - UIInteractions.simulateKeyDownEvent(document.activeElement, 'PageDown'); - fixture.detectChanges(); - flush(); + prevMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0].nativeElement; + nextMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0].nativeElement; - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); - expect(date.nativeElement).toBe(document.activeElement); + })); - UIInteractions.triggerKeyDownEvtUponElem('PageUp', document.activeElement, true, false, true); - fixture.detectChanges(); - flush(); + it('Should increment/decrement months continuously on mousedown.', fakeAsync(() => { + expect(calendar.viewDate.getMonth()).toEqual(5); + // Have no idea how this test worked before, + // changing expectation based on my udnerstanding of that the test does + UIInteractions.simulateMouseEvent('mousedown', prevMonthBtn, 0, 0); + tick(900); + UIInteractions.simulateMouseEvent('mouseup', prevMonthBtn, 0, 0); + fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(4); - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2016, 5, 1).getTime()); - expect(date.nativeElement).toBe(document.activeElement); + UIInteractions.simulateMouseEvent('mousedown', nextMonthBtn, 0, 0); + tick(900); + UIInteractions.simulateMouseEvent('mouseup', nextMonthBtn, 0, 0); + fixture.detectChanges(); + flush(); + expect(calendar.viewDate.getMonth()).toEqual(5); + })); - UIInteractions.triggerKeyDownEvtUponElem('PageDown', document.activeElement, true, false, true); - fixture.detectChanges(); - flush(); + it('Should increment/decrement months continuously on enter keydown.', fakeAsync(() => { + expect(calendar.viewDate.getMonth()).toEqual(5); - date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 5, 1).getTime()); - expect(date.nativeElement).toBe(document.activeElement); - })); - }); + prevMonthBtn.focus(); + UIInteractions.simulateKeyDownEvent(prevMonthBtn, 'Enter'); + tick(800); + fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(4); - describe('Continuous month increment/decrement - ', () => { - let fixture, dom, calendar, prevMonthBtn, nextMonthBtn; - - beforeEach(async(() => { - fixture = TestBed.createComponent(IgxCalendarSampleComponent); - fixture.detectChanges(); - dom = fixture.debugElement; - calendar = fixture.componentInstance.calendar; - - prevMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0].nativeElement; - nextMonthBtn = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0].nativeElement; - - })); - - it('Should increment/decrement months continuously on mousedown.', fakeAsync(() => { - expect(calendar.viewDate.getMonth()).toEqual(5); - // Have no idea how this test worked before, - // changing expectation based on my udnerstanding of that the test does - UIInteractions.simulateMouseEvent('mousedown', prevMonthBtn, 0, 0); - tick(900); - UIInteractions.simulateMouseEvent('mouseup', prevMonthBtn, 0, 0); - fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(4); - - UIInteractions.simulateMouseEvent('mousedown', nextMonthBtn, 0, 0); - tick(900); - UIInteractions.simulateMouseEvent('mouseup', nextMonthBtn, 0, 0); - fixture.detectChanges(); - flush(); - expect(calendar.viewDate.getMonth()).toEqual(5); - })); - - it('Should increment/decrement months continuously on enter keydown.', fakeAsync(() => { - expect(calendar.viewDate.getMonth()).toEqual(5); - - prevMonthBtn.focus(); - UIInteractions.simulateKeyDownEvent(prevMonthBtn, 'Enter'); - tick(800); - fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(4); - - nextMonthBtn.focus(); - UIInteractions.simulateKeyDownEvent(nextMonthBtn, 'Enter'); - tick(800); - fixture.detectChanges(); - expect(calendar.viewDate.getMonth()).toEqual(5); - })); + nextMonthBtn.focus(); + UIInteractions.simulateKeyDownEvent(nextMonthBtn, 'Enter'); + tick(800); + fixture.detectChanges(); + expect(calendar.viewDate.getMonth()).toEqual(5); + })); + }); }); }); From fbb499ab30a752c9a9dc4940d83fe4e65b91266e Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Wed, 22 Jan 2020 18:14:28 +0200 Subject: [PATCH 3/3] test(calendar): fix build #6453 --- .../src/lib/calendar/calendar.component.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index b8951d9f5c6..b07ad564800 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1158,7 +1158,8 @@ describe('IgxCalendar - ', () => { })); it('Should be able to set disabled and active dates as @Input', () => { - expect(calendar.specialDates).toEqual([{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); + expect(calendar.specialDates).toEqual( + [{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 1), new Date(2017, 5, 6)]}]); expect(calendar.disabledDates).toEqual( [{type: DateRangeType.Between, dateRange: [new Date(2017, 5, 23), new Date(2017, 5, 29)]}]); let specialDates = calendar.daysView.dates.toArray().filter(d => {