import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:sm_mobile/core/app_controller.dart'; import 'package:sm_mobile/l10n/strings.dart'; import 'package:sm_mobile/main.dart'; import 'package:sm_mobile/models/server_profile.dart'; import 'package:sm_mobile/ui/profile_editor.dart'; import 'support.dart'; void main() { for (final locale in ['cs', 'de', 'en']) { testWidgets('onboarding gates server access and localizes $locale', ( tester, ) async { final c = AppController(MemoryStore()); await tester.runAsync(() => c.initialize()); c.locale = Locale(locale); await tester.pumpWidget(SmMobileApp(c)); await tester.pumpAndSettle(); final ctx = tester.element(find.byType(Scaffold).first); expect(find.text(ctx.tr('guidance')), findsOneWidget); expect(find.text(ctx.tr('addServer')), findsNothing); await tester.ensureVisible(find.text(ctx.tr('continueAction'))); await tester.pumpAndSettle(); await tester.tap(find.text(ctx.tr('continueAction'))); await tester.pumpAndSettle(); final accept = tester.widget( find.widgetWithText(FilledButton, ctx.tr('accept')), ); expect(accept.onPressed, null); await tester.ensureVisible(find.text(ctx.tr('decline'))); await tester.pumpAndSettle(); await tester.tap(find.text(ctx.tr('decline'))); await tester.pumpAndSettle(); expect(find.text(ctx.tr('licenseDeclined')), findsOneWidget); expect(c.accepted, false); await tester.pumpWidget(const SizedBox()); c.dispose(); }); } testWidgets('onboarding remains usable in landscape with large text', ( tester, ) async { tester.view.physicalSize = const Size(740, 340); tester.view.devicePixelRatio = 1; tester.platformDispatcher.textScaleFactorTestValue = 2; addTearDown(() { tester.view.resetPhysicalSize(); tester.view.resetDevicePixelRatio(); tester.platformDispatcher.clearTextScaleFactorTestValue(); }); final c = AppController(MemoryStore()); await tester.runAsync(() => c.initialize()); await tester.pumpWidget(SmMobileApp(c)); await tester.pumpAndSettle(); expect(tester.takeException(), null); await tester.pumpWidget(const SizedBox()); c.dispose(); }); testWidgets('profile editor renders required inputs and auth picker', ( tester, ) async { final c = AppController(MemoryStore()); await tester.pumpWidget( MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: ProfileEditor(c), ), ); await tester.pumpAndSettle(); expect(find.byType(TextField), findsNWidgets(4)); expect(find.byType(DropdownButtonFormField), findsOneWidget); await tester.pumpWidget(const SizedBox()); c.dispose(); }); test('all three locales provide identical nonempty message sets', () async { final en = await AppLocalizations.delegate.load(const Locale('en')); final cs = await AppLocalizations.delegate.load(const Locale('cs')); final de = await AppLocalizations.delegate.load(const Locale('de')); expect({en.hostChanged, cs.hostChanged, de.hostChanged}.length, 3); for (final l in [en, cs, de]) { expect(l.consent, contains('1.14')); expect(l.unsafePath, isNotEmpty); } }); }