Files
pluriwave/test/pantallas/ajustes/pantalla_ajustes_backup_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

111 lines
3.9 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pluriwave/estado/estado_radio.dart';
import 'package:pluriwave/l10n/gen/app_localizations.dart';
import 'package:pluriwave/pantallas/ajustes/pantalla_ajustes_backup.dart';
import 'package:pluriwave/widgets/pluri_push_scaffold.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../helpers/fakes.dart';
import '../../helpers/fakes_alarmas.dart';
/// Pre-existing project constraint (see `pantalla_ajustes_test.dart`):
/// PluriGlassSurface paints a background over ListTile's ink layer, which
/// Flutter flags as a warning-level assertion, not a correctness bug.
void _suppressListTileInkAssertion() {
final original = FlutterError.onError;
FlutterError.onError = (details) {
if (details.exceptionAsString().contains(
'ListTile background color or ink splashes may be invisible',
)) {
return;
}
original?.call(details);
};
addTearDown(() => FlutterError.onError = original);
}
/// WU3b task 3b.1: the APLICACIÓN detail screen for "Copia de seguridad"
/// renders inside a [PluriPushScaffold] and its moved controls (export /
/// import rows) are still present and reachable exactly as they were inside
/// the old `_SeccionBackup`.
///
/// Both rows call into native plugins (`share_plus`, `file_picker`) that
/// this suite does not mock, so this file verifies reachability (title and
/// both row labels present, with a live `onTap`) rather than tapping through
/// the native share/pick flow — the same conservative choice this batch
/// makes for any moved control that would otherwise depend on an unmocked
/// platform channel.
void main() {
setUp(() {
SharedPreferences.setMockInitialValues({});
});
Future<File> archivoCustomVacio() async => File(
'${Directory.current.path}/test/fixtures/emisoras_custom_vacio.json',
);
Future<EstadoRadio> crearEstado() async {
return EstadoRadio(
esPremium: () => true,
audio: FakeServicioAudio(),
favoritos: FakeServicioFavoritos(),
radio: FakeServicioRadio(),
servicioEcualizador: FakeServicioEcualizador(),
servicioGrabacion: FakeServicioGrabacionRadioInactiva(),
resolverArchivoCustom: archivoCustomVacio,
iniciarAutomaticamente: false,
);
}
Widget buildScreen(EstadoRadio estado) {
return ChangeNotifierProvider<EstadoRadio>.value(
value: estado,
child: MaterialApp(
locale: const Locale('en'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const PantallaAjustesBackup(),
),
);
}
testWidgets('renders inside a PluriPushScaffold titled "Backup"', (
tester,
) async {
_suppressListTileInkAssertion();
final estado = await crearEstado();
addTearDown(estado.dispose);
await tester.pumpWidget(buildScreen(estado));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(find.byType(PluriPushScaffold), findsOneWidget);
expect(find.text('Backup'), findsOneWidget);
});
testWidgets(
'moved controls still reachable: export and import rows both present',
(tester) async {
_suppressListTileInkAssertion();
final estado = await crearEstado();
addTearDown(estado.dispose);
await tester.pumpWidget(buildScreen(estado));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
final exportTile = find.widgetWithText(ListTile, 'Export configuration');
final importTile = find.widgetWithText(ListTile, 'Import configuration');
expect(exportTile, findsOneWidget);
expect(importTile, findsOneWidget);
expect(tester.widget<ListTile>(exportTile).onTap, isNotNull);
expect(tester.widget<ListTile>(importTile).onTap, isNotNull);
},
);
}