fix: stabilize two CI test failures (Paris today, worker cancel race) #307

Closed
nessar wants to merge 3 commits from feature/ci-test-stability into develop
pull from: feature/ci-test-stability
3 changed files with 19 additions and 9 deletions

No files matched your search

+12
View File
@@ -8,6 +8,7 @@ import {
SelectedDates, SelectedDates,
} from './calendar-service'; } from './calendar-service';
import { DateRange } from '@angular/material/datepicker'; import { DateRange } from '@angular/material/datepicker';
import { vi } from '../../testing/vitest-compat';
describe('CalendarService', () => { describe('CalendarService', () => {
let service: CalendarService; let service: CalendarService;
@@ -197,6 +198,8 @@ describe('CalendarService', () => {
service.project({ placements: [], horizon }); service.project({ placements: [], horizon });
const day = (key: string) => new Date(`${key}T00:00:00`); const day = (key: string) => new Date(`${key}T00:00:00`);
afterEach(() => vi.useRealTimers());
it('projects weekends, holidays and today for the default planning horizon', () => { it('projects weekends, holidays and today for the default planning horizon', () => {
const { selections } = project({ start: '2026-01-01', end: '2027-01-01' }); const { selections } = project({ start: '2026-01-01', end: '2027-01-01' });
expect(selections.dayTypes(day('2026-05-09'))).toContain(DayType.WEEKEND); 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', () => { it('lists the covered months, including partial boundary months and year changes', () => {
expect(project({ start: '2024-11-20', end: '2025-02-02' }).months).toEqual([ expect(project({ start: '2024-11-20', end: '2025-02-02' }).months).toEqual([
{ monthIndex: 10, year: 2024 }, { monthIndex: 10, year: 2024 },
+4 -6
View File
@@ -85,11 +85,9 @@ export class CalendarService {
const holidays = new Set( const holidays = new Set(
this.getHolidays(first.getFullYear(), last.getFullYear()).map((h) => h.getTime()), this.getHolidays(first.getFullYear(), last.getFullYear()).map((h) => h.getTime()),
); );
const { const [todayYear, todayMonth, todayDate] = planningDateInParis(new Date())
date: todayDate, .split('-')
month: todayMonth, .map(Number);
year: todayYear,
} = this.dateCache.getTodayComponents();
const months: CalendarProjection['months'] = []; const months: CalendarProjection['months'] = [];
const ranges: SelectedDate[] = []; const ranges: SelectedDate[] = [];
const cursor = new Date(first); const cursor = new Date(first);
@@ -124,7 +122,7 @@ export class CalendarService {
); );
if ( if (
day.getDate() === todayDate && day.getDate() === todayDate &&
day.getMonth() === todayMonth && day.getMonth() + 1 === todayMonth &&
day.getFullYear() === todayYear day.getFullYear() === todayYear
) )
ranges.push(new SelectedDate(DayType.TODAY, new DateRange<Date>(day, day))); ranges.push(new SelectedDate(DayType.TODAY, new DateRange<Date>(day, day)));
@@ -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 () => { it('stops during calendar preparation without a plan or an obligation conflict', async () => {
holdForCancelAtStage = 'preparation';
const stages: string[] = []; const stages: string[] = [];
let preparationUpdates = 0;
const calculation = createPlanningCalculation({ const calculation = createPlanningCalculation({
horizon: { start: '2024-01-01', end: '2027-01-01' }, horizon: { start: '2024-01-01', end: '2027-01-01' },
balances: [], balances: [],
@@ -596,7 +596,7 @@ parentPort.on('message', (data) => globalThis.self.onmessage({ data }));
declaredDays: [{ date: '2024-01-02', type: 'other' }], declaredDays: [{ date: '2024-01-02', type: 'other' }],
progress: (stage) => { progress: (stage) => {
stages.push(stage); stages.push(stage);
if (stage === 'preparation' && ++preparationUpdates === 2) calculation.cancel(); if (stage === 'preparation') calculation.cancel();
}, },
}); });
const outcome = await calculation.outcome; const outcome = await calculation.outcome;
@@ -606,7 +606,7 @@ parentPort.on('message', (data) => globalThis.self.onmessage({ data }));
}); });
if (outcome.kind !== 'PlanningIncomplete') return; if (outcome.kind !== 'PlanningIncomplete') return;
expect(outcome.incumbent).toBeUndefined(); expect(outcome.incumbent).toBeUndefined();
expect(preparationUpdates).toBeGreaterThanOrEqual(2); expect(stages).toContain('preparation');
expect(stages).not.toContain('obligations'); expect(stages).not.toContain('obligations');
expect(await calculation.explanationError).toBeUndefined(); expect(await calculation.explanationError).toBeUndefined();
expect(heartbeats).toBeGreaterThan(0); expect(heartbeats).toBeGreaterThan(0);