Files
pluriwave/test/pantallas/pantalla_inicio_rebuild_test.dart
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

113 lines
4.4 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pluriwave/estado/estado_busqueda.dart';
import 'package:pluriwave/estado/estado_ecualizador.dart';
import 'package:pluriwave/estado/estado_grabacion.dart';
import 'package:pluriwave/estado/estado_radio.dart';
import 'package:pluriwave/l10n/gen/app_localizations.dart';
import 'package:pluriwave/modelos/preset_ecualizador.dart';
import 'package:pluriwave/pantallas/pantalla_inicio.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../helpers/fakes.dart';
/// S4-R5-A: changing the EQ preset must NOT rebuild PantallaInicio.
void main() {
setUp(() {
SharedPreferences.setMockInitialValues({});
});
testWidgets('cambiar el preset de EQ no marca PantallaInicio para rebuild', (
tester,
) async {
tester.view.physicalSize = const Size(1440, 3200);
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final radio = FakeServicioRadio(
populares: [emisoraDemo(uuid: 'api-1', nombre: 'API Uno')],
popularesPorLlamada: [
[emisoraDemo(uuid: 'api-1', nombre: 'API Uno')],
[emisoraDemo(uuid: 'api-2', nombre: 'API Dos')],
],
);
final estado = EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: radio,
servicioEcualizador: FakeServicioEcualizador(),
resolverArchivoCustom:
() async => File(
'${Directory.current.path}/test/fixtures/emisoras_custom_vacio.json',
),
iniciarAutomaticamente: false,
);
addTearDown(estado.dispose);
await tester.runAsync(estado.inicializar);
await tester.pumpWidget(
MultiProvider(
providers: [
ChangeNotifierProvider<EstadoRadio>.value(value: estado),
ListenableProvider<EstadoEcualizador>.value(
value: estado.ecualizador,
),
ListenableProvider<EstadoBusqueda>.value(value: estado.busqueda),
ListenableProvider<EstadoGrabacion>.value(value: estado.grabacion),
],
child: MaterialApp(
locale: const Locale('es'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const Scaffold(body: PantallaInicio()),
),
),
);
await tester.pumpAndSettle(const Duration(milliseconds: 100));
// Provider defers dependent notification to the next build phase, so a
// dirty-flag probe cannot observe it synchronously. Instead, log every
// element rebuilt per frame and look for the screen in that log.
final registro = <String>[];
final debugPrintOriginal = debugPrint;
debugPrintRebuildDirtyWidgets = true;
debugPrint = (String? message, {int? wrapWidth}) {
registro.add(message ?? '');
};
addTearDown(() {
debugPrintRebuildDirtyWidgets = false;
debugPrint = debugPrintOriginal;
});
// EQ preset change: a different notifier — must NOT rebuild the screen.
await estado.ecualizador.cambiarPresetPrincipal(PresetEcualizador.rock);
await tester.pump();
expect(registro.any((linea) => linea.contains('PantallaInicio')), isFalse);
// Probe control: a real data change DOES rebuild the screen.
//
// WU6 correction: this used to be `estado.cargarPopulares()`, which
// notifies `emisorasInicio`/`cargandoPopulares` — fields the removed
// discovery grid (`_gridEmisoras`) used to read. Task 6.5 relocated
// that grid to `PantallaBuscar` and deleted it here, so
// `PantallaInicio` no longer selects either field; `cargarPopulares()`
// would silently turn this probe into a false negative instead of a
// real control. Toggling a favorite is the correct replacement — the
// remaining "Tus emisoras" section (`_seccionTusEmisoras`) selects
// `listaFavoritos` directly.
registro.clear();
final emisoraProbe = emisoraDemo(uuid: 'probe-1', nombre: 'Probe Uno');
await tester.runAsync(() => estado.toggleFavorito(emisoraProbe));
await tester.pump();
expect(registro.any((linea) => linea.contains('PantallaInicio')), isTrue);
debugPrintRebuildDirtyWidgets = false;
debugPrint = debugPrintOriginal;
await tester.pumpAndSettle(const Duration(milliseconds: 100));
});
}