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.
159 lines
5.0 KiB
Dart
159 lines
5.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:pluriwave/estado/estado_alarmas.dart';
|
|
import 'package:pluriwave/estado/estado_radio.dart';
|
|
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
|
import 'package:pluriwave/modelos/alarma_musical.dart';
|
|
import 'package:pluriwave/pantallas/pantalla_alarmas.dart';
|
|
import 'package:pluriwave/pantallas/pantalla_diagnostico_alarmas.dart';
|
|
import 'package:pluriwave/servicios/servicio_alarmas.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../helpers/fakes.dart';
|
|
import '../helpers/fakes_alarmas.dart';
|
|
|
|
/// Card-level visibility for a failed scheduling attempt (fix/alarmas-
|
|
/// fallos-silenciosos): before this, `ultimaExcepcionPara` existed but was
|
|
/// never read from any screen, so a failed alarm rendered exactly like a
|
|
/// working one -- switched on, no visible sign anything was wrong.
|
|
void main() {
|
|
setUp(() {
|
|
SharedPreferences.setMockInitialValues({});
|
|
});
|
|
|
|
Future<void> montarPantalla(
|
|
WidgetTester tester,
|
|
EstadoAlarmas estadoAlarmas,
|
|
) async {
|
|
tester.view.physicalSize = const Size(1440, 3200);
|
|
tester.view.devicePixelRatio = 1.0;
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
addTearDown(tester.view.resetDevicePixelRatio);
|
|
|
|
final radio = EstadoRadio(
|
|
esPremium: () => true,
|
|
audio: FakeServicioAudio(),
|
|
favoritos: FakeServicioFavoritos(),
|
|
radio: FakeServicioRadio(),
|
|
servicioEcualizador: FakeServicioEcualizador(),
|
|
servicioGrabacion: FakeServicioGrabacionRadioInactiva(),
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(radio.dispose);
|
|
|
|
await tester.pumpWidget(
|
|
MultiProvider(
|
|
providers: [
|
|
ChangeNotifierProvider<EstadoRadio>.value(value: radio),
|
|
ChangeNotifierProvider<EstadoAlarmas>.value(value: estadoAlarmas),
|
|
],
|
|
child: MaterialApp(
|
|
locale: const Locale('es'),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: const Scaffold(body: PantallaAlarmas()),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
}
|
|
|
|
testWidgets(
|
|
'una alarma cuya programacion fallo muestra un aviso en su tarjeta',
|
|
(tester) async {
|
|
final android = FakePuertoAlarmasAndroid()..fallaProgramar = true;
|
|
final estadoAlarmas = EstadoAlarmas(
|
|
esPremium: () => true,
|
|
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 6, 1, 6, 0)),
|
|
android: android,
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(estadoAlarmas.dispose);
|
|
addTearDown(android.dispose);
|
|
await estadoAlarmas.guardarAlarma(
|
|
const AlarmaMusical(
|
|
id: 'r1',
|
|
nombre: 'Rota',
|
|
hora: 7,
|
|
minuto: 0,
|
|
tipoProgramacion: TipoProgramacionAlarma.diaria,
|
|
diasSemana: [],
|
|
),
|
|
);
|
|
|
|
await montarPantalla(tester, estadoAlarmas);
|
|
|
|
expect(
|
|
find.byKey(const ValueKey('tarjeta-alarma-fallo-r1')),
|
|
findsOneWidget,
|
|
);
|
|
},
|
|
);
|
|
|
|
testWidgets(
|
|
'una alarma programada correctamente NO muestra el aviso de fallo',
|
|
(tester) async {
|
|
final android = FakePuertoAlarmasAndroid();
|
|
final estadoAlarmas = EstadoAlarmas(
|
|
esPremium: () => true,
|
|
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 6, 1, 6, 0)),
|
|
android: android,
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(estadoAlarmas.dispose);
|
|
addTearDown(android.dispose);
|
|
await estadoAlarmas.guardarAlarma(
|
|
const AlarmaMusical(
|
|
id: 'ok1',
|
|
nombre: 'Sana',
|
|
hora: 7,
|
|
minuto: 0,
|
|
tipoProgramacion: TipoProgramacionAlarma.diaria,
|
|
diasSemana: [],
|
|
),
|
|
);
|
|
|
|
await montarPantalla(tester, estadoAlarmas);
|
|
|
|
expect(
|
|
find.byKey(const ValueKey('tarjeta-alarma-fallo-ok1')),
|
|
findsNothing,
|
|
);
|
|
},
|
|
);
|
|
|
|
testWidgets('el aviso de fallo abre la pantalla de diagnostico al tocarlo', (
|
|
tester,
|
|
) async {
|
|
final android = FakePuertoAlarmasAndroid()..fallaProgramar = true;
|
|
final estadoAlarmas = EstadoAlarmas(
|
|
esPremium: () => true,
|
|
servicio: ServicioAlarmas(reloj: () => DateTime(2026, 6, 1, 6, 0)),
|
|
android: android,
|
|
iniciarAutomaticamente: false,
|
|
);
|
|
addTearDown(estadoAlarmas.dispose);
|
|
addTearDown(android.dispose);
|
|
await estadoAlarmas.guardarAlarma(
|
|
const AlarmaMusical(
|
|
id: 'r1',
|
|
nombre: 'Rota',
|
|
hora: 7,
|
|
minuto: 0,
|
|
tipoProgramacion: TipoProgramacionAlarma.diaria,
|
|
diasSemana: [],
|
|
),
|
|
);
|
|
|
|
await montarPantalla(tester, estadoAlarmas);
|
|
|
|
await tester.tap(find.byKey(const ValueKey('tarjeta-alarma-fallo-r1')));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
|
|
expect(find.byType(PantallaDiagnosticoAlarmas), findsOneWidget);
|
|
});
|
|
}
|