Skip to content

Commit 41eb62e

Browse files
test(calendar): adiciona testes de cobertura para variações
Co-Authored-By: arthur.polidorio <arthur.polidorio@totvs.com.br>
1 parent 8ac4448 commit 41eb62e

4 files changed

Lines changed: 689 additions & 0 deletions

File tree

projects/ui/src/lib/components/po-calendar/po-calendar-base.component.spec.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,5 +330,98 @@ describe('PoCalendarBaseComponent:', () => {
330330
expect((component as any).applySizeBasedOnA11y).toHaveBeenCalled();
331331
});
332332
});
333+
334+
describe('p-year-range:', () => {
335+
it('should set yearRange with valid positive value', () => {
336+
component.yearRange = 100;
337+
expect(component.yearRange).toBe(100);
338+
});
339+
340+
it('should default to 150 when value is 0', () => {
341+
component.yearRange = 0;
342+
expect(component.yearRange).toBe(150);
343+
});
344+
345+
it('should default to 150 when value is negative', () => {
346+
component.yearRange = -10;
347+
expect(component.yearRange).toBe(150);
348+
});
349+
350+
it('should default to 150 when value is null', () => {
351+
component.yearRange = null;
352+
expect(component.yearRange).toBe(150);
353+
});
354+
355+
it('should default to 150 when value is undefined', () => {
356+
component.yearRange = undefined;
357+
expect(component.yearRange).toBe(150);
358+
});
359+
});
360+
361+
describe('isMonthYear:', () => {
362+
it('should return true when mode is MonthYear', () => {
363+
component['_mode'] = PoCalendarMode.MonthYear;
364+
expect(component.isMonthYear).toBeTrue();
365+
});
366+
367+
it('should return false when mode is Range', () => {
368+
component['_mode'] = PoCalendarMode.Range;
369+
expect(component.isMonthYear).toBeFalse();
370+
});
371+
372+
it('should return false when mode is undefined', () => {
373+
component['_mode'] = undefined;
374+
expect(component.isMonthYear).toBeFalse();
375+
});
376+
});
377+
378+
describe('isYearOnly:', () => {
379+
it('should return true when mode is Year', () => {
380+
component['_mode'] = PoCalendarMode.Year;
381+
expect(component.isYearOnly).toBeTrue();
382+
});
383+
384+
it('should return false when mode is MonthYear', () => {
385+
component['_mode'] = PoCalendarMode.MonthYear;
386+
expect(component.isYearOnly).toBeFalse();
387+
});
388+
389+
it('should return false when mode is Range', () => {
390+
component['_mode'] = PoCalendarMode.Range;
391+
expect(component.isYearOnly).toBeFalse();
392+
});
393+
});
394+
395+
describe('p-range-presets:', () => {
396+
it('should accept boolean true', () => {
397+
component.rangePresets = true;
398+
expect(component.rangePresets).toBeTrue();
399+
});
400+
401+
it('should accept string "true"', () => {
402+
component.rangePresets = 'true';
403+
expect(component.rangePresets).toBeTrue();
404+
});
405+
406+
it('should accept empty string as true', () => {
407+
component.rangePresets = '';
408+
expect(component.rangePresets).toBeTrue();
409+
});
410+
411+
it('should accept boolean false', () => {
412+
component.rangePresets = false;
413+
expect(component.rangePresets).toBeFalse();
414+
});
415+
416+
it('should accept array of strings', () => {
417+
component.rangePresets = ['today', '7days'];
418+
expect(component.rangePresets).toEqual(['today', '7days']);
419+
});
420+
421+
it('should set to false for invalid values', () => {
422+
component.rangePresets = 'invalid' as any;
423+
expect(component.rangePresets).toBeFalse();
424+
});
425+
});
333426
});
334427
});

projects/ui/src/lib/components/po-calendar/po-calendar-month-year/po-calendar-month-year.component.spec.ts

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ describe('PoCalendarMonthYearComponent:', () => {
5555
component.locale = 'pt';
5656
expect(component['setupMonths']).toHaveBeenCalled();
5757
});
58+
59+
it('locale: getter should return the current locale value', () => {
60+
component.locale = 'en';
61+
expect(component.locale).toBe('en');
62+
});
5863
});
5964

6065
describe('Methods:', () => {
@@ -827,6 +832,244 @@ describe('PoCalendarMonthYearComponent:', () => {
827832

828833
expect(mockSelectedEl.scrollIntoView).toHaveBeenCalledWith({ block: 'center', behavior: 'smooth' });
829834
}));
835+
836+
it('should scroll to current year when no selected element', fakeAsync(() => {
837+
const currentYear = new Date().getFullYear();
838+
const currentYearIndex = component.displayYears.indexOf(currentYear);
839+
const mockCurrentYearEl = { scrollIntoView: jasmine.createSpy('scrollIntoView') };
840+
const mockItems = [];
841+
for (let i = 0; i <= currentYearIndex; i++) {
842+
mockItems.push(i === currentYearIndex ? mockCurrentYearEl : {});
843+
}
844+
845+
const mockContainer = {
846+
querySelector: jasmine.createSpy('querySelector').and.returnValue(null),
847+
querySelectorAll: jasmine.createSpy('querySelectorAll').and.returnValue(mockItems)
848+
};
849+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(mockContainer);
850+
851+
component.scrollToSelectedYear();
852+
tick(200);
853+
854+
expect(mockCurrentYearEl.scrollIntoView).toHaveBeenCalledWith({ block: 'center', behavior: 'smooth' });
855+
}));
856+
857+
it('should do nothing when container is null', fakeAsync(() => {
858+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(null);
859+
860+
component.scrollToSelectedYear();
861+
tick(200);
862+
}));
863+
864+
it('should do nothing when no selected element and currentYear not in display', fakeAsync(() => {
865+
component.minDate = new Date(2060, 0, 1);
866+
component.maxDate = new Date(2065, 11, 31);
867+
component['setupYears']();
868+
869+
const mockContainer = {
870+
querySelector: jasmine.createSpy('querySelector').and.returnValue(null),
871+
querySelectorAll: jasmine.createSpy('querySelectorAll').and.returnValue([])
872+
};
873+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(mockContainer);
874+
875+
component.scrollToSelectedYear();
876+
tick(200);
877+
}));
878+
});
879+
880+
describe('focusMonthButton:', () => {
881+
it('should call focus on the button at the given index', fakeAsync(() => {
882+
const mockBtn = { focus: jasmine.createSpy('focus') };
883+
const mockPoButton = { querySelector: jasmine.createSpy('querySelector').and.returnValue(mockBtn) };
884+
const mockButtons = [mockPoButton];
885+
886+
spyOn(component['elementRef'].nativeElement, 'querySelectorAll').and.returnValue(mockButtons);
887+
888+
component['focusMonthButton'](0);
889+
tick(10);
890+
891+
expect(mockBtn.focus).toHaveBeenCalled();
892+
}));
893+
894+
it('should handle case when button element not found', fakeAsync(() => {
895+
spyOn(component['elementRef'].nativeElement, 'querySelectorAll').and.returnValue([]);
896+
897+
component['focusMonthButton'](5);
898+
tick(10);
899+
}));
900+
901+
it('should handle case when inner button is null', fakeAsync(() => {
902+
const mockPoButton = { querySelector: jasmine.createSpy('querySelector').and.returnValue(null) };
903+
spyOn(component['elementRef'].nativeElement, 'querySelectorAll').and.returnValue([mockPoButton]);
904+
905+
component['focusMonthButton'](0);
906+
tick(10);
907+
}));
908+
});
909+
910+
describe('focusYearButton:', () => {
911+
it('should call focus and scrollIntoView on the year button', fakeAsync(() => {
912+
const mockBtn = {
913+
focus: jasmine.createSpy('focus'),
914+
scrollIntoView: jasmine.createSpy('scrollIntoView')
915+
};
916+
const mockPoButton = { querySelector: jasmine.createSpy('querySelector').and.returnValue(mockBtn) };
917+
const mockContainer = {
918+
querySelectorAll: jasmine.createSpy('querySelectorAll').and.returnValue([mockPoButton])
919+
};
920+
921+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(mockContainer);
922+
923+
component['focusYearButton'](0);
924+
tick(10);
925+
926+
expect(mockBtn.focus).toHaveBeenCalled();
927+
expect(mockBtn.scrollIntoView).toHaveBeenCalledWith({ block: 'nearest', behavior: 'smooth' });
928+
}));
929+
930+
it('should handle case when container is null', fakeAsync(() => {
931+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(null);
932+
933+
component['focusYearButton'](0);
934+
tick(10);
935+
}));
936+
937+
it('should handle case when buttons array is empty', fakeAsync(() => {
938+
const mockContainer = {
939+
querySelectorAll: jasmine.createSpy('querySelectorAll').and.returnValue([])
940+
};
941+
942+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(mockContainer);
943+
944+
component['focusYearButton'](5);
945+
tick(10);
946+
}));
947+
948+
it('should handle case when inner button is null', fakeAsync(() => {
949+
const mockPoButton = { querySelector: jasmine.createSpy('querySelector').and.returnValue(null) };
950+
const mockContainer = {
951+
querySelectorAll: jasmine.createSpy('querySelectorAll').and.returnValue([mockPoButton])
952+
};
953+
954+
spyOn(component['elementRef'].nativeElement, 'querySelector').and.returnValue(mockContainer);
955+
956+
component['focusYearButton'](0);
957+
tick(10);
958+
}));
959+
});
960+
961+
describe('setupMonths:', () => {
962+
it('should populate displayMonths without setting language when locale is not set', () => {
963+
component['_locale'] = undefined;
964+
component['setupMonths']();
965+
expect(component.displayMonths.length).toBe(12);
966+
});
967+
});
968+
969+
describe('setupYears with string minDate/maxDate:', () => {
970+
it('should handle string minDate by converting to Date', () => {
971+
const currentYear = new Date().getFullYear();
972+
component.minDate = new Date(currentYear - 5, 0, 1);
973+
component['setupYears']();
974+
expect(component.displayYears[0]).toBe(currentYear - 5);
975+
});
976+
977+
it('should handle string maxDate by converting to Date', () => {
978+
const currentYear = new Date().getFullYear();
979+
component.maxDate = new Date(currentYear + 3, 11, 31);
980+
component['setupYears']();
981+
expect(component.displayYears[component.displayYears.length - 1]).toBe(currentYear + 3);
982+
});
983+
984+
it('should handle non-Date minDate by converting via new Date()', () => {
985+
const currentYear = new Date().getFullYear();
986+
component.minDate = `${currentYear - 3}-01-01` as any;
987+
component['setupYears']();
988+
expect(component.displayYears[0]).toBe(currentYear - 3);
989+
});
990+
991+
it('should handle non-Date maxDate by converting via new Date()', () => {
992+
const currentYear = new Date().getFullYear();
993+
component.maxDate = `${currentYear + 2}-12-31` as any;
994+
component['setupYears']();
995+
expect(component.displayYears[component.displayYears.length - 1]).toBe(currentYear + 2);
996+
});
997+
});
998+
999+
describe('emitSelection edge cases:', () => {
1000+
it('should not emit in year mode when selectedYear is null', () => {
1001+
component.mode = 'year';
1002+
component.selectedYear = null;
1003+
spyOn(component.select, 'emit');
1004+
component['emitSelection']();
1005+
expect(component.select.emit).not.toHaveBeenCalled();
1006+
});
1007+
1008+
it('should not emit in year mode when selectedYear is undefined', () => {
1009+
component.mode = 'year';
1010+
component.selectedYear = undefined;
1011+
spyOn(component.select, 'emit');
1012+
component['emitSelection']();
1013+
expect(component.select.emit).not.toHaveBeenCalled();
1014+
});
1015+
});
1016+
1017+
describe('navigateMonth edge cases:', () => {
1018+
it('should skip all disabled months and not navigate if all are disabled', () => {
1019+
spyOn(component, 'isMonthDisabled').and.returnValue(true);
1020+
spyOn(component as any, 'focusMonthButton');
1021+
component.focusedMonthIndex = 5;
1022+
1023+
component['navigateMonth'](5, 1);
1024+
1025+
expect(component['focusMonthButton']).not.toHaveBeenCalled();
1026+
});
1027+
});
1028+
1029+
describe('navigateYear edge cases:', () => {
1030+
it('should skip all disabled years and not navigate if all are disabled', () => {
1031+
spyOn(component, 'isYearDisabled').and.returnValue(true);
1032+
spyOn(component as any, 'focusYearButton');
1033+
component.focusedYearIndex = 5;
1034+
1035+
component['navigateYear'](5, 1);
1036+
1037+
expect(component['focusYearButton']).not.toHaveBeenCalled();
1038+
});
1039+
});
1040+
1041+
describe('onYearKeydown edge cases:', () => {
1042+
it('should not select year on Space when year is disabled', () => {
1043+
spyOn(component, 'isYearDisabled').and.returnValue(true);
1044+
spyOn(component, 'onSelectYear');
1045+
const event = new KeyboardEvent('keydown', { key: ' ' });
1046+
1047+
component.onYearKeydown(event, 5);
1048+
1049+
expect(component.onSelectYear).not.toHaveBeenCalled();
1050+
});
1051+
});
1052+
1053+
describe('setInitialFocus edge cases:', () => {
1054+
it('should handle selectedMonth as negative number', () => {
1055+
component.selectedMonth = -1;
1056+
component['setInitialFocus']();
1057+
expect(component.focusedMonthIndex).toBe(0);
1058+
});
1059+
1060+
it('should handle selectedMonth as 12 (out of range)', () => {
1061+
component.selectedMonth = 12;
1062+
component['setInitialFocus']();
1063+
expect(component.focusedMonthIndex).toBe(0);
1064+
});
1065+
1066+
it('should handle selectedYear not in displayYears but currentYear is', () => {
1067+
const currentYear = new Date().getFullYear();
1068+
component.selectedYear = 1800;
1069+
component['setInitialFocus']();
1070+
const expectedIndex = component.displayYears.indexOf(currentYear);
1071+
expect(component.focusedYearIndex).toBe(expectedIndex);
1072+
});
8301073
});
8311074
});
8321075
});

0 commit comments

Comments
 (0)