import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/estado/estado_navegacion.dart'; import 'package:pluriwave/l10n/gen/app_localizations.dart'; import 'package:pluriwave/pantallas/pantalla_bienvenida.dart'; import 'package:provider/provider.dart'; /// WU17: `onboarding-welcome` spec — full-screen route (not a modal), /// content only (logo/headline/body/3 bullets/1 CTA), binding /// no-monetization guard, and CTA dismisses to Escuchar with the route /// popped. Widget _app({required EstadoNavegacionRaiz navegacion}) { return ChangeNotifierProvider.value( value: navegacion, child: const MaterialApp( locale: Locale('es'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: PantallaBienvenida(), ), ); } void main() { testWidgets( 'renders as a full-screen route with a logo, headline, body copy, ' 'exactly 3 feature bullets, and exactly one primary CTA', (tester) async { final navegacion = EstadoNavegacionRaiz(); addTearDown(navegacion.dispose); await tester.pumpWidget(_app(navegacion: navegacion)); await tester.pumpAndSettle(); // A full-screen route, never a modal dialog. expect(find.byType(Dialog), findsNothing); expect(find.byType(AlertDialog), findsNothing); expect(find.byType(Scaffold), findsOneWidget); expect(find.byType(Image), findsOneWidget, reason: 'the logo mark'); expect(find.text('Tu mundo, en directo'), findsOneWidget); expect( find.textContaining('53.412 emisoras de 238 países'), findsOneWidget, ); expect( find.byType(FilaCaracteristicaBienvenida), findsNWidgets(3), reason: 'exactly 3 feature bullets', ); expect( find.byType(FilledButton), findsOneWidget, reason: 'exactly 1 primary CTA', ); expect(find.text('Empezar a escuchar'), findsOneWidget); }, ); testWidgets('rendered content contains no monetization strings', ( tester, ) async { final navegacion = EstadoNavegacionRaiz(); addTearDown(navegacion.dispose); await tester.pumpWidget(_app(navegacion: navegacion)); await tester.pumpAndSettle(); final textoCompleto = tester .widgetList(find.byType(Text)) .map((widget) => widget.data ?? '') .join('\n'); expect(textoCompleto.contains('PRO'), isFalse); expect(textoCompleto.contains('€'), isFalse); expect(textoCompleto.contains(r'$'), isFalse); expect( RegExp(r'\d+\s*d[ií]as?\b', caseSensitive: false).hasMatch( textoCompleto, ), isFalse, reason: 'no day-count trial phrase (e.g. "14 días")', ); expect( find.textContaining('gratuita', findRichText: true), findsNothing, reason: 'no secondary "free version" link', ); expect( find.textContaining('gratis', findRichText: true), findsNothing, reason: 'no secondary "free version" link', ); // Only one tappable action on the whole screen: the primary CTA. expect(find.byType(TextButton), findsNothing); expect(find.byType(FilledButton), findsOneWidget); }); testWidgets( 'tapping the primary CTA switches to Escuchar and pops the welcome route', (tester) async { // Start on a DIFFERENT tab so a pass actually proves irA() ran, // rather than coasting on EstadoNavegacionRaiz's own escuchar default. final navegacion = EstadoNavegacionRaiz() ..irA(RaizPluriWave.ajustes); addTearDown(navegacion.dispose); final navigatorKey = GlobalKey(); await tester.pumpWidget( ChangeNotifierProvider.value( value: navegacion, child: MaterialApp( navigatorKey: navigatorKey, locale: const Locale('es'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const Scaffold(body: Center(child: Text('home stand-in'))), ), ), ); unawaited( navigatorKey.currentState!.push( MaterialPageRoute(builder: (_) => const PantallaBienvenida()), ), ); await tester.pumpAndSettle(); expect(find.byType(PantallaBienvenida), findsOneWidget); await tester.tap(find.text('Empezar a escuchar')); await tester.pumpAndSettle(); expect(navegacion.actual, RaizPluriWave.escuchar); expect( find.byType(PantallaBienvenida), findsNothing, reason: 'the welcome route was removed from the back stack', ); expect(find.text('home stand-in'), findsOneWidget); }, ); }