import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/estado/estado_grabacion.dart'; import 'package:pluriwave/modelos/emisora.dart'; import 'package:pluriwave/servicios/servicio_grabacion_radio.dart'; import '../helpers/fakes.dart'; /// S4-R2: EstadoGrabacion owns the recording state previously in EstadoRadio /// and manages ServicioGrabacionRadio. void main() { test('notifica listeners cuando cambia el estado de grabación', () async { final servicio = _ServicioGrabacionControlado(); final estado = EstadoGrabacion(servicio: servicio); addTearDown(estado.dispose); var notificaciones = 0; estado.addListener(() => notificaciones++); servicio.emitir( EstadoGrabacionRadio( tipo: EstadoGrabacionRadioTipo.grabando, emisora: emisoraDemo(uuid: 'rec-1', nombre: 'Grabable'), inicio: DateTime(2026, 6, 11, 10), ), ); await Future.delayed(Duration.zero); expect(notificaciones, 1); expect(estado.activa, isTrue); expect(estado.estado.tipo, EstadoGrabacionRadioTipo.grabando); }); test('iniciar delega en el servicio con la emisora actual', () async { final servicio = _ServicioGrabacionControlado(); final emisora = emisoraDemo(uuid: 'rec-2', nombre: 'Actual'); final estado = EstadoGrabacion( servicio: servicio, emisoraActual: () => emisora, ); addTearDown(estado.dispose); await estado.iniciar(duracion: const Duration(minutes: 1)); expect(servicio.inicios, 1); expect(servicio.emisoraIniciada?.uuid, 'rec-2'); expect(servicio.duracionIniciada, const Duration(minutes: 1)); }); test( 'iniciar sin emisora actual reporta error y no llama al servicio', () async { final servicio = _ServicioGrabacionControlado(); final errores = []; final estado = EstadoGrabacion( servicio: servicio, emisoraActual: () => null, alError: errores.add, ); addTearDown(estado.dispose); await estado.iniciar(); expect(servicio.inicios, 0); expect(errores, hasLength(1)); }, ); test('un estado de error del servicio se reporta vía alError', () async { final servicio = _ServicioGrabacionControlado(); final errores = []; final estado = EstadoGrabacion(servicio: servicio, alError: errores.add); addTearDown(estado.dispose); servicio.emitir( const EstadoGrabacionRadio( tipo: EstadoGrabacionRadioTipo.error, error: 'HTTP 500', ), ); await Future.delayed(Duration.zero); expect(errores, hasLength(1)); expect(errores.single, contains('HTTP 500')); }); } class _ServicioGrabacionControlado extends ServicioGrabacionRadio { final _controller = StreamController.broadcast(); EstadoGrabacionRadio _estadoActual = const EstadoGrabacionRadio.inactiva(); int inicios = 0; Emisora? emisoraIniciada; Duration? duracionIniciada; @override EstadoGrabacionRadio get estado => _estadoActual; @override Stream get estadoStream => _controller.stream; @override Future inicializar() async {} @override Future iniciar( Emisora emisora, { Duration? duracion, String? directorio, }) async { inicios++; emisoraIniciada = emisora; duracionIniciada = duracion; } void emitir(EstadoGrabacionRadio estado) { _estadoActual = estado; _controller.add(estado); } @override Future dispose() => _controller.close(); }