import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/estado/estado_entitlement.dart'; import 'package:pluriwave/l10n/gen/app_localizations.dart'; import 'package:pluriwave/servicios/servicio_compras.dart'; import 'package:pluriwave/widgets/hoja_premium.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// Fake [PuertoCompras] (mirrors `app_test.dart`'s own fake): lets a test /// drive [EstadoEntitlement]'s purchase-stream events without touching /// `in_app_purchase`. class _PuertoComprasFalso implements PuertoCompras { final _eventos = StreamController.broadcast(); @override Stream get eventos => _eventos.stream; @override Future comprar() async {} @override Future restaurar() async {} void emitir(EventoCompra evento) => _eventos.add(evento); Future dispose() => _eventos.close(); } /// FIX 3 / FIX 9 (code review): the paywall must show localized feedback for /// a failed purchase/restore, a distinct non-error confirmation when a /// restore finds nothing, and its own dedicated "premium active" string /// instead of reusing the equalizer's `equalizerActive` translation. void main() { setUp(() { SharedPreferences.setMockInitialValues({}); }); late AppLocalizations l10n; Future bombear( WidgetTester tester, { required _PuertoComprasFalso compras, }) async { late EstadoEntitlement estado; await tester.pumpWidget( MultiProvider( providers: [ ChangeNotifierProvider( create: (_) { estado = EstadoEntitlement(prefs: null, compras: compras); return estado; }, ), ], child: MaterialApp( locale: const Locale('es'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const Scaffold(body: HojaPremium()), ), ), ); await tester.pump(); l10n = AppLocalizations.of(tester.element(find.byType(HojaPremium))); return estado; } group( 'FIX 9 — la etiqueta de premium activo es propia, no la del ecualizador', () { testWidgets( 'usuario premium: muestra l10n.premiumActivo, nunca l10n.equalizerActive', (tester) async { SharedPreferences.setMockInitialValues({'compra_premium_v1': true}); final compras = _PuertoComprasFalso(); addTearDown(compras.dispose); await bombear(tester, compras: compras); await tester.pump(); expect(find.text(l10n.premiumActivo), findsOneWidget); expect(find.text(l10n.equalizerActive), findsNothing); }, ); }, ); group('FIX 3 — feedback de error/restauración en el paywall', () { testWidgets('un error de compra muestra el mensaje localizado genérico ' '(l10n.compraError), nunca el texto interno de EventoCompra.mensaje', ( tester, ) async { final compras = _PuertoComprasFalso(); addTearDown(compras.dispose); await bombear(tester, compras: compras); compras.emitir( const EventoCompra( TipoEventoCompra.error, mensaje: 'Producto no encontrado en Play Console', ), ); await tester.pump(); await tester.pump(); expect(find.text(l10n.compraError), findsOneWidget); expect(find.text('Producto no encontrado en Play Console'), findsNothing); }); testWidgets('una restauración sin compras muestra su propia confirmación ' '(l10n.restauracionSinCompras), distinta del mensaje de error', ( tester, ) async { final compras = _PuertoComprasFalso(); addTearDown(compras.dispose); await bombear(tester, compras: compras); compras.emitir(const EventoCompra(TipoEventoCompra.noEncontrada)); await tester.pump(); await tester.pump(); expect(find.text(l10n.restauracionSinCompras), findsOneWidget); expect(find.text(l10n.compraError), findsNothing); }); testWidgets( 'descartar el mensaje de error llama a consumirResultadoUsuario() y ' 'lo oculta de la UI', (tester) async { final compras = _PuertoComprasFalso(); addTearDown(compras.dispose); final estado = await bombear(tester, compras: compras); compras.emitir(const EventoCompra(TipoEventoCompra.error)); await tester.pump(); await tester.pump(); expect(find.text(l10n.compraError), findsOneWidget); await tester.tap( find.byKey(const ValueKey('hoja-premium-resultado-descartar')), ); await tester.pump(); expect(find.text(l10n.compraError), findsNothing); expect(estado.resultadoUsuario, isNull); }, ); }); }