UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,078 lines (869 loc) 121 kB
import { Component, LOCALE_ID, ViewChild } from '@angular/core'; import { TestBed, tick, fakeAsync, flush, waitForAsync } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Calendar, IgxCalendarComponent, IgxCalendarView, isLeap, IViewDateChangeEventArgs, monthRange, weekDay, WEEKDAYS } from './public_api'; 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 '../test-utils/calendar-helper-utils'; describe('IgxCalendar - ', () => { 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]); const weeks = calendar.monthdatescalendar(2017, 5); const firstWeek = weeks[0]; const lastWeek = weeks[weeks.length - 1]; expect(firstWeek[0].date.toDateString()).toMatch( new Date(2017, 4, 28).toDateString() ); expect(lastWeek[lastWeek.length - 1].date.toDateString()).toMatch( new Date(2017, 6, 1).toDateString() ); // 2017 June with first day set to Sunday let dates = calendar.monthdates(2017, 5); expect(dates[0].date.toDateString()).toMatch( new Date(2017, 4, 28).toDateString() ); expect(dates[dates.length - 1].date.toDateString()).toMatch( new Date(2017, 6, 1).toDateString() ); expect(dates.length).toEqual(35); // 2017 June with first day set to Sunday and extra week dates = calendar.monthdates(2017, 5, true); expect(dates.length).toEqual(42); expect(dates[0].date.toDateString()).toMatch( new Date(2017, 4, 28).toDateString() ); expect(dates[dates.length - 1].date.toDateString()).toMatch( new Date(2017, 6, 8).toDateString() ); calendar.firstWeekDay = WEEKDAYS.FRIDAY; expect(calendar.firstWeekDay).toEqual(WEEKDAYS.FRIDAY); expect(calendar.weekdays()).toEqual([5, 6, 0, 1, 2, 3, 4]); // 2017 June with first day set to Friday dates = calendar.monthdates(2017, 5); expect(dates[0].date.toDateString()).toMatch( new Date(2017, 4, 26).toDateString() ); expect(dates[dates.length - 1].date.toDateString()).toMatch( new Date(2017, 6, 6).toDateString() ); expect(dates.length).toEqual(42); // Leap year tests - 2016 calendar.firstWeekDay = WEEKDAYS.SUNDAY; dates = calendar.monthdates(2016, 1); expect(dates[0].date.toDateString()).toMatch( new Date(2016, 0, 31).toDateString() ); expect(dates[dates.length - 1].date.toDateString()).toMatch( new Date(2016, 2, 5).toDateString() ); expect(dates.length).toEqual(35); }); it('Should receive correct values from utility functions', () => { const calendar = new Calendar(); // Leap year expect(isLeap(2017)).toBe(false); expect(isLeap(2016)).toBe(true); // monthRange expect(() => monthRange(2017, -1)).toThrow(); expect(() => monthRange(2017, 12)).toThrow(); expect(monthRange(2017, 5)).toEqual([weekDay(2017, 5, 1), 30]); expect(monthRange(2016, 1)).toEqual([weekDay(2016, 1, 1), 29]); // Leap year // Calendar timedelta const startDate = new Date(2017, 0, 1, 0, 0, 0); // Year timedelta let newDate = calendar.timedelta(startDate, 'year', 1); expect(newDate.getFullYear()).toEqual(2018); newDate = calendar.timedelta(startDate, 'year', -1); expect(newDate.getFullYear()).toEqual(2016); // Quarter timedelta newDate = calendar.timedelta(startDate, 'quarter', 1); expect(newDate.getMonth()).toEqual(3); newDate = calendar.timedelta(startDate, 'quarter', -1); expect(newDate.getFullYear()).toEqual(2016); expect(newDate.getMonth()).toEqual(9); // Month timedelta newDate = calendar.timedelta(startDate, 'month', 1); expect(newDate.getMonth()).toEqual(1); newDate = calendar.timedelta(startDate, 'month', -1); expect(newDate.getFullYear()).toEqual(2016); expect(newDate.getMonth()).toEqual(11); // Week timedelta newDate = calendar.timedelta(startDate, 'week', 1); expect(newDate.getDate()).toEqual(8); newDate = calendar.timedelta(startDate, 'week', -1); expect(newDate.getFullYear()).toEqual(2016); expect(newDate.getDate()).toEqual(25); // Day timedelta newDate = calendar.timedelta(startDate, 'day', 3); expect(newDate.getDate()).toEqual(4); expect(calendar.timedelta(startDate, 'day', 7).toDateString()).toEqual( calendar.timedelta(startDate, 'week', 1).toDateString() ); newDate = calendar.timedelta(startDate, 'day', -3); expect(newDate.getFullYear()).toEqual(2016); expect(newDate.getDate()).toEqual(29); // Hour timedelta newDate = calendar.timedelta(startDate, 'hour', 1); expect(newDate.getHours()).toEqual(1); newDate = calendar.timedelta(startDate, 'hour', 24); expect(newDate.getDate()).toEqual(2); expect(newDate.getHours()).toEqual(0); newDate = calendar.timedelta(startDate, 'hour', -1); expect(newDate.getHours()).toEqual(23); expect(newDate.getDate()).toEqual(31); expect(newDate.getFullYear()).toEqual(2016); // Minute timedelta newDate = calendar.timedelta(startDate, 'minute', 60); expect(newDate.getHours()).toEqual(1); newDate = calendar.timedelta(startDate, 'minute', 24 * 60); expect(newDate.getDate()).toEqual(2); expect(newDate.getHours()).toEqual(0); newDate = calendar.timedelta(startDate, 'minute', -60); expect(newDate.getHours()).toEqual(23); expect(newDate.getDate()).toEqual(31); expect(newDate.getFullYear()).toEqual(2016); // Seconds timedelta newDate = calendar.timedelta(startDate, 'second', 3600); expect(newDate.getHours()).toEqual(1); newDate = calendar.timedelta(startDate, 'second', 24 * 3600); expect(newDate.getDate()).toEqual(2); expect(newDate.getHours()).toEqual(0); newDate = calendar.timedelta(startDate, 'second', -3600); expect(newDate.getHours()).toEqual(23); expect(newDate.getDate()).toEqual(31); expect(newDate.getFullYear()).toEqual(2016); // Throws on invalid interval expect(() => calendar.timedelta(startDate, 'nope', 1)).toThrow(); }); describe('Basic', () => { configureTestSuite(); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, IgxCalendarSampleComponent, IgxCalendarRangeComponent, IgxCalendarDisabledSpecialDatesComponent, IgxCalendarValueComponent ] }).compileComponents(); })); describe('Rendered Component - ', () => { let fixture; let calendar; let dom; beforeEach( waitForAsync(() => { fixture = TestBed.createComponent(IgxCalendarSampleComponent); fixture.detectChanges(); calendar = fixture.componentInstance.calendar; dom = fixture.debugElement; }) ); 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(HelperTestFunctions.CALENDAR)).nativeElement; expect(calendar.id).toContain('igx-calendar-'); expect(domCalendar.id).toContain('igx-calendar-'); calendar.id = 'customCalendar'; fixture.detectChanges(); expect(calendar.id).toBe('customCalendar'); expect(domCalendar.id).toBe('customCalendar'); }); it('Should properly set @Input properties and setters', () => { expect(calendar.weekStart).toEqual(WEEKDAYS.SUNDAY); expect(calendar.selection).toEqual('single'); const today = new Date(Date.now()); calendar.viewDate = today; fixture.detectChanges(); calendar.weekStart = WEEKDAYS.MONDAY; expect(calendar.weekStart).toEqual(1); 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() ); expect(() => (calendar.selection = 'non-existant')).toThrow(); }); 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('Sat'); expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 1'); 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('Sat'); expect(headerDate.nativeElement.textContent.trim()).toMatch('September 1'); 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('Sat'); expect(headerDate.nativeElement.textContent.trim()).toMatch('September 1'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('8'); }); it('Should show right month when value is set', () => { fixture = TestBed.createComponent(IgxCalendarValueComponent); fixture.detectChanges(); calendar = fixture.componentInstance.calendar; expect(calendar.weekStart).toEqual(WEEKDAYS.SUNDAY); expect(calendar.selection).toEqual('single'); expect(calendar.viewDate.getMonth()).toEqual(calendar.value.getMonth()); const date = new Date(2020, 8, 28); calendar.viewDate = date; fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(date.getMonth()); calendar.value = new Date(2020, 9, 15); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(date.getMonth()); }); 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('Sat'); expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 1'); 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('sam.,'); expect(headerDate.nativeElement.textContent.trim()).toMatch('1 sept.'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('sept.'); expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Lun.'); }); it('Should default to today date when invalid date is passed', () => { fixture = TestBed.createComponent(IgxCalendarValueComponent); fixture.detectChanges(); calendar = fixture.componentInstance.calendar; const today = new Date().setHours(0, 0, 0, 0); calendar.value = new Date(NaN); fixture.detectChanges(); expect(calendar.value.getTime()).toEqual(today); calendar.value = undefined; fixture.detectChanges(); expect(calendar.value.getTime()).toEqual(today); calendar.value = new Date('1989-5s-dd'); fixture.detectChanges(); expect(calendar.value.getTime()).toEqual(today); }); 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); // 6 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 render calendar DOM with week numbers enabled', () => { const today = new Date(Date.now()); calendar.viewDate = today; calendar.showWeekNumbers = true; fixture.detectChanges(); const calendarRows = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_ROW_CSSCLASS)); expect(calendarRows.length).toEqual(7); // 6 calendar rows * 8 elements in each expect( dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > igx-day-item`)).length + dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > ${HelperTestFunctions.CALENDAR_WEEK_NUMBER_CLASS}`)).length ).toEqual(48); expect( dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > span`)).length + dom.queryAll( By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS} > ${HelperTestFunctions.CALENDAR_WEEK_NUMBER_LABEL_CLASS}`) ).length ).toEqual(8); }); it('Week numbers should appear as first column', () => { const firstWeekOfTheYear = new Date(2020, 0, 5); calendar.viewDate = firstWeekOfTheYear; calendar.showWeekNumbers = true; fixture.detectChanges(); const calendarRows = dom.queryAll(By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}`)); const maxWeeks = 52; calendarRows.forEach((row, idx) => { const firstRowItem = row.nativeElement.children[0]; if (idx === 0) { expect(firstRowItem.firstChild.innerText).toEqual('Wk'); } else { expect(firstRowItem.firstChild.innerText).toEqual((idx === 1 ? maxWeeks : idx - 1).toString()); } }); }); it('Calendar DOM structure - year view | month view', () => { dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0].nativeElement.click(); 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(months.length).toEqual(12); expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun'); months[0].nativeElement.click(); fixture.detectChanges(); expect(calendar.viewDate.getMonth()).toEqual(0); dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1].nativeElement.click(); fixture.detectChanges(); 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(7); expect(currentYear.nativeElement.textContent.trim()).toMatch('2017'); years[0].triggerEventHandler('click', { target: years[0].nativeElement }); fixture.detectChanges(); expect(calendar.viewDate.getFullYear()).toEqual(2014); }); it('Calendar selection - single 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 nextDay = new Date(2017, 5, 14); expect((calendar.value as Date).toDateString()).toMatch( new Date(2017, 5, 13).toDateString() ); spyOn(calendar.selected, 'emit'); // Select 14th weekDays[3].nativeElement.click(); fixture.detectChanges(); expect(calendar.selected.emit).toHaveBeenCalled(); 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 - outside of current month - 1', () => { const parent = dom.query( By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}:last-child`) ); const parentDates = parent.queryAll(By.css(HelperTestFunctions.INACTIVE_DAYS_CSSCLASS)); const target = parentDates[parentDates.length - 1]; 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); }); 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); }); it('Calendar selection - single 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)); const nextDay = new Date(2017, 5, 14); expect((calendar.value as Date).toDateString()).toMatch( new Date(2017, 5, 13).toDateString() ); calendar.selectDate(new Date(2017, 5, 14)); fixture.detectChanges(); 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 - 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)); calendar.selection = 'multi'; fixture.detectChanges(); 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 (const days of weekDays) { days.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(); 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[])[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 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)); calendar.selection = 'range'; fixture.detectChanges(); const lastDay = new Date(2017, 5, 17); const firstDay = new Date(2017, 5, 11); // Toggle range selection... weekDays[0].nativeElement.click(); 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()); 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); }); }); it('Calendar selection - range 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 = '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( 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( 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', fakeAsync(() => { const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); UIInteractions.triggerKeyDownEvtUponElem('PageUp', component.nativeElement); fixture.detectChanges(); tick(); expect(calendar.viewDate.getMonth()).toEqual(4); calendar.viewDate = new Date(2017, 5, 13); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('PageDown', component.nativeElement); fixture.detectChanges(); tick(); expect(calendar.viewDate.getMonth()).toEqual(6); UIInteractions.triggerKeyDownEvtUponElem('PageUp', component.nativeElement, true, false, true); fixture.detectChanges(); tick(); expect(calendar.viewDate.getFullYear()).toEqual(2016); calendar.viewDate = new Date(2017, 5, 13); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('PageDown', component.nativeElement, true, false, true); fixture.detectChanges(); tick(); expect(calendar.viewDate.getFullYear()).toEqual(2018); })); it('Calendar keyboard navigation - Home/End/Enter', () => { const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); const firstDay = days[0]; const lastDay = days[days.length - 1]; UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement); fixture.detectChanges(); expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); expect(document.activeElement.textContent.trim()).toMatch('1'); UIInteractions.triggerKeyDownEvtUponElem('End', component.nativeElement); fixture.detectChanges(); expect(document.activeElement.textContent).toMatch(lastDay.nativeElement.textContent); expect(document.activeElement.textContent.trim()).toMatch('30'); UIInteractions.triggerKeyDownEvtUponElem('Enter', firstDay.nativeElement); fixture.detectChanges(); expect((calendar.value as Date).toDateString()).toMatch(new Date(2017, 5, 1).toDateString()); }); it('Calendar keyboard navigation - Arrow keys', () => { const component = dom.query(By.css(HelperTestFunctions.CALENDAR_CSSCLASS)); const days = calendar.daysView.dates.filter((day) => day.isCurrentMonth); const firstDay = days[0]; UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement); fixture.detectChanges(); expect(document.activeElement.textContent).toMatch(firstDay.nativeElement.textContent); expect(document.activeElement.textContent.trim()).toMatch('1'); UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', document.activeElement); fixture.detectChanges(); expect(document.activeElement.textContent.trim()).toMatch('8'); UIInteractions.triggerKeyDownEvtUponElem('ArrowLeft', document.activeElement); fixture.detectChanges(); expect(document.activeElement.textContent.trim()).toMatch('7'); UIInteractions.triggerKeyDownEvtUponElem('ArrowRight', document.activeElement); fixture.detectChanges(); expect(document.activeElement.textContent.trim()).toMatch('8'); UIInteractions.triggerKeyDownEvtUponElem('ArrowUp', document.activeElement); 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]; UIInteractions.triggerKeyDownEvtUponElem('Home', component.nativeElement, true); let date = calendar.daysView.dates.find((d) => d.date.date.toString() === value.date.toString()).nativeElement; UIInteractions.triggerKeyDownEvtUponElem('Enter', date); 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.triggerKeyDownEvtUponElem('Enter', date); 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.triggerKeyDownEvtUponElem('Home', calendarNativeElement); 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.triggerKeyDownEvtUponElem('End', calendarNativeElement); 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.triggerKeyDownEvtUponElem('End', calendarNativeElement); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('ArrowUp', document.activeElement); 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.triggerKeyDownEvtUponElem('Home', calendarNativeElement); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', document.activeElement); 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.triggerKeyDownEvtUponElem('End', calendarNativeElement); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('ArrowLeft', document.activeElement); 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.triggerKeyDownEvtUponElem('Home', calendarNativeElement); fixture.detectChanges(); UIInteractions.triggerKeyDownEvtUponElem('ArrowRight', document.activeElement); 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()); }); 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); }); }); }); describe(