import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/modelos/alarma_musical.dart'; import 'package:pluriwave/servicios/servicio_alarmas.dart'; import 'package:pluriwave/servicios/servicio_programacion_alarmas.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { group('ServicioProgramacionAlarmas', () { final servicio = ServicioProgramacionAlarmas(); test('calcula la próxima alarma diaria futura', () { final alarma = AlarmaMusical( id: 'a1', nombre: 'Diaria', hora: 7, minuto: 30, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: const [], ); final proxima = servicio.calcularProxima( alarma: alarma, desde: DateTime(2026, 5, 21, 7), ); expect(proxima, DateTime(2026, 5, 21, 7, 30)); }); test('salta vacaciones si la alarma no debe sonar esos días', () { final alarma = AlarmaMusical( id: 'a2', nombre: 'Laboral', hora: 8, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: const [], sonarEnVacaciones: false, ); final proxima = servicio.calcularProxima( alarma: alarma, desde: DateTime(2026, 8, 1, 7), vacaciones: [ RangoVacaciones( id: 'v1', nombre: 'Verano', inicio: DateTime(2026, 8), fin: DateTime(2026, 8, 3), ), ], ); expect(proxima, DateTime(2026, 8, 4, 8)); }); test('saltar próxima solo omite esa ejecución', () { final alarma = AlarmaMusical( id: 'a3', nombre: 'Diaria', hora: 9, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: const [], ); final omitida = DateTime(2026, 5, 22, 9); final proxima = servicio.calcularProxima( alarma: alarma, desde: DateTime(2026, 5, 22, 8), excepciones: [ ExcepcionAlarma(alarmaId: 'a3', ejecucion: omitida, tipo: 'skipNext'), ], ); expect(proxima, DateTime(2026, 5, 23, 9)); }); test('snooze solo permite 3, 5 o 10 minutos y cae a 5', () { expect( servicio.calcularSnooze(DateTime(2026, 5, 21, 7), 10), DateTime(2026, 5, 21, 7, 10), ); expect( servicio.calcularSnooze(DateTime(2026, 5, 21, 7), 99), DateTime(2026, 5, 21, 7, 5), ); }); test( 'servicio limpia proxima ejecucion obsoleta al recalcular unica vencida', () async { SharedPreferences.setMockInitialValues({}); final servicioAlarmas = ServicioAlarmas( reloj: () => DateTime(2026, 5, 22, 10), ); final alarma = AlarmaMusical( id: 'a4', nombre: 'Unica vencida', hora: 9, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.unica, diasSemana: const [], fechaUnica: DateTime(2026, 5, 22), proximaEjecucion: DateTime(2026, 5, 22, 9), ); final guardada = await servicioAlarmas.guardarAlarma(alarma); expect(guardada.alarmas.single.proximaEjecucion, isNull); }, ); test('mantiene alarma unica creada dentro del mismo minuto', () { final alarma = AlarmaMusical( id: 'a5', nombre: 'Ahora', hora: 20, minuto: 13, tipoProgramacion: TipoProgramacionAlarma.unica, diasSemana: const [], fechaUnica: DateTime(2026, 5, 23), ); final proxima = servicio.calcularProxima( alarma: alarma, desde: DateTime(2026, 5, 23, 20, 13, 45), ); expect(proxima, DateTime(2026, 5, 23, 20, 13, 47)); }); test('calcula siguiente diaria despues de ejecucion completada', () { final alarma = AlarmaMusical( id: 'a6', nombre: 'Diaria', hora: 7, minuto: 30, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: const [], proximaEjecucion: DateTime(2026, 5, 25, 7, 30), ); final siguiente = servicio.calcularSiguienteDespuesDeEjecucion( alarma: alarma, ejecucion: DateTime(2026, 5, 25, 7, 30), ); expect(siguiente, DateTime(2026, 5, 26, 7, 30)); }); test('calcula siguiente por dias de semana despues de ejecucion', () { final alarma = AlarmaMusical( id: 'a7', nombre: 'Laboral', hora: 8, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.diasSemana, diasSemana: const [DateTime.monday, DateTime.wednesday], proximaEjecucion: DateTime(2026, 5, 25, 8), ); final siguiente = servicio.calcularSiguienteDespuesDeEjecucion( alarma: alarma, ejecucion: DateTime(2026, 5, 25, 8), ); expect(siguiente, DateTime(2026, 5, 27, 8)); }); test('alarma unica completada no calcula siguiente', () { final alarma = AlarmaMusical( id: 'a8', nombre: 'Unica', hora: 8, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.unica, diasSemana: const [], fechaUnica: DateTime(2026, 5, 25), proximaEjecucion: DateTime(2026, 5, 25, 8), ); final siguiente = servicio.calcularSiguienteDespuesDeEjecucion( alarma: alarma, ejecucion: DateTime(2026, 5, 25, 8), ); expect(siguiente, isNull); }); }); }