@@ -63,6 +63,7 @@ describe('IgxDateRangePicker', () => {
63
63
let mockCalendar : IgxCalendarComponent ;
64
64
let mockDaysView : any ;
65
65
let mockAnimationService : AnimationService ;
66
+ let mockCdr : any ;
66
67
const elementRef = { nativeElement : null } ;
67
68
const platform = { } as any ;
68
69
const mockNgControl = jasmine . createSpyObj ( 'NgControl' ,
@@ -88,6 +89,9 @@ describe('IgxDateRangePicker', () => {
88
89
mockInjector = jasmine . createSpyObj ( 'Injector' , {
89
90
get : mockNgControl
90
91
} ) ;
92
+ mockCdr = jasmine . createSpyObj ( 'ChangeDetectorRef' , {
93
+ detectChanges : ( ) => { }
94
+ } ) ;
91
95
mockAnimationBuilder = {
92
96
build : ( a : AnimationMetadata | AnimationMetadata [ ] ) => ( {
93
97
create : ( e : any , opt ?: AnimationOptions ) => ( {
@@ -244,7 +248,7 @@ describe('IgxDateRangePicker', () => {
244
248
} ) ;
245
249
246
250
it ( 'should disable calendar dates when min and/or max values as dates are provided' , ( ) => {
247
- const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en-US' , platform , mockInjector , null , overlay ) ;
251
+ const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en-US' , platform , mockInjector , mockCdr , overlay ) ;
248
252
dateRange . ngOnInit ( ) ;
249
253
250
254
spyOnProperty ( ( dateRange as any ) , 'calendar' ) . and . returnValue ( mockCalendar ) ;
@@ -260,7 +264,7 @@ describe('IgxDateRangePicker', () => {
260
264
} ) ;
261
265
262
266
it ( 'should disable calendar dates when min and/or max values as strings are provided' , fakeAsync ( ( ) => {
263
- const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en' , platform , mockInjector , null , null , null ) ;
267
+ const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en' , platform , mockInjector , mockCdr , null , null ) ;
264
268
dateRange . ngOnInit ( ) ;
265
269
266
270
spyOnProperty ( ( dateRange as any ) , 'calendar' ) . and . returnValue ( mockCalendar ) ;
@@ -277,7 +281,7 @@ describe('IgxDateRangePicker', () => {
277
281
} ) ) ;
278
282
279
283
it ( 'should validate correctly when disabledDates are set' , ( ) => {
280
- const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en-US' , platform , mockInjector , null , null , null ) ;
284
+ const dateRange = new IgxDateRangePickerComponent ( elementRef , 'en-US' , platform , mockInjector , mockCdr , null , null ) ;
281
285
dateRange . ngOnInit ( ) ;
282
286
283
287
dateRange . registerOnChange ( mockNgControl . registerOnChangeCb ) ;
@@ -1317,6 +1321,60 @@ describe('IgxDateRangePicker', () => {
1317
1321
expect ( dateRange . opening . emit ) . toHaveBeenCalledTimes ( 0 ) ;
1318
1322
expect ( dateRange . opened . emit ) . toHaveBeenCalledTimes ( 0 ) ;
1319
1323
} ) ) ;
1324
+
1325
+ it ( 'should update the calendar selection on typing' , fakeAsync ( ( ) => {
1326
+ const range = { start : new Date ( 2025 , 0 , 16 ) , end : new Date ( 2025 , 0 , 20 ) } ;
1327
+ dateRange . value = range ;
1328
+ fixture . detectChanges ( ) ;
1329
+ dateRange . open ( ) ;
1330
+ fixture . detectChanges ( ) ;
1331
+
1332
+ expect ( ( dateRange [ '_calendar' ] . value as Date [ ] ) . length ) . toBe ( 5 ) ;
1333
+
1334
+ startInput . triggerEventHandler ( 'focus' , { } ) ;
1335
+ fixture . detectChanges ( ) ;
1336
+ UIInteractions . simulateTyping ( '01/18/2025' , startInput ) ;
1337
+
1338
+ tick ( DEBOUNCE_TIME ) ;
1339
+ fixture . detectChanges ( ) ;
1340
+
1341
+ expect ( ( dateRange [ '_calendar' ] . value as Date [ ] ) . length ) . toBe ( 3 ) ;
1342
+
1343
+ startDate = new Date ( 2025 , 0 , 18 ) ;
1344
+ const expectedRange = { start : startDate , end : new Date ( 2025 , 0 , 20 ) } ;
1345
+ expect ( dateRange . value ) . toEqual ( expectedRange ) ;
1346
+ expect ( dateRange . activeDate ) . toEqual ( expectedRange . start ) ;
1347
+
1348
+ const activeDescendantDate = new Date ( startDate . setHours ( 0 , 0 , 0 , 0 ) ) . getTime ( ) . toString ( ) ;
1349
+ expect ( dateRange [ '_calendar' ] . activeDate ) . toEqual ( startDate ) ;
1350
+ expect ( dateRange [ '_calendar' ] . viewDate . getMonth ( ) ) . toEqual ( startDate . getMonth ( ) ) ;
1351
+ expect ( dateRange [ '_calendar' ] . value [ 0 ] ) . toEqual ( startDate ) ;
1352
+ expect ( dateRange [ '_calendar' ] . wrapper . nativeElement . getAttribute ( 'aria-activedescendant' ) ) . toEqual ( activeDescendantDate ) ;
1353
+ } ) ) ;
1354
+
1355
+ it ( 'should update the calendar view and active date on typing a date that is not in the current view' , fakeAsync ( ( ) => {
1356
+ const range = { start : new Date ( 2025 , 0 , 16 ) , end : new Date ( 2025 , 0 , 20 ) } ;
1357
+ dateRange . value = range ;
1358
+ fixture . detectChanges ( ) ;
1359
+ dateRange . open ( ) ;
1360
+ fixture . detectChanges ( ) ;
1361
+
1362
+ expect ( ( dateRange [ '_calendar' ] . value as Date [ ] ) . length ) . toBe ( 5 ) ;
1363
+
1364
+ startInput . triggerEventHandler ( 'focus' , { } ) ;
1365
+ fixture . detectChanges ( ) ;
1366
+ UIInteractions . simulateTyping ( '11/18/2025' , startInput ) ;
1367
+
1368
+ tick ( DEBOUNCE_TIME ) ;
1369
+ fixture . detectChanges ( ) ;
1370
+
1371
+ startDate = new Date ( 2025 , 10 , 18 ) ;
1372
+
1373
+ const activeDescendantDate = new Date ( startDate . setHours ( 0 , 0 , 0 , 0 ) ) . getTime ( ) . toString ( ) ;
1374
+ expect ( dateRange [ '_calendar' ] . activeDate ) . toEqual ( startDate ) ;
1375
+ expect ( dateRange [ '_calendar' ] . viewDate . getMonth ( ) ) . toEqual ( startDate . getMonth ( ) ) ;
1376
+ expect ( dateRange [ '_calendar' ] . wrapper . nativeElement . getAttribute ( 'aria-activedescendant' ) ) . toEqual ( activeDescendantDate ) ;
1377
+ } ) ) ;
1320
1378
} ) ;
1321
1379
1322
1380
it ( 'should focus the last focused input after the calendar closes - dropdown' , fakeAsync ( ( ) => {
@@ -1739,13 +1797,70 @@ describe('IgxDateRangePicker', () => {
1739
1797
fixture . detectChanges ( ) ;
1740
1798
1741
1799
expect ( dateRange [ '_calendar' ] . disabledDates ) . toEqual ( disabledDates ) ;
1800
+ } ) ) ;
1742
1801
1743
- // should not allow to select a date from the disabled dates
1744
- startDate = new Date ( new Date ( ) . getFullYear ( ) , new Date ( ) . getMonth ( ) , 4 ) ;
1745
- endDate = new Date ( new Date ( ) . getFullYear ( ) , new Date ( ) . getMonth ( ) , 6 ) ;
1802
+ it ( 'should initialize activeDate with current date, when not set' , fakeAsync ( ( ) => {
1803
+ fixture = TestBed . createComponent ( DateRangeDefaultComponent ) ;
1804
+ fixture . detectChanges ( ) ;
1805
+ dateRange = fixture . componentInstance . dateRange ;
1806
+ const todayDate = new Date ( ) ;
1807
+ const today = new Date ( todayDate . setHours ( 0 , 0 , 0 , 0 ) ) . getTime ( ) . toString ( ) ;
1808
+
1809
+ expect ( dateRange . activeDate ) . toEqual ( todayDate ) ;
1810
+
1811
+ dateRange . open ( ) ;
1812
+ fixture . detectChanges ( ) ;
1813
+
1814
+ expect ( dateRange [ '_calendar' ] . activeDate ) . toEqual ( todayDate ) ;
1815
+ expect ( dateRange [ '_calendar' ] . value ) . toEqual ( [ ] ) ;
1816
+ const wrapper = fixture . debugElement . query ( By . css ( '.igx-calendar__wrapper' ) ) . nativeElement ;
1817
+ expect ( wrapper . getAttribute ( 'aria-activedescendant' ) ) . toEqual ( today ) ;
1818
+ } ) ) ;
1819
+
1820
+ it ( 'should initialize activeDate = first defined in value (start/end) when it is not set, but value is' , fakeAsync ( ( ) => {
1821
+ fixture = TestBed . createComponent ( DateRangeDefaultComponent ) ;
1822
+ fixture . detectChanges ( ) ;
1823
+ dateRange = fixture . componentInstance . dateRange ;
1824
+ let range = { start : new Date ( 2025 , 0 , 1 ) , end : new Date ( 2025 , 0 , 5 ) } ;
1825
+ dateRange . value = range ;
1826
+ fixture . detectChanges ( ) ;
1827
+
1828
+ expect ( dateRange . activeDate ) . toEqual ( range . start ) ;
1829
+ dateRange . open ( ) ;
1830
+ fixture . detectChanges ( ) ;
1831
+
1832
+ const activeDescendantDate = new Date ( range . start . setHours ( 0 , 0 , 0 , 0 ) ) . getTime ( ) . toString ( ) ;
1833
+ expect ( dateRange [ '_calendar' ] . activeDate ) . toEqual ( range . start ) ;
1834
+ expect ( dateRange [ '_calendar' ] . value [ 0 ] ) . toEqual ( range . start ) ;
1835
+ const wrapper = fixture . debugElement . query ( By . css ( '.igx-calendar__wrapper' ) ) . nativeElement ;
1836
+ expect ( wrapper . getAttribute ( 'aria-activedescendant' ) ) . toEqual ( activeDescendantDate ) ;
1837
+
1838
+ range = { ...range , start : null } ;
1839
+ dateRange . value = range ;
1840
+ fixture . detectChanges ( ) ;
1841
+
1842
+ expect ( dateRange . activeDate ) . toEqual ( range . end ) ;
1843
+ } ) ) ;
1844
+
1845
+ it ( 'should set activeDate correctly' , fakeAsync ( ( ) => {
1846
+ const targetDate = new Date ( 2025 , 11 , 1 ) ;
1847
+ fixture = TestBed . createComponent ( DateRangeDefaultComponent ) ;
1848
+ fixture . detectChanges ( ) ;
1849
+ dateRange = fixture . componentInstance . dateRange ;
1850
+ const range = { start : new Date ( 2025 , 0 , 1 ) , end : new Date ( 2025 , 0 , 5 ) } ;
1851
+ dateRange . value = range ;
1852
+ dateRange . activeDate = targetDate ;
1853
+ fixture . detectChanges ( ) ;
1854
+
1855
+ expect ( dateRange . activeDate ) . toEqual ( targetDate ) ;
1856
+ dateRange . open ( ) ;
1857
+ fixture . detectChanges ( ) ;
1746
1858
1747
- selectDateRangeFromCalendar ( startDate , endDate ) ;
1748
- expect ( dateRange . value ) . toBeNull ( ) ;
1859
+ const activeDescendantDate = new Date ( targetDate . setHours ( 0 , 0 , 0 , 0 ) ) . getTime ( ) . toString ( ) ;
1860
+ expect ( dateRange [ '_calendar' ] . activeDate ) . toEqual ( targetDate ) ;
1861
+ expect ( dateRange [ '_calendar' ] . value [ 0 ] ) . toEqual ( range . start ) ;
1862
+ const wrapper = fixture . debugElement . query ( By . css ( '.igx-calendar__wrapper' ) ) . nativeElement ;
1863
+ expect ( wrapper . getAttribute ( 'aria-activedescendant' ) ) . toEqual ( activeDescendantDate ) ;
1749
1864
} ) ) ;
1750
1865
1751
1866
describe ( 'Templated Calendar Header' , ( ) => {
0 commit comments