diff --git a/src/app/services/calendar-service.spec.ts b/src/app/services/calendar-service.spec.ts index ec749a9..912c641 100644 --- a/src/app/services/calendar-service.spec.ts +++ b/src/app/services/calendar-service.spec.ts @@ -8,6 +8,7 @@ import { SelectedDates, } from './calendar-service'; import { DateRange } from '@angular/material/datepicker'; +import { vi } from '../../testing/vitest-compat'; describe('CalendarService', () => { let service: CalendarService; @@ -197,6 +198,8 @@ describe('CalendarService', () => { service.project({ placements: [], horizon }); const day = (key: string) => new Date(`${key}T00:00:00`); + afterEach(() => vi.useRealTimers()); + it('projects weekends, holidays and today for the default planning horizon', () => { const { selections } = project({ start: '2026-01-01', end: '2027-01-01' }); expect(selections.dayTypes(day('2026-05-09'))).toContain(DayType.WEEKEND); @@ -207,6 +210,15 @@ describe('CalendarService', () => { ); }); + it('marks today on the Europe/Paris date when the runtime date is still the day before', () => { + vi.setSystemTime(new Date('2026-10-17T22:16:00Z')); + const horizon = service.getDefaultPlanningHorizon(); + expect(horizon.start).toBe('2026-10-18'); + const { selections } = project(horizon); + expect(selections.getClasses(day('2026-10-18'))).toContain(DayType.TODAY); + expect(selections.getClasses(day('2026-10-17'))).not.toContain(DayType.TODAY); + }); + it('lists the covered months, including partial boundary months and year changes', () => { expect(project({ start: '2024-11-20', end: '2025-02-02' }).months).toEqual([ { monthIndex: 10, year: 2024 }, diff --git a/src/app/services/calendar-service.ts b/src/app/services/calendar-service.ts index bedccdc..67ed933 100644 --- a/src/app/services/calendar-service.ts +++ b/src/app/services/calendar-service.ts @@ -85,11 +85,9 @@ export class CalendarService { const holidays = new Set( this.getHolidays(first.getFullYear(), last.getFullYear()).map((h) => h.getTime()), ); - const { - date: todayDate, - month: todayMonth, - year: todayYear, - } = this.dateCache.getTodayComponents(); + const [todayYear, todayMonth, todayDate] = planningDateInParis(new Date()) + .split('-') + .map(Number); const months: CalendarProjection['months'] = []; const ranges: SelectedDate[] = []; const cursor = new Date(first); @@ -124,7 +122,7 @@ export class CalendarService { ); if ( day.getDate() === todayDate && - day.getMonth() === todayMonth && + day.getMonth() + 1 === todayMonth && day.getFullYear() === todayYear ) ranges.push(new SelectedDate(DayType.TODAY, new DateRange(day, day))); diff --git a/src/app/services/leave-planner.worker.spec.ts b/src/app/services/leave-planner.worker.spec.ts index 61a2423..36f1e81 100644 --- a/src/app/services/leave-planner.worker.spec.ts +++ b/src/app/services/leave-planner.worker.spec.ts @@ -587,8 +587,8 @@ parentPort.on('message', (data) => globalThis.self.onmessage({ data })); ); it('stops during calendar preparation without a plan or an obligation conflict', async () => { + holdForCancelAtStage = 'preparation'; const stages: string[] = []; - let preparationUpdates = 0; const calculation = createPlanningCalculation({ horizon: { start: '2024-01-01', end: '2027-01-01' }, balances: [], @@ -596,7 +596,7 @@ parentPort.on('message', (data) => globalThis.self.onmessage({ data })); declaredDays: [{ date: '2024-01-02', type: 'other' }], progress: (stage) => { stages.push(stage); - if (stage === 'preparation' && ++preparationUpdates === 2) calculation.cancel(); + if (stage === 'preparation') calculation.cancel(); }, }); const outcome = await calculation.outcome; @@ -606,7 +606,7 @@ parentPort.on('message', (data) => globalThis.self.onmessage({ data })); }); if (outcome.kind !== 'PlanningIncomplete') return; expect(outcome.incumbent).toBeUndefined(); - expect(preparationUpdates).toBeGreaterThanOrEqual(2); + expect(stages).toContain('preparation'); expect(stages).not.toContain('obligations'); expect(await calculation.explanationError).toBeUndefined(); expect(heartbeats).toBeGreaterThan(0);