diff --git a/src/app/app.spec.ts b/src/app/app.spec.ts index 755261f..3aaada2 100644 --- a/src/app/app.spec.ts +++ b/src/app/app.spec.ts @@ -20,6 +20,6 @@ describe('App', () => { const fixture = TestBed.createComponent(App); fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, vac-optimizer'); + expect(compiled.querySelector('h1')?.textContent).toContain('vac-optimizer'); }); }); diff --git a/src/app/components/calendar-month/calendar-month.spec.ts b/src/app/components/calendar-month/calendar-month.spec.ts index f626a80..4854521 100644 --- a/src/app/components/calendar-month/calendar-month.spec.ts +++ b/src/app/components/calendar-month/calendar-month.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { CalendarMonth } from './calendar-month'; describe('CalendarMonth', () => { @@ -8,7 +8,8 @@ describe('CalendarMonth', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CalendarMonth] + imports: [CalendarMonth], + providers: [provideZonelessChangeDetection()] }) .compileComponents(); diff --git a/src/app/components/calendar-settings/calendar-settings.spec.ts b/src/app/components/calendar-settings/calendar-settings.spec.ts index 995228c..0fbfe5e 100644 --- a/src/app/components/calendar-settings/calendar-settings.spec.ts +++ b/src/app/components/calendar-settings/calendar-settings.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { CalendarSettings } from './calendar-settings'; describe('CalendarSettings', () => { @@ -8,7 +8,8 @@ describe('CalendarSettings', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CalendarSettings] + imports: [CalendarSettings], + providers: [provideZonelessChangeDetection()] }) .compileComponents(); diff --git a/src/app/components/calendar-year/calendar-year.spec.ts b/src/app/components/calendar-year/calendar-year.spec.ts index 7bdfb0f..6a027bf 100644 --- a/src/app/components/calendar-year/calendar-year.spec.ts +++ b/src/app/components/calendar-year/calendar-year.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { CalendarYear } from './calendar-year'; describe('CalendarYear', () => { @@ -8,7 +8,8 @@ describe('CalendarYear', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CalendarYear] + imports: [CalendarYear], + providers: [provideZonelessChangeDetection()] }) .compileComponents(); diff --git a/src/app/components/calendar-year/calendar-year.ts b/src/app/components/calendar-year/calendar-year.ts index f0223b7..d418519 100644 --- a/src/app/components/calendar-year/calendar-year.ts +++ b/src/app/components/calendar-year/calendar-year.ts @@ -46,6 +46,7 @@ export class CalendarYear { this.selectedDates.optimizeVacations( { ...vacationData }, this.calendarSettingsService, + this.calendarService, ); } this.isLoading.set(false); diff --git a/src/app/components/dark-light-mode-button/dark-light-mode-button.spec.ts b/src/app/components/dark-light-mode-button/dark-light-mode-button.spec.ts index f1289f4..9a5e150 100644 --- a/src/app/components/dark-light-mode-button/dark-light-mode-button.spec.ts +++ b/src/app/components/dark-light-mode-button/dark-light-mode-button.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { DarkLightModeButton } from './dark-light-mode-button'; describe('DarkLightModeButton', () => { @@ -9,6 +9,7 @@ describe('DarkLightModeButton', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [DarkLightModeButton], + providers: [provideZonelessChangeDetection()], }).compileComponents(); fixture = TestBed.createComponent(DarkLightModeButton); diff --git a/src/app/components/dialog/calendar-settings-dialog/calendar-settings-dialog.spec.ts b/src/app/components/dialog/calendar-settings-dialog/calendar-settings-dialog.spec.ts index e2e8057..402949c 100644 --- a/src/app/components/dialog/calendar-settings-dialog/calendar-settings-dialog.spec.ts +++ b/src/app/components/dialog/calendar-settings-dialog/calendar-settings-dialog.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; import { CalendarSettingsDialog } from './calendar-settings-dialog'; describe('CalendarSettingsDialog', () => { @@ -8,7 +9,16 @@ describe('CalendarSettingsDialog', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CalendarSettingsDialog] + imports: [CalendarSettingsDialog], + providers: [ + provideZonelessChangeDetection(), + { + provide: MatDialogRef, + useValue: { + close: jasmine.createSpy('close') + } + } + ] }) .compileComponents(); @@ -20,4 +30,13 @@ describe('CalendarSettingsDialog', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should have calendar settings service', () => { + expect(component['calendarSettingsService']).toBeDefined(); + }); + + it('should close dialog when closeDialog is called', () => { + component.closeDialog(); + expect(component.dialogRef.close).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/user-input/user-input.spec.ts b/src/app/components/user-input/user-input.spec.ts index 7ebb8c0..2de59e0 100644 --- a/src/app/components/user-input/user-input.spec.ts +++ b/src/app/components/user-input/user-input.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { UserInput } from './user-input'; describe('UserInput', () => { @@ -8,7 +8,8 @@ describe('UserInput', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [UserInput] + imports: [UserInput], + providers: [provideZonelessChangeDetection()] }) .compileComponents(); @@ -20,4 +21,21 @@ describe('UserInput', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should initialize form with values from service', () => { + expect(component.userInputForm).toBeDefined(); + expect(component.userInputForm.get('CP')).toBeDefined(); + expect(component.userInputForm.get('RTT')).toBeDefined(); + expect(component.userInputForm.get('Others')).toBeDefined(); + }); + + it('should have valid form controls', () => { + const cpControl = component.userInputForm.get('CP'); + const rttControl = component.userInputForm.get('RTT'); + const othersControl = component.userInputForm.get('Others'); + + expect(cpControl).toBeTruthy(); + expect(rttControl).toBeTruthy(); + expect(othersControl).toBeTruthy(); + }); }); diff --git a/src/app/components/user-settings/user-settings.spec.ts b/src/app/components/user-settings/user-settings.spec.ts index 8276af1..d0a0eaa 100644 --- a/src/app/components/user-settings/user-settings.spec.ts +++ b/src/app/components/user-settings/user-settings.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { UserSettings } from './user-settings'; describe('UserSettings', () => { @@ -8,7 +8,8 @@ describe('UserSettings', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [UserSettings] + imports: [UserSettings], + providers: [provideZonelessChangeDetection()] }) .compileComponents(); diff --git a/src/app/services/calendar-service.spec.ts b/src/app/services/calendar-service.spec.ts index c2bf5a5..48aa9c4 100644 --- a/src/app/services/calendar-service.spec.ts +++ b/src/app/services/calendar-service.spec.ts @@ -1,16 +1,241 @@ import { TestBed } from '@angular/core/testing'; - -import { CalendarService } from './calendar-service'; +import { provideZonelessChangeDetection } from '@angular/core'; +import { + CalendarService, + DayType, + SelectedDate, + SelectedDates, +} from './calendar-service'; +import { DateRange } from '@angular/material/datepicker'; describe('CalendarService', () => { let service: CalendarService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(CalendarService); }); it('should be created', () => { expect(service).toBeTruthy(); }); + + describe('getHolidays', () => { + it('should return an array of holidays', () => { + const holidays = service.getHolidays(); + expect(Array.isArray(holidays)).toBe(true); + expect(holidays.length).toBeGreaterThan(0); + }); + + it('should cache holidays for the same year', () => { + const holidays1 = service.getHolidays(); + const holidays2 = service.getHolidays(); + expect(holidays1).toEqual(holidays2); + }); + }); + + describe('static date calculation methods', () => { + it('should calculate days in a week', () => { + const week = CalendarService.daysInWeek(0, 0, 2024); + expect(week.length).toBe(7); + }); + + it('should calculate weeks in a month', () => { + const weeks = CalendarService.weeksInMonth(0, 2024); + expect(weeks.length).toBeGreaterThan(0); + expect(weeks.length).toBeLessThanOrEqual(6); + }); + + it('should calculate months in a year', () => { + const months = CalendarService.monthsInYear(2024); + expect(months.length).toBe(12); + }); + + it('should calculate months from now', () => { + const months = service.monthsInAYearFromNow(); + expect(months.length).toBe(12); + }); + + it('should return week number for a date', () => { + const date = new Date(2024, 0, 1); + const weekNumber = CalendarService.getWeekNumber(date); + expect(weekNumber).toBeGreaterThan(0); + expect(weekNumber).toBeLessThanOrEqual(53); + }); + }); + + describe('getSelectedDatesForYear', () => { + it('should return selected dates for the year', () => { + const selectedDates = service.getSelectedDatesForYear(); + expect(selectedDates).toBeDefined(); + expect(selectedDates._datesSelected.length).toBeGreaterThan(0); + }); + + it('should include weekends', () => { + const selectedDates = service.getSelectedDatesForYear(); + const hasWeekend = selectedDates._datesSelected.some( + (date) => date.type === DayType.WEEKEND, + ); + expect(hasWeekend).toBe(true); + }); + + it('should include holidays', () => { + const selectedDates = service.getSelectedDatesForYear(); + const hasHoliday = selectedDates._datesSelected.some( + (date) => date.type === DayType.CLOSED_DAY, + ); + expect(hasHoliday).toBe(true); + }); + + it('should include today', () => { + const selectedDates = service.getSelectedDatesForYear(); + const hasToday = selectedDates._datesSelected.some( + (date) => date.type === DayType.TODAY, + ); + expect(hasToday).toBe(true); + }); + }); + + describe('setWeekendSelection', () => { + it('should add weekend for Saturday', () => { + const selectedDates = new SelectedDates(); + const saturday = new Date(2024, 0, 6); // A Saturday + service.setWeekendSelection(saturday, selectedDates); + expect(selectedDates._datesSelected.length).toBeGreaterThan(0); + }); + }); +}); + +describe('SelectedDate', () => { + it('should check if date is selected', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(date, date), + ); + expect(selectedDate.isSelected(date)).toBe(true); + }); + + it('should check if date is start', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(date, date), + ); + expect(selectedDate.isStart(date)).toBe(true); + }); + + it('should check if date is end', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(date, date), + ); + expect(selectedDate.isEnd(date)).toBe(true); + }); + + it('should return correct classes for date', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(date, date), + ); + const classes = selectedDate.getClasses(date); + expect(classes).toContain(DayType.CP); + }); + + it('should return tooltip for selected date', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(date, date), + ); + const tooltip = selectedDate.getTooltip(date); + expect(tooltip).toBeTruthy(); + }); + + it('should calculate length in days', () => { + const startDate = new Date(2024, 0, 1); + const endDate = new Date(2024, 0, 3); + const selectedDate = new SelectedDate( + DayType.CP, + new DateRange(startDate, endDate), + ); + expect(selectedDate.getLengthInDays()).toBe(3); + }); + + it('should not mark TODAY as selected', () => { + const date = new Date(2024, 0, 1); + const selectedDate = new SelectedDate( + DayType.TODAY, + new DateRange(date, date), + ); + expect(selectedDate.isSelected(date)).toBe(false); + }); +}); + +describe('SelectedDates', () => { + it('should push selected dates', () => { + const selectedDates = new SelectedDates(); + const date = new Date(2024, 0, 1); + selectedDates.push( + new SelectedDate(DayType.CP, new DateRange(date, date)), + ); + expect(selectedDates._datesSelected.length).toBe(1); + }); + + it('should check if date is selected', () => { + const selectedDates = new SelectedDates(); + const date = new Date(2024, 0, 1); + selectedDates.push( + new SelectedDate(DayType.CP, new DateRange(date, date)), + ); + expect(selectedDates.isSelected(date)).toBe(true); + }); + + it('should group adjacent dates', () => { + const selectedDates = new SelectedDates(); + const date1 = new Date(2024, 0, 1); + const date2 = new Date(2024, 0, 2); + selectedDates._datesSelected.push( + new SelectedDate(DayType.CP, new DateRange(date1, date1)), + ); + selectedDates._datesSelected.push( + new SelectedDate(DayType.RTT, new DateRange(date2, date2)), + ); + selectedDates.update(); + expect(selectedDates.datesSelected.length).toBeGreaterThan(2); + }); + + it('should compute heuristics', () => { + const selectedDates = new SelectedDates(); + const date = new Date(2024, 0, 1); + selectedDates.push( + new SelectedDate(DayType.CP, new DateRange(date, date)), + ); + const heuristic = selectedDates.computeHeuristics(); + expect(typeof heuristic).toBe('number'); + }); + + it('should return correct classes', () => { + const selectedDates = new SelectedDates(); + const date = new Date(2024, 0, 1); + selectedDates.push( + new SelectedDate(DayType.CP, new DateRange(date, date)), + ); + const classes = selectedDates.getClasses(date); + expect(classes).toContain(DayType.CP); + }); + + it('should return tooltip', () => { + const selectedDates = new SelectedDates(); + const date = new Date(2024, 0, 1); + selectedDates.push( + new SelectedDate(DayType.CP, new DateRange(date, date)), + ); + const tooltip = selectedDates.getTooltip(date); + expect(tooltip).toBeTruthy(); + }); }); diff --git a/src/app/services/calendar-service.ts b/src/app/services/calendar-service.ts index a910fb5..8edf06d 100644 --- a/src/app/services/calendar-service.ts +++ b/src/app/services/calendar-service.ts @@ -36,7 +36,7 @@ export class CalendarService { getSelectedDatesForYear(): SelectedDates { const holidays = this.getHolidays(); - const monthInAYear = CalendarService.monthsInAYearFromNow(); + const monthInAYear = this.monthsInAYearFromNow(); let selectedDates: SelectedDates = new SelectedDates(); // Use DateCacheService to get today's date components @@ -167,15 +167,14 @@ export class CalendarService { return months; } - static monthsInAYearFromNow(): Year { - const dateCache = inject(DateCacheService); + monthsInAYearFromNow(): Year { const months: Year = []; - const currentMonthIndex = dateCache.getCurrentMonth(); - const currentYear = dateCache.getCurrentYear(); + const currentMonthIndex = this.dateCache.getCurrentMonth(); + const currentYear = this.dateCache.getCurrentYear(); for (let i = 0; i < 12; i++) { const monthIndex = (currentMonthIndex + i) % 12; const year = currentYear + Math.floor((currentMonthIndex + i) / 12); - months.push(this.weeksInMonth(monthIndex, year)); + months.push(CalendarService.weeksInMonth(monthIndex, year)); } return months; } @@ -539,24 +538,25 @@ export class SelectedDates implements SelectedDateInterface { optimizeVacations( vacationsNumber: VacationsNumber, calendarSettingsService: CalendarSettingsService, + calendarService: CalendarService, ): void { if (calendarSettingsService.samediMalin()) this.samediMalin(vacationsNumber); while (vacationsNumber.cp > 0) { - const result = this.lookForVacation(DayType.CP); + const result = this.lookForVacation(DayType.CP, calendarService); if (result.heuristic === SelectedDates.NO_VALID_STRATEGY_HEURISTIC) { break; } vacationsNumber.cp -= 1; } while (vacationsNumber.rtt > 0) { - const result = this.lookForVacation(DayType.RTT); + const result = this.lookForVacation(DayType.RTT, calendarService); if (result.heuristic === SelectedDates.NO_VALID_STRATEGY_HEURISTIC) { break; } vacationsNumber.rtt -= 1; } while (vacationsNumber.other > 0) { - const result = this.lookForVacation(DayType.OTHER); + const result = this.lookForVacation(DayType.OTHER, calendarService); if (result.heuristic === SelectedDates.NO_VALID_STRATEGY_HEURISTIC) { break; } @@ -719,8 +719,8 @@ export class SelectedDates implements SelectedDateInterface { } } - lookForVacation(vacType: DayType): { apply: () => void; heuristic: number } { - const daysOfYear = CalendarService.monthsInAYearFromNow(); + lookForVacation(vacType: DayType, calendarService: CalendarService): { apply: () => void; heuristic: number } { + const daysOfYear = calendarService.monthsInAYearFromNow(); const now = new Date(); now.setHours(0, 0, 0, 0); const nowTime = now.getTime(); diff --git a/src/app/services/calendar-settings-service.spec.ts b/src/app/services/calendar-settings-service.spec.ts index 9d3efe1..33dc540 100644 --- a/src/app/services/calendar-settings-service.spec.ts +++ b/src/app/services/calendar-settings-service.spec.ts @@ -1,16 +1,33 @@ import { TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { CalendarSettingsService } from './calendar-settings-service'; describe('CalendarSettingsService', () => { let service: CalendarSettingsService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(CalendarSettingsService); }); it('should be created', () => { expect(service).toBeTruthy(); }); + + it('should initialize with default values', () => { + expect(service.showWeekNumbers()).toBe(false); + expect(service.samediMalin()).toBe(true); + }); + + it('should allow updating showWeekNumbers', () => { + service.showWeekNumbers.set(true); + expect(service.showWeekNumbers()).toBe(true); + }); + + it('should allow updating samediMalin', () => { + service.samediMalin.set(false); + expect(service.samediMalin()).toBe(false); + }); }); diff --git a/src/app/services/date-cache.service.spec.ts b/src/app/services/date-cache.service.spec.ts index c51d794..f7a199c 100644 --- a/src/app/services/date-cache.service.spec.ts +++ b/src/app/services/date-cache.service.spec.ts @@ -1,11 +1,14 @@ import { TestBed } from '@angular/core/testing'; +import { provideZonelessChangeDetection } from '@angular/core'; import { DateCacheService } from './date-cache.service'; describe('DateCacheService', () => { let service: DateCacheService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(DateCacheService); }); @@ -43,4 +46,18 @@ describe('DateCacheService', () => { const year2 = service.getCurrentYear(); expect(year1).toBe(year2); // Values should be the same even after clearing }); + + it('should return today with time normalized to 00:00:00.000', () => { + const today = service.getToday(); + expect(today.getHours()).toBe(0); + expect(today.getMinutes()).toBe(0); + expect(today.getSeconds()).toBe(0); + expect(today.getMilliseconds()).toBe(0); + }); + + it('should return getNow() same as getToday()', () => { + const now = service.getNow(); + const today = service.getToday(); + expect(now).toBe(today); + }); }); diff --git a/src/app/services/theme-service.spec.ts b/src/app/services/theme-service.spec.ts index 4d6836c..aca0ffa 100644 --- a/src/app/services/theme-service.spec.ts +++ b/src/app/services/theme-service.spec.ts @@ -1,16 +1,42 @@ import { TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { ThemeService } from './theme-service'; describe('ThemeService', () => { let service: ThemeService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(ThemeService); }); it('should be created', () => { expect(service).toBeTruthy(); }); + + it('should initialize with system preference', () => { + expect(service.isLightMode()).toBeDefined(); + }); + + it('should toggle theme', () => { + const initialMode = service.isLightMode(); + service.toggleTheme(); + expect(service.isLightMode()).toBe(!initialMode); + }); + + it('should force light mode when specified', () => { + service.toggleTheme(true); + expect(service.isLightMode()).toBe(true); + expect(document.body.classList.contains('light-mode')).toBe(true); + expect(document.body.classList.contains('dark-mode')).toBe(false); + }); + + it('should force dark mode when specified', () => { + service.toggleTheme(false); + expect(service.isLightMode()).toBe(false); + expect(document.body.classList.contains('light-mode')).toBe(false); + expect(document.body.classList.contains('dark-mode')).toBe(true); + }); }); diff --git a/src/app/services/user-input-service.spec.ts b/src/app/services/user-input-service.spec.ts index fa0eb04..abaafdf 100644 --- a/src/app/services/user-input-service.spec.ts +++ b/src/app/services/user-input-service.spec.ts @@ -1,16 +1,34 @@ import { TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { UserInputService } from './user-input-service'; describe('UserInput', () => { let service: UserInputService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(UserInputService); }); it('should be created', () => { expect(service).toBeTruthy(); }); + + it('should initialize with random vacation numbers', () => { + const vacations = service.vacationNumberSignal(); + expect(vacations.cp).toBeGreaterThanOrEqual(1); + expect(vacations.cp).toBeLessThanOrEqual(9); + expect(vacations.rtt).toBeGreaterThanOrEqual(1); + expect(vacations.rtt).toBeLessThanOrEqual(9); + expect(vacations.other).toBeGreaterThanOrEqual(1); + expect(vacations.other).toBeLessThanOrEqual(9); + }); + + it('should update vacation number signal', () => { + const newVacations = { cp: 5, rtt: 3, other: 2 }; + service.vacationNumberSignal.set(newVacations); + expect(service.vacationNumberSignal()).toEqual(newVacations); + }); }); diff --git a/src/app/services/user-settings-service.spec.ts b/src/app/services/user-settings-service.spec.ts index 54bc3ba..399f06a 100644 --- a/src/app/services/user-settings-service.spec.ts +++ b/src/app/services/user-settings-service.spec.ts @@ -1,12 +1,14 @@ import { TestBed } from '@angular/core/testing'; - +import { provideZonelessChangeDetection } from '@angular/core'; import { UserSettingsService } from './user-settings-service'; describe('UserSettingsService', () => { let service: UserSettingsService; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [provideZonelessChangeDetection()], + }); service = TestBed.inject(UserSettingsService); });