import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sxchnge_app/main.dart'; import 'package:sxchnge_app/providers/locale.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); setUp(() => SharedPreferences.setMockInitialValues({})); test('saved choice overrides system locale, with English fallback', () async { expect( LocaleProvider.resolve(null, [const Locale('ru', 'RU')]), const Locale('ru'), ); expect( LocaleProvider.resolve('en', [const Locale('ru')]), const Locale('en'), ); expect( LocaleProvider.resolve('ru-RU', [const Locale('en')]), const Locale('ru'), ); expect( LocaleProvider.resolve('de', [const Locale('ru')]), const Locale('en'), ); expect( LocaleProvider.resolve(null, [const Locale('fr')]), const Locale('en'), ); expect(LocaleProvider.resolve(null, []), const Locale('en')); final first = await LocaleProvider.load([const Locale('en')]); await first.setLocale(const Locale('ru')); final restarted = await LocaleProvider.load([const Locale('en')]); expect(restarted.locale, const Locale('ru')); await Future.wait([ first.setLocale(const Locale('en')), first.setLocale(const Locale('ru')), ]); expect( (await SharedPreferences.getInstance()).getString( LocaleProvider.storageKey, ), 'ru', ); first.dispose(); restarted.dispose(); }); test('catalogs have equal keys and no empty translations', () { final en = jsonDecode(File('lib/l10n/en.arb').readAsStringSync()) as Map; final ru = jsonDecode(File('lib/l10n/ru.arb').readAsStringSync()) as Map; expect(ru.keys.toSet(), en.keys.toSet()); expect( ru.values.every((value) => value is String && value.trim().isNotEmpty), isTrue, ); }); testWidgets( 'switching language updates errors and keeps form data and mode', (tester) async { tester.view.physicalSize = const Size(1440, 1200); tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); final locale = await LocaleProvider.load([const Locale('en')]); await tester.pumpWidget(SxchngeApp(localeProvider: locale)); await tester.pumpAndSettle(); await tester.tap(find.text('Sign up')); await tester.pumpAndSettle(); await tester.enterText(find.byKey(const ValueKey('name')), 'Алексей'); await tester.enterText(find.byKey(const ValueKey('email')), 'invalid'); await tester.ensureVisible(find.byKey(const ValueKey('submit'))); await tester.tap(find.byKey(const ValueKey('submit'))); await tester.pumpAndSettle(); expect(find.text('Enter a valid email address.'), findsOneWidget); await locale.setLocale(const Locale('ru')); await tester.pumpAndSettle(); expect(find.text('Введите корректный адрес почты.'), findsOneWidget); expect(find.text('Алексей'), findsOneWidget); expect(find.text('invalid'), findsOneWidget); expect(find.byKey(const ValueKey('confirmation')), findsOneWidget); expect(find.byTooltip('Показать пароль'), findsOneWidget); expect( (await SharedPreferences.getInstance()).getString( LocaleProvider.storageKey, ), 'ru', ); expect(tester.takeException(), isNull); }, ); for (final width in [320.0, 1440.0]) { testWidgets('Russian forms fit at width $width with 200% text', ( tester, ) async { tester.view.physicalSize = Size(width, 1000); tester.view.devicePixelRatio = 1; tester.platformDispatcher.textScaleFactorTestValue = 2; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); addTearDown(tester.platformDispatcher.clearTextScaleFactorTestValue); await tester.pumpWidget( SxchngeApp( localeProvider: LocaleProvider(initialLocale: const Locale('ru')), ), ); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); await tester.ensureVisible(find.text('Регистрация')); await tester.tap(find.text('Регистрация')); await tester.pumpAndSettle(); await tester.ensureVisible(find.byKey(const ValueKey('submit'))); await tester.tap(find.byKey(const ValueKey('submit'))); await tester.pumpAndSettle(); expect(find.text('Введите ваше имя.'), findsOneWidget); expect(tester.takeException(), isNull); }); } }