import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/estado/estado_busqueda.dart'; import 'package:pluriwave/l10n/gen/app_localizations.dart'; import 'package:pluriwave/modelos/pais_radio.dart'; import 'package:pluriwave/pantallas/pantalla_paises.dart'; import 'package:pluriwave/widgets/pluri_push_scaffold.dart'; import 'package:provider/provider.dart'; import '../helpers/fakes.dart'; /// WU7, `station-discovery-browse` spec — "Países Browser Over the Verified /// Countries Contract": "Tus idiomas" shortlist + the full alphabetical /// list, each entry showing its station count. `stationcount`'s "arrives as /// a JSON string" edge case is covered at its own layer boundary in /// `test/modelos/pais_radio_test.dart` — `FakeServicioRadio.obtenerPaises()` /// returns already-parsed `PaisRadio` instances here, so this file tests /// rendering only, not JSON parsing. void main() { Widget buildScreen(EstadoBusqueda estado) { return ChangeNotifierProvider.value( value: estado, child: MaterialApp( locale: const Locale('es'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const PantallaPaises(), ), ); } Future pumpEstable(WidgetTester tester) async { await tester.pump(); await tester.pumpAndSettle(); } testWidgets( 'renders inside a PluriPushScaffold; muestra "Tus idiomas" y la lista ' 'alfabética completa con el conteo de cada país', (tester) async { final estado = EstadoBusqueda( radio: FakeServicioRadio( paises: const [ PaisRadio(nombre: 'Spain', codigoIso: 'ES', numeroEmisoras: 482), PaisRadio( nombre: 'Argentina', codigoIso: 'AR', numeroEmisoras: 120, ), PaisRadio(nombre: 'France', codigoIso: 'FR', numeroEmisoras: 75), ], ), ); addTearDown(estado.dispose); await tester.pumpWidget(buildScreen(estado)); await pumpEstable(tester); expect(find.byType(PluriPushScaffold), findsOneWidget); final l10n = AppLocalizations.of( tester.element(find.byType(PantallaPaises)), ); expect(find.text(l10n.countriesYourLanguagesTitle), findsOneWidget); expect(find.text(l10n.countriesAllTitle), findsOneWidget); // Full alphabetical list: all 3 fetched countries render. expect(find.text('Argentina'), findsOneWidget); expect(find.text('France'), findsOneWidget); // 'Spain' renders twice: "Tus idiomas" (locale es -> representative // country ES) AND the full list below. expect(find.text('Spain'), findsWidgets); // Each entry's parsed `stationcount` renders via the existing // `stationsCount` string — 482 came from the API as a STRING // (`PaisRadio.fromApi`'s job, verified separately) and must display // as a plain number here, never throwing a cast error. expect(find.text(l10n.stationsCount(482)), findsWidgets); expect(find.text(l10n.stationsCount(120)), findsOneWidget); expect(find.text(l10n.stationsCount(75)), findsOneWidget); }, ); testWidgets( 'cargarPaises no se re-dispara si ya hay datos en caché al reconstruir', (tester) async { final radio = FakeServicioRadio( paises: const [ PaisRadio(nombre: 'Italy', codigoIso: 'IT', numeroEmisoras: 30), ], ); final estado = EstadoBusqueda(radio: radio); addTearDown(estado.dispose); await tester.pumpWidget(buildScreen(estado)); await pumpEstable(tester); expect(radio.obtenerPaisesCalls, 1); // Re-entering the screen (a fresh State, same EstadoBusqueda instance) // must not refetch — the in-memory cache guard lives on EstadoBusqueda, // not on the widget. await tester.pumpWidget(const SizedBox.shrink()); await pumpEstable(tester); await tester.pumpWidget(buildScreen(estado)); await pumpEstable(tester); expect(radio.obtenerPaisesCalls, 1); }, ); }