Files
pluriwave/test/estado/estado_grabacion_test.dart
T
FreeTLab d81fabbe27 refactor(iap): make esPremium a required constructor parameter
EstadoAlarmas, EstadoGrabacion and EstadoRadio defaulted `esPremium` to
`() => true`, so any construction site that forgot to wire entitlement
compiled fine and silently ran ungated — failing OPEN to premium and
disabling the paywall with no test able to catch it.

The parameter is now required with no default. Production wiring in
app.dart was already correct and is unchanged; the 184 pre-existing test
call sites now pass `() => true` explicitly, which is exactly the old
implicit default, so every assertion is untouched.

EstadoRadio has no gate of its own but constructs EstadoGrabacion, so it
inherits the same contract.

The one test that existed to pin the old default is renamed to describe
what it still covers (the premium path through iniciar() with no
duracion); its assertions are unchanged.
2026-08-10 22:06:36 +02:00

131 lines
3.6 KiB
Dart

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(esPremium: () => true, 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<void>.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(
esPremium: () => true,
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 = <String>[];
final estado = EstadoGrabacion(
esPremium: () => true,
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 = <String>[];
final estado = EstadoGrabacion(
servicio: servicio,
alError: errores.add,
esPremium: () => true,
);
addTearDown(estado.dispose);
servicio.emitir(
const EstadoGrabacionRadio(
tipo: EstadoGrabacionRadioTipo.error,
error: 'HTTP 500',
),
);
await Future<void>.delayed(Duration.zero);
expect(errores, hasLength(1));
expect(errores.single, contains('HTTP 500'));
});
}
class _ServicioGrabacionControlado extends ServicioGrabacionRadio {
final _controller = StreamController<EstadoGrabacionRadio>.broadcast();
EstadoGrabacionRadio _estadoActual = const EstadoGrabacionRadio.inactiva();
int inicios = 0;
Emisora? emisoraIniciada;
Duration? duracionIniciada;
@override
EstadoGrabacionRadio get estado => _estadoActual;
@override
Stream<EstadoGrabacionRadio> get estadoStream => _controller.stream;
@override
Future<void> inicializar() async {}
@override
Future<void> iniciar(
Emisora emisora, {
Duration? duracion,
String? directorio,
}) async {
inicios++;
emisoraIniciada = emisora;
duracionIniciada = duracion;
}
void emitir(EstadoGrabacionRadio estado) {
_estadoActual = estado;
_controller.add(estado);
}
@override
Future<void> dispose() => _controller.close();
}