import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/estado/estado_alarmas.dart'; import 'package:pluriwave/modelos/alarma_musical.dart'; import 'package:pluriwave/servicios/servicio_alarmas.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../helpers/fakes_alarmas.dart'; /// S3-R6: `_ejecucionesEmitidas` must be bounded — stale entries (>24 h) /// pruned and total size capped. void main() { TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { SharedPreferences.setMockInitialValues({}); }); EstadoAlarmas crearEstado(FakePuertoAlarmasAndroid android) { final estado = EstadoAlarmas( servicio: ServicioAlarmas(), android: android, iniciarAutomaticamente: false, ); addTearDown(estado.dispose); addTearDown(android.dispose); return estado; } const base = AlarmaMusical( id: 'a1', nombre: 'Diaria', hora: 7, minuto: 0, tipoProgramacion: TipoProgramacionAlarma.diaria, diasSemana: [], ); test('poda las entradas con mas de 24 horas (S3-R6-A)', () { final estado = crearEstado(FakePuertoAlarmasAndroid()); final ahora = DateTime.now(); for (var i = 0; i < 100; i++) { estado.marcarEjecucionGestionada( base.copyWith( proximaEjecucion: ahora.subtract(Duration(hours: 25, minutes: i)), ), ); } estado.marcarEjecucionGestionada( base.copyWith( id: 'fresca', proximaEjecucion: ahora.add(const Duration(minutes: 5)), ), ); expect( estado.ejecucionesEmitidasLength, lessThanOrEqualTo(EstadoAlarmas.maxEjecucionesEmitidas), ); expect( estado.ejecucionesEmitidasLength, 1, reason: 'solo la entrada fresca sobrevive a la poda por antiguedad', ); }); test('limita el total de entradas al tope configurado', () { final estado = crearEstado(FakePuertoAlarmasAndroid()); final ahora = DateTime.now(); for (var i = 0; i < EstadoAlarmas.maxEjecucionesEmitidas + 50; i++) { estado.marcarEjecucionGestionada( base.copyWith(proximaEjecucion: ahora.add(Duration(minutes: i))), ); } expect( estado.ejecucionesEmitidasLength, lessThanOrEqualTo(EstadoAlarmas.maxEjecucionesEmitidas), ); }); }