import { describe, expect, it } from 'bun:test'; import { CLASS_WINDOW_HOURS, nextClassOccurrence } from '@/modules/home/lib/scheduler'; const TZ = 'America/Mexico_City'; describe('nextClassOccurrence', () => { it('devuelve la próxima clase de hoy cuando aún no arrancó', () => { const now = new Date('2026-09-23T18:00:00.000Z'); // miércoles 12:00 hora CDMX const result = nextClassOccurrence({ days: ['WEDNESDAY'], time: '18:00', now, timeZone: TZ, }); expect(result).toEqual({ occurrenceAt: new Date('2026-09-24T00:00:00.000Z'), isNow: false, }); }); it('marca en curso si la clase arrancó hace menos de la ventana', () => { const now = new Date('2026-09-24T01:00:00.000Z'); // miércoles 19:00 hora CDMX (1 h tras la clase) const result = nextClassOccurrence({ days: ['WEDNESDAY'], time: '18:00', now, timeZone: TZ, }); expect(result).toEqual({ occurrenceAt: new Date('2026-09-24T00:00:00.000Z'), isNow: true, }); }); it('salta a la próxima semana si la clase ya pasó la ventana', () => { const now = new Date('2026-09-24T03:00:00.000Z'); // miércoles 21:00 hora CDMX (3 h tras la clase) const result = nextClassOccurrence({ days: ['WEDNESDAY'], time: '18:00', now, timeZone: TZ, }); expect(result).toEqual({ occurrenceAt: new Date('2026-10-01T00:00:00.000Z'), isNow: false, }); }); it('elige la ocurrencia más próxima entre varios días', () => { const now = new Date('2026-09-23T18:00:00.000Z'); // miércoles 12:00 hora CDMX const result = nextClassOccurrence({ days: ['MONDAY', 'WEDNESDAY', 'FRIDAY'], time: '18:00', now, timeZone: TZ, }); expect(result).toEqual({ occurrenceAt: new Date('2026-09-24T00:00:00.000Z'), isNow: false, }); }); it('cruza de mes sin problema', () => { const now = new Date('2026-09-29T18:00:00.000Z'); // martes 12:00 hora CDMX (último día de septiembre es miércoles 30) const result = nextClassOccurrence({ days: ['THURSDAY'], time: '09:00', now, timeZone: TZ, }); expect(result).toEqual({ occurrenceAt: new Date('2026-10-01T15:00:00.000Z'), isNow: false, }); }); it('devuelve null si no hay días de clase', () => { const result = nextClassOccurrence({ days: [], time: '18:00', now: new Date('2026-09-23T18:00:00.000Z'), timeZone: TZ, }); expect(result).toBeNull(); }); it('devuelve null si la hora es inválida', () => { const result = nextClassOccurrence({ days: ['WEDNESDAY'], time: '99:99', now: new Date('2026-09-23T18:00:00.000Z'), timeZone: TZ, }); expect(result).toBeNull(); }); it('expone el tamaño de la ventana de "en curso"', () => { expect(CLASS_WINDOW_HOURS).toBeGreaterThan(0); }); });