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.
This commit is contained in:
2026-08-10 22:06:36 +02:00
parent aa0b242374
commit d81fabbe27
59 changed files with 215 additions and 23 deletions
@@ -46,6 +46,7 @@ void main() {
var ahora = DateTime(2026, 8, 3, 16, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -151,6 +152,7 @@ void main() {
var ahora = DateTime(2026, 8, 3, 9, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -17,6 +17,7 @@ void main() {
EstadoAlarmas crearEstado(FakePuertoAlarmasAndroid android) {
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(),
android: android,
iniciarAutomaticamente: false,
@@ -31,8 +31,11 @@ void main() {
android = FakePuertoAlarmasAndroid();
});
EstadoAlarmas crearEstado() =>
EstadoAlarmas(android: android, iniciarAutomaticamente: false);
EstadoAlarmas crearEstado() => EstadoAlarmas(
android: android,
iniciarAutomaticamente: false,
esPremium: () => true,
);
/// Mirrors exactly what the native side puts on the channel.
FalloProgramacionNativo falloNativo(String alarmaId, String tipo) =>
+4 -5
View File
@@ -8,11 +8,10 @@ import '../helpers/fakes_alarmas.dart';
/// Freemium gating (freemium-gating spec, design ADR-3/ADR-5): the 5-alarm
/// cap for free-tier users, grandfathering of pre-existing alarms, and the
/// full premium gate on vacation-range creation. `EstadoAlarmas`'s existing
/// suite constructs it with NO `esPremium` callback and expects unrestricted
/// behavior — the default therefore stays `() => true` (ungated) so every
/// one of those tests keeps passing unchanged; only tests here explicitly
/// inject `esPremium: () => false` to exercise the free tier.
/// full premium gate on vacation-range creation. `esPremium` is a REQUIRED
/// constructor parameter with no default — every other suite passes
/// `() => true` explicitly to keep its pre-gate behavior, and the tests here
/// inject `() => false` to exercise the free tier.
AlarmaMusical _alarma(String id, {bool activa = true}) => AlarmaMusical(
id: id,
nombre: 'Alarma $id',
@@ -41,6 +41,7 @@ void main() {
) {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: reloj),
android: android,
iniciarAutomaticamente: false,
@@ -36,6 +36,7 @@ void main() {
var ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -74,6 +75,7 @@ void main() {
final android = FakePuertoAlarmasAndroid();
final servicio = ServicioAlarmas(reloj: () => ahora);
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: servicio,
android: android,
iniciarAutomaticamente: false,
@@ -113,6 +115,7 @@ void main() {
var ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -139,6 +142,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -182,6 +186,7 @@ void main() {
var ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -231,6 +236,7 @@ void main() {
),
);
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: servicio,
android: android,
iniciarAutomaticamente: false,
@@ -250,6 +256,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -274,6 +281,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 36);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -307,6 +315,7 @@ void main() {
var ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -337,6 +346,7 @@ void main() {
var ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -363,6 +373,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -393,6 +404,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 0);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -423,6 +435,7 @@ void main() {
final ahora = DateTime(2026, 6, 11, 7, 32);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
+27
View File
@@ -20,6 +20,7 @@ void main() {
var ahora = DateTime(2026, 5, 25, 7, 31);
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => ahora),
android: android,
iniciarAutomaticamente: false,
@@ -63,6 +64,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -100,6 +102,7 @@ void main() {
test('finalizar diaria calcula siguiente dia y limpia snooze', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -132,6 +135,7 @@ void main() {
test('finalizar unica la desactiva y queda sin proxima ejecucion', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -163,6 +167,7 @@ void main() {
final android =
FakePuertoAlarmasAndroid()..ignoraOptimizacionBateria = false;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -201,6 +206,7 @@ void main() {
test('no solicita exencion de bateria cuando ya esta exenta', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -227,6 +233,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -256,6 +263,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -284,6 +292,7 @@ void main() {
'(SS-1c, guardia de regresion)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -312,6 +321,7 @@ void main() {
'falla (fail-toward-silence, regresion de eliminarAlarma)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -342,6 +352,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -371,6 +382,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -410,6 +422,7 @@ void main() {
'(SS-2a)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -438,6 +451,7 @@ void main() {
'(SS-2b)', () async {
final android = FakePuertoAlarmasAndroid()..fallaDetener = true;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -464,6 +478,7 @@ void main() {
'exito (SS-3b)', () async {
final android = FakePuertoAlarmasAndroid()..fallaDetener = true;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -495,6 +510,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid()..fallaDetener = true;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -522,6 +538,7 @@ void main() {
test('evento nativo missed completa la ejecucion (Phase 6)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7, 31)),
android: android,
iniciarAutomaticamente: false,
@@ -587,6 +604,7 @@ void main() {
);
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: servicio,
android: android,
iniciarAutomaticamente: false,
@@ -617,6 +635,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid()..fallaProgramar = true;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -647,6 +666,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid()..fallaProgramar = true;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -676,6 +696,7 @@ void main() {
() async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -730,6 +751,7 @@ void main() {
);
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: servicio,
android: android,
iniciarAutomaticamente: false,
@@ -756,6 +778,7 @@ void main() {
'calza (fixed ahora)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 7, 10)),
android: android,
iniciarAutomaticamente: false,
@@ -783,6 +806,7 @@ void main() {
'ambas son disjuntas del rango activo', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 7, 10)),
android: android,
iniciarAutomaticamente: false,
@@ -838,6 +862,7 @@ void main() {
'(servicio_programacion_alarmas.dart)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 7, 10)),
android: android,
iniciarAutomaticamente: false,
@@ -894,6 +919,7 @@ void main() {
'no afectadas', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 7, 10)),
android: android,
iniciarAutomaticamente: false,
@@ -930,6 +956,7 @@ void main() {
'pureza — son solo lectura sobre _alarmas/_vacaciones)', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 7, 10)),
android: android,
iniciarAutomaticamente: false,
@@ -25,6 +25,7 @@ void main() {
// actually persisting the registration.
final android = FakePuertoAlarmasAndroid()..alarmasNativasPendientes = 0;
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -53,6 +54,7 @@ void main() {
'fallo alguno', () async {
final android = FakePuertoAlarmasAndroid();
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 5, 25, 7)),
android: android,
iniciarAutomaticamente: false,
@@ -118,6 +120,7 @@ void main() {
);
final estado = EstadoAlarmas(
esPremium: () => true,
servicio: servicio,
android: android,
iniciarAutomaticamente: false,
+1
View File
@@ -33,6 +33,7 @@ void main() {
test('EQ preset change does NOT rebuild EstadoRadio listeners '
'(S4-R1-A, S4-R5)', () async {
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -49,10 +49,14 @@ void main() {
expect(servicio.inicios, 1);
});
test('sin callback de entitlement, el default no bloquea (compat)', () async {
// `esPremium` is a required parameter, so "no entitlement callback" is no
// longer a reachable state to test; what stays worth covering is the
// premium path through `iniciar()` with no explicit `duracion`.
test('premium: iniciar() sin duracion tambien delega', () async {
final servicio = _ServicioGrabacionControlado();
final emisora = emisoraDemo(uuid: 'rec-3', nombre: 'Grabable');
final estado = EstadoGrabacion(
esPremium: () => true,
servicio: servicio,
emisoraActual: () => emisora,
);
+8 -2
View File
@@ -12,7 +12,7 @@ import '../helpers/fakes.dart';
void main() {
test('notifica listeners cuando cambia el estado de grabación', () async {
final servicio = _ServicioGrabacionControlado();
final estado = EstadoGrabacion(servicio: servicio);
final estado = EstadoGrabacion(esPremium: () => true, servicio: servicio);
addTearDown(estado.dispose);
var notificaciones = 0;
@@ -36,6 +36,7 @@ void main() {
final servicio = _ServicioGrabacionControlado();
final emisora = emisoraDemo(uuid: 'rec-2', nombre: 'Actual');
final estado = EstadoGrabacion(
esPremium: () => true,
servicio: servicio,
emisoraActual: () => emisora,
);
@@ -54,6 +55,7 @@ void main() {
final servicio = _ServicioGrabacionControlado();
final errores = <String>[];
final estado = EstadoGrabacion(
esPremium: () => true,
servicio: servicio,
emisoraActual: () => null,
alError: errores.add,
@@ -70,7 +72,11 @@ void main() {
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);
final estado = EstadoGrabacion(
servicio: servicio,
alError: errores.add,
esPremium: () => true,
);
addTearDown(estado.dispose);
servicio.emitir(
+31
View File
@@ -26,6 +26,7 @@ void main() {
emisoraDemo(uuid: 'custom-1', nombre: 'Custom Uno'),
]);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(
@@ -51,6 +52,7 @@ void main() {
final principal = PresetEcualizador.rock;
final emisora = emisoraDemo(uuid: 'api-1', nombre: 'API Uno');
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(populares: [emisora]),
@@ -74,6 +76,7 @@ void main() {
final principal = PresetEcualizador.jazz;
final porEmisora = {'fav-1': PresetEcualizador.rock};
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(ecualizadorActivo: false),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -112,6 +115,7 @@ void main() {
],
);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: radio,
@@ -143,6 +147,7 @@ void main() {
await favoritos.agregar(emisora);
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: favoritos,
radio: FakeServicioRadio(populares: [emisora]),
@@ -176,6 +181,7 @@ void main() {
await favoritos.agregar(emisora);
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: favoritos,
radio: FakeServicioRadio(populares: [emisora]),
@@ -200,6 +206,7 @@ void main() {
final audio = FakeServicioAudio();
final servicioEcualizador = FakeServicioEcualizador();
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -229,6 +236,7 @@ void main() {
final audio = FakeServicioAudio();
final emisora = emisoraDemo(uuid: 'play-1', nombre: 'Primera');
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(populares: [emisora]),
@@ -254,6 +262,7 @@ void main() {
final audio = FakeServicioAudio();
final emisora = emisoraDemo(uuid: 'same-1', nombre: 'Misma');
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(populares: [emisora]),
@@ -278,6 +287,7 @@ void main() {
final primera = emisoraDemo(uuid: 'slow-1', nombre: 'Lenta');
final segunda = emisoraDemo(uuid: 'fast-2', nombre: 'Rapida');
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: radio,
@@ -328,6 +338,7 @@ void main() {
final favoritos = FakeServicioFavoritos();
final emisora = emisoraDemo(uuid: 'fav-sync', nombre: 'Sync');
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: favoritos,
radio: FakeServicioRadio(populares: [emisora]),
@@ -351,6 +362,7 @@ void main() {
final emisora = emisoraDemo(uuid: 'fav-group', nombre: 'Grupo');
await favoritos.agregar(emisora);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: favoritos,
radio: FakeServicioRadio(populares: [emisora]),
@@ -383,6 +395,7 @@ void main() {
'popularidad persiste y sobrevive a una nueva instancia (reinicio)',
() async {
final estadoUno = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -398,6 +411,7 @@ void main() {
// Fresh instance, same (mocked) SharedPreferences-backed store —
// simulates an app restart re-reading the persisted preference.
final estadoDos = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -427,6 +441,7 @@ void main() {
]),
);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -447,6 +462,7 @@ void main() {
test('si resolver la ruta del archivo custom falla, la inicializacion '
'sobrevive y las cargas hermanas no se pierden (D5 IO-fail)', () async {
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -469,6 +485,7 @@ void main() {
'original (D5 parse-fail)', () async {
final archivo = await _crearArchivoCustomRaw('{bad');
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -490,6 +507,7 @@ void main() {
'toca el sidecar (D5, autoridad de escritura restaurada)', () async {
final archivo = await _crearArchivoCustomRaw('{bad');
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -521,6 +539,7 @@ void main() {
throw const FileSystemException('fallo simulado de lectura'),
);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -547,6 +566,7 @@ void main() {
await sidecar.writeAsString('contenido-previo-X');
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -573,6 +593,7 @@ void main() {
]);
final emisoraFav = emisoraDemo(uuid: 'fav-auto-1', nombre: 'Fav Auto');
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(
@@ -624,6 +645,7 @@ void main() {
);
final fuenteAuto = _FuenteEmisorasAutoEspia();
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: favoritosServicio,
radio: FakeServicioRadio(),
@@ -651,6 +673,7 @@ void main() {
});
final fuenteAuto = _FuenteEmisorasAutoEspia();
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(
@@ -684,6 +707,7 @@ void main() {
]);
final fuenteAuto = _FuenteEmisorasAutoEspia();
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -710,6 +734,7 @@ void main() {
]);
final fuenteAuto = _FuenteEmisorasAutoEspia();
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(
@@ -741,6 +766,7 @@ void main() {
'el auto (no via reproducir())', () async {
final audio = _AudioControlado();
final estado = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -767,6 +793,7 @@ void main() {
'reproduce, sólo queda seleccionada', () async {
final emisora = emisoraDemo(uuid: 'last-1', nombre: 'Ultima FM');
final estadoUno = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -783,6 +810,7 @@ void main() {
final audioDos = FakeServicioAudio();
final estadoDos = EstadoRadio(
esPremium: () => true,
audio: audioDos,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -805,6 +833,7 @@ void main() {
test('sin ninguna emisora previamente reproducida, emisoraActual sigue '
'siendo null tras inicializar (instalación nueva)', () async {
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -822,6 +851,7 @@ void main() {
'también se recuerda para la próxima instancia', () async {
final audio = _AudioControlado();
final estadoUno = EstadoRadio(
esPremium: () => true,
audio: audio,
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
@@ -838,6 +868,7 @@ void main() {
await Future<void>.delayed(Duration.zero);
final estadoDos = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),