import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:emergency/features/home/country_picker_screen.dart'; import 'package:emergency/l10n/app_localizations.dart'; import 'package:emergency/models/country.dart'; import 'package:emergency/models/emergency_number.dart'; import 'package:emergency/models/emergency_type.dart'; import 'package:emergency/providers/emergency_provider.dart'; import 'package:emergency/repositories/emergency_number_repository.dart'; import 'package:emergency/services/country_code_sources/country_code_source.dart'; import 'package:emergency/services/location_service.dart'; /// Liefert eine feste Länderliste, ohne das echte JSON-Asset laden zu /// müssen (analog zum Fake-Repository-Muster in `emergency_provider_test.dart`). class _FakeRepository extends EmergencyNumberRepository { @override List get allCountries => const [ Country( isoCode: 'DE', nameDe: 'Deutschland', nameEn: 'Germany', flag: '🇩🇪', numbers: [ EmergencyNumber(type: EmergencyType.general, number: '112', labelDe: 'Notruf', labelEn: 'Emergency'), ], ), Country( isoCode: 'FR', nameDe: 'Frankreich', nameEn: 'France', flag: '🇫🇷', numbers: [ EmergencyNumber(type: EmergencyType.general, number: '112', labelDe: 'Notruf', labelEn: 'Emergency'), ], ), ]; } class _NoopSource implements CountryCodeSource { const _NoopSource(); @override Future resolve() async => null; } /// Fake-Provider: überschreibt `selectCountryManually`, damit der Test ohne /// echte `LocationService`-Ermittlungskette prüfen kann, mit welchem /// ISO-Code der Screen die Auswahl auslöst. class _FakeProvider extends EmergencyProvider { _FakeProvider({required super.repository}) : super( locationService: LocationService( simSource: const _NoopSource(), gpsSource: const _NoopSource(), ), ); String? selectedIsoCode; int selectCallCount = 0; @override Future selectCountryManually(String isoCode) async { selectCallCount++; selectedIsoCode = isoCode; } } void main() { Future pumpPickerBehindAButton(WidgetTester tester, EmergencyProvider provider) async { // CountryPickerScreen ruft `Navigator.pop()` beim Auswählen auf – dafür // muss eine vorherige Route existieren, sonst wäre der Pop ein No-op. await tester.pumpWidget( ChangeNotifierProvider.value( value: provider, child: MaterialApp( // Feste Locale, damit die (unveränderten) deutschen Text-Assertions // dieser Tests unabhängig von der Test-Umgebungs-/Systemsprache // funktionieren; das eigentliche Umschalten der App-Sprache wird // gezielt in `test/core/country_locale_map_test.dart` bzw. // `test/app_locale_test.dart` (AP7) geprüft. locale: const Locale('de'), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: Builder( builder: (context) => ElevatedButton( onPressed: () => Navigator.of(context).push( MaterialPageRoute(builder: (_) => const CountryPickerScreen()), ), child: const Text('Öffnen'), ), ), ), ), ); await tester.tap(find.text('Öffnen')); await tester.pumpAndSettle(); } testWidgets('zeigt die Länderliste an', (tester) async { final provider = _FakeProvider(repository: _FakeRepository()); await pumpPickerBehindAButton(tester, provider); expect(find.text('Deutschland'), findsOneWidget); expect(find.text('Frankreich'), findsOneWidget); }); testWidgets('Suchfeld filtert die Länderliste', (tester) async { final provider = _FakeProvider(repository: _FakeRepository()); await pumpPickerBehindAButton(tester, provider); await tester.enterText(find.byType(TextField), 'Deutsch'); await tester.pump(); expect(find.text('Deutschland'), findsOneWidget); expect(find.text('Frankreich'), findsNothing); }); testWidgets('zeigt einen Hinweis, wenn kein Land zum Filter passt', (tester) async { final provider = _FakeProvider(repository: _FakeRepository()); await pumpPickerBehindAButton(tester, provider); await tester.enterText(find.byType(TextField), 'Nichtland'); await tester.pump(); expect(find.text('Kein Land gefunden.'), findsOneWidget); }); testWidgets('Tap auf ein Land löst selectCountryManually aus und schließt den Screen', ( tester, ) async { final provider = _FakeProvider(repository: _FakeRepository()); await pumpPickerBehindAButton(tester, provider); await tester.tap(find.text('Deutschland')); await tester.pumpAndSettle(); expect(provider.selectCallCount, 1); expect(provider.selectedIsoCode, 'DE'); // Screen wurde geschlossen (zurück zum "Öffnen"-Button). expect(find.text('Öffnen'), findsOneWidget); expect(find.text('Deutschland'), findsNothing); }); }