diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index be573c695..0840517a6 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -108,6 +108,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_create_filter_for_folder.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_save_email_as_draft_extension.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/reopen_composer_cache_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart'; @@ -127,6 +128,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/update_vacati import 'package:tmail_ui_user/features/manage_account/domain/usecases/create_new_email_rule_filter_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/datetime_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; @@ -238,6 +240,7 @@ class MailboxDashBoardController extends ReloadableController IOSNotificationManager? _iosNotificationManager; GetServerSettingInteractor? getServerSettingInteractor; CreateNewEmailRuleFilterInteractor? createNewEmailRuleFilterInteractor; + SaveLanguageInteractor? saveLanguageInteractor; final scaffoldKey = GlobalKey(); final selectedMailbox = Rxn(); @@ -465,6 +468,7 @@ class MailboxDashBoardController extends ReloadableController ); } else if (success is GetServerSettingSuccess) { isSenderImportantFlagEnabled.value = success.settingOption.isDisplaySenderPriority; + initializeAppLanguage(success); } else if (success is ClearMailboxSuccess) { clearMailboxSuccess(success); } else if (success is CreateNewRuleFilterSuccess) { diff --git a/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart b/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart index 5719e7145..314fe8655 100644 --- a/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart +++ b/lib/features/mailbox_dashboard/presentation/extensions/handle_preferences_setting_extension.dart @@ -1,6 +1,7 @@ import 'package:server_settings/server_settings/capability_server_settings.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart'; import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; @@ -21,6 +22,7 @@ extension HandlePreferencesSettingExtension on MailboxDashBoardController { if (isServerSettingsCapabilitySupported) { PreferencesInteractorsBindings().dependencies(); getServerSettingInteractor = getBinding(); + saveLanguageInteractor = getBinding(); } } diff --git a/lib/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart b/lib/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart new file mode 100644 index 000000000..e612275f5 --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart @@ -0,0 +1,16 @@ +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/main/localizations/localization_service.dart'; + +extension InitializeAppLanguage on MailboxDashBoardController { + void initializeAppLanguage(GetServerSettingSuccess success) { + LocalizationService.initializeAppLanguage( + serverLanguage: success.settingOption.language, + onServerLanguageApplied: (locale) { + if (saveLanguageInteractor != null) { + consumeState(saveLanguageInteractor!.execute(locale)); + } + }, + ); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/data/datasource/manage_account_datasource.dart b/lib/features/manage_account/data/datasource/preferences_datasource.dart similarity index 64% rename from lib/features/manage_account/data/datasource/manage_account_datasource.dart rename to lib/features/manage_account/data/datasource/preferences_datasource.dart index a04784535..005048f86 100644 --- a/lib/features/manage_account/data/datasource/manage_account_datasource.dart +++ b/lib/features/manage_account/data/datasource/preferences_datasource.dart @@ -1,5 +1,5 @@ import 'dart:ui'; -abstract class ManageAccountDataSource { +abstract class PreferencesDataSource { Future persistLanguage(Locale localeCurrent); } \ No newline at end of file diff --git a/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart b/lib/features/manage_account/data/datasource_impl/preferences_datasource_impl.dart similarity index 82% rename from lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart rename to lib/features/manage_account/data/datasource_impl/preferences_datasource_impl.dart index c9fbdfbb3..74d5a10c4 100644 --- a/lib/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart +++ b/lib/features/manage_account/data/datasource_impl/preferences_datasource_impl.dart @@ -1,15 +1,15 @@ import 'dart:ui'; -import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource/preferences_datasource.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; -class ManageAccountDataSourceImpl extends ManageAccountDataSource { +class PreferencesDataSourceImpl extends PreferencesDataSource { final LanguageCacheManager _languageCacheManager; final ExceptionThrower _exceptionThrower; - ManageAccountDataSourceImpl( + PreferencesDataSourceImpl( this._languageCacheManager, this._exceptionThrower ); diff --git a/lib/features/manage_account/data/repository/manage_account_repository_impl.dart b/lib/features/manage_account/data/repository/preferences_repository_impl.dart similarity index 53% rename from lib/features/manage_account/data/repository/manage_account_repository_impl.dart rename to lib/features/manage_account/data/repository/preferences_repository_impl.dart index d33978915..57914c0d6 100644 --- a/lib/features/manage_account/data/repository/manage_account_repository_impl.dart +++ b/lib/features/manage_account/data/repository/preferences_repository_impl.dart @@ -1,13 +1,13 @@ import 'dart:ui'; -import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; -import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource/preferences_datasource.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/preferences_repository.dart'; -class ManageAccountRepositoryImpl extends ManageAccountRepository { +class PreferencesRepositoryImpl extends PreferencesRepository { - final ManageAccountDataSource dataSource; + final PreferencesDataSource dataSource; - ManageAccountRepositoryImpl(this.dataSource); + PreferencesRepositoryImpl(this.dataSource); @override Future persistLanguage(Locale localeCurrent) { diff --git a/lib/features/manage_account/domain/repository/manage_account_repository.dart b/lib/features/manage_account/domain/repository/preferences_repository.dart similarity index 64% rename from lib/features/manage_account/domain/repository/manage_account_repository.dart rename to lib/features/manage_account/domain/repository/preferences_repository.dart index de03d24f4..144c6260f 100644 --- a/lib/features/manage_account/domain/repository/manage_account_repository.dart +++ b/lib/features/manage_account/domain/repository/preferences_repository.dart @@ -1,5 +1,5 @@ import 'dart:ui'; -abstract class ManageAccountRepository { +abstract class PreferencesRepository { Future persistLanguage(Locale localeCurrent); } \ No newline at end of file diff --git a/lib/features/manage_account/domain/usecases/save_language_interactor.dart b/lib/features/manage_account/domain/usecases/save_language_interactor.dart index c547a09da..2f2cd89c1 100644 --- a/lib/features/manage_account/domain/usecases/save_language_interactor.dart +++ b/lib/features/manage_account/domain/usecases/save_language_interactor.dart @@ -4,11 +4,11 @@ import 'dart:ui'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:dartz/dartz.dart'; -import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/preferences_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/save_language_state.dart'; class SaveLanguageInteractor { - final ManageAccountRepository manageAccountRepository; + final PreferencesRepository manageAccountRepository; SaveLanguageInteractor(this.manageAccountRepository); diff --git a/lib/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart b/lib/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart index d141c1a37..cc58a6889 100644 --- a/lib/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart +++ b/lib/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart'; -import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/preferences_repository.dart'; import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_controller.dart'; @@ -21,7 +21,7 @@ class LanguageAndRegionBindings extends BaseBindings { @override void bindingsInteractor() { - Get.lazyPut(() => SaveLanguageInteractor(Get.find())); + Get.lazyPut(() => SaveLanguageInteractor(Get.find())); } @override diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart b/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart index a964d8324..bf06fd7b0 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_bindings.dart @@ -1,10 +1,10 @@ import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart'; -import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart'; -import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource/preferences_datasource.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/preferences_datasource_impl.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; -import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart'; -import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/data/repository/preferences_repository_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/preferences_repository.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_bindings.dart'; @@ -28,12 +28,12 @@ class ManageAccountDashBoardBindings extends BaseBindings { @override void bindingsDataSource() { - Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override void bindingsDataSourceImpl() { - Get.lazyPut(() => ManageAccountDataSourceImpl( + Get.lazyPut(() => PreferencesDataSourceImpl( Get.find(), Get.find())); } @@ -43,11 +43,11 @@ class ManageAccountDashBoardBindings extends BaseBindings { @override void bindingsRepository() { - Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override void bindingsRepositoryImpl() { - Get.lazyPut(() => ManageAccountRepositoryImpl(Get.find())); + Get.lazyPut(() => PreferencesRepositoryImpl(Get.find())); } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart b/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart index 22bab0b44..9e793e6ac 100644 --- a/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart +++ b/lib/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart @@ -1,5 +1,11 @@ import 'package:get/get.dart'; import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource/preferences_datasource.dart'; +import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/preferences_datasource_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; +import 'package:tmail_ui_user/features/manage_account/data/repository/preferences_repository_impl.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/repository/preferences_repository.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/save_language_interactor.dart'; import 'package:tmail_ui_user/features/server_settings/data/datasource/server_settings_data_source.dart'; import 'package:tmail_ui_user/features/server_settings/data/datasource_impl/remote_server_settings_data_source_impl.dart'; import 'package:tmail_ui_user/features/server_settings/data/network/server_settings_api.dart'; @@ -7,6 +13,7 @@ import 'package:tmail_ui_user/features/server_settings/data/repository/server_se import 'package:tmail_ui_user/features/server_settings/domain/repository/server_settings_repository.dart'; import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_server_setting_interactor.dart'; import 'package:tmail_ui_user/features/server_settings/domain/usecases/update_server_setting_interactor.dart'; +import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart'; class PreferencesInteractorsBindings extends InteractorsBindings { @@ -21,6 +28,10 @@ class PreferencesInteractorsBindings extends InteractorsBindings { () => Get.find(tag: composerId), tag: composerId, ); + Get.lazyPut( + () => Get.find(tag: composerId), + tag: composerId, + ); } @override @@ -29,6 +40,10 @@ class PreferencesInteractorsBindings extends InteractorsBindings { Get.find(), Get.find(), ), tag: composerId); + Get.lazyPut(() => PreferencesDataSourceImpl( + Get.find(), + Get.find(), + ), tag: composerId); } @override @@ -41,6 +56,10 @@ class PreferencesInteractorsBindings extends InteractorsBindings { () => UpdateServerSettingInteractor(Get.find(tag: composerId)), tag: composerId, ); + Get.lazyPut( + () => SaveLanguageInteractor(Get.find(tag: composerId)), + tag: composerId, + ); } @override @@ -49,6 +68,10 @@ class PreferencesInteractorsBindings extends InteractorsBindings { () => Get.find(tag: composerId), tag: composerId, ); + Get.lazyPut( + () => Get.find(tag: composerId), + tag: composerId, + ); } @override @@ -57,6 +80,10 @@ class PreferencesInteractorsBindings extends InteractorsBindings { () => ServerSettingsRepositoryImpl(Get.find(tag: composerId)), tag: composerId, ); + Get.lazyPut( + () => PreferencesRepositoryImpl(Get.find(tag: composerId)), + tag: composerId, + ); } void dispose() { @@ -66,5 +93,11 @@ class PreferencesInteractorsBindings extends InteractorsBindings { Get.delete(tag: composerId); Get.delete(tag: composerId); Get.delete(tag: composerId); + + Get.delete(tag: composerId); + Get.delete(tag: composerId); + Get.delete(tag: composerId); + Get.delete(tag: composerId); + Get.delete(tag: composerId); } } \ No newline at end of file diff --git a/lib/main/localizations/localization_service.dart b/lib/main/localizations/localization_service.dart index 5b4bac3b7..4a8b4f529 100644 --- a/lib/main/localizations/localization_service.dart +++ b/lib/main/localizations/localization_service.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:core/utils/app_logger.dart'; +import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; import 'package:tmail_ui_user/main/localizations/language_code_constants.dart'; @@ -45,26 +46,77 @@ class LocalizationService extends Translations { log('LocalizationService::_getLocaleFromLanguage:languageCacheManager: $languageCacheManager'); final localeStored = languageCacheManager?.getStoredLanguage(); log('LocalizationService::_getLocaleFromLanguage():localeStored: $localeStored'); - if (localeStored != null) { - return localeStored; - } else { - final languageCodeCurrent = langCode ?? Get.deviceLocale?.languageCode; - log('LocalizationService::_getLocaleFromLanguage():languageCodeCurrent: $languageCodeCurrent'); - final localeSelected = supportedLocales.firstWhereOrNull((locale) => locale.languageCode == languageCodeCurrent); - return localeSelected ?? Get.deviceLocale ?? defaultLocale; - } + final localeSelected = supportedLocales.firstWhereOrNull( + (locale) => locale.languageCode == langCode, + ); + return localeSelected ?? localeStored ?? Get.deviceLocale ?? defaultLocale; } catch (e) { logError('LocalizationService::getLocaleFromLanguage: Exception: $e'); return Get.deviceLocale ?? defaultLocale; } } + static Locale? getCachedLocale() { + try { + final languageCacheManager = getBinding(); + return languageCacheManager?.getStoredLanguage(); + } catch (e) { + logError('LocalizationService::getCachedLocale: Exception: $e'); + return null; + } + } + static String supportedLocalesToLanguageTags() { final listLanguageTags = supportedLocales.map((locale) => locale.toLanguageTag()).join(', '); log('LocalizationService::supportedLocalesToLanguageTags:listLanguageTags: $listLanguageTags'); return listLanguageTags; } + static void initializeAppLanguage({ + String? serverLanguage, + void Function(Locale locale)? onServerLanguageApplied, + }) { + final currentLocale = Get.locale; + try { + final serverLocale = supportedLocales + .firstWhereOrNull((locale) => locale.languageCode == serverLanguage); + final cachedLocale = getCachedLocale(); + + // From server + if (serverLocale != null && supportedLocales.contains(serverLocale)) { + changeLocale(serverLocale.languageCode); + onServerLanguageApplied?.call(serverLocale); + return; + } + + // From cache + if (cachedLocale != null && supportedLocales.contains(cachedLocale)) { + changeLocale(cachedLocale.languageCode); + return; + } + + // From device + final deviceLocale = WidgetsBinding.instance.platformDispatcher.locale; + if (supportedLocales.contains(deviceLocale)) { + changeLocale(deviceLocale.languageCode); + return; + } + + // Default + if (currentLocale == null || !supportedLocales.contains(currentLocale)) { + changeLocale(defaultLocale.languageCode); + return; + } + } catch (e) { + logError('LocalizationService::initializeAppLanguage: Exception: $e'); + // Default + if (currentLocale == null || !supportedLocales.contains(currentLocale)) { + changeLocale(defaultLocale.languageCode); + return; + } + } + } + @override Map> get keys => {}; } diff --git a/server_settings/lib/server_settings/tmail_server_settings.dart b/server_settings/lib/server_settings/tmail_server_settings.dart index 335537dfc..fe339de39 100644 --- a/server_settings/lib/server_settings/tmail_server_settings.dart +++ b/server_settings/lib/server_settings/tmail_server_settings.dart @@ -37,9 +37,13 @@ class TMailServerSettingOptions with EquatableMixin { @JsonKey(name: 'display.sender.priority') final bool? displaySenderPriority; + @JsonKey(name: 'language') + final String? language; + TMailServerSettingOptions({ this.alwaysReadReceipts, this.displaySenderPriority, + this.language, }); factory TMailServerSettingOptions.fromJson(Map json) => @@ -50,10 +54,12 @@ class TMailServerSettingOptions with EquatableMixin { TMailServerSettingOptions copyWith({ bool? alwaysReadReceipts, bool? displaySenderPriority, + String? language, }) { return TMailServerSettingOptions( alwaysReadReceipts: alwaysReadReceipts ?? this.alwaysReadReceipts, displaySenderPriority: displaySenderPriority ?? this.displaySenderPriority, + language: language ?? this.language, ); } @@ -61,5 +67,6 @@ class TMailServerSettingOptions with EquatableMixin { List get props => [ alwaysReadReceipts, displaySenderPriority, + language, ]; } diff --git a/test/features/mailbox_dashboard/presentation/extensions/initialize_app_language_test.dart b/test/features/mailbox_dashboard/presentation/extensions/initialize_app_language_test.dart new file mode 100644 index 000000000..511f6c500 --- /dev/null +++ b/test/features/mailbox_dashboard/presentation/extensions/initialize_app_language_test.dart @@ -0,0 +1,315 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:get/get.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:server_settings/server_settings/tmail_server_settings.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/initialize_app_language.dart'; +import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; +import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart'; +import 'package:tmail_ui_user/main/localizations/language_code_constants.dart'; +import 'package:tmail_ui_user/main/localizations/localization_service.dart'; + +import 'initialize_app_language_test.mocks.dart'; + +@GenerateNiceMocks([ + MockSpec(), + MockSpec(), +]) +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + final mailboxDashboardController = MockMailboxDashBoardController(); + final languageCacheManager = MockLanguageCacheManager(); + + setUp(() { + Get.testMode = true; + Get.locale = const Locale('fr', 'FR'); + Get.put(languageCacheManager); + }); + + tearDown(() { + Get.reset(); + Get.locale = null; + Get.testMode = false; + TestWidgetsFlutterBinding.instance.reset(); + }); + + group('initialize app language test:', () { + testWidgets( + 'should apply server language ' + 'when server language is not null ' + 'and server language is supported', + (tester) async { + // arrange + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: LanguageCodeConstants.vietnamese, + )); + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale?.languageCode, LanguageCodeConstants.vietnamese); + }); + + testWidgets( + 'should apply cached language ' + 'when server language is null ' + 'and cached language is not null ' + 'and cached language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(expectedLocale); + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply cached language ' + 'when server language is not null ' + 'and server language is not supported ' + 'and cached language is not null ' + 'and cached language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: 'fi', + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(expectedLocale); + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply device language ' + 'when server language is null ' + 'and cached language is null ' + 'and device language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(null); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = expectedLocale; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply device language ' + 'when server language is not null ' + 'and server language is not supported ' + 'and cached language is null ' + 'and device language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: 'fi', + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(null); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = expectedLocale; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply device language ' + 'when server language is null ' + 'and cached language is not null ' + 'and cached language is not supported ' + 'and device language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()) + .thenReturn(const Locale('fi', 'FI')); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = expectedLocale; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply device language ' + 'when server language is not null ' + 'and server language is not supported ' + 'and cached language is not null ' + 'and cached language is not supported ' + 'and device language is supported', + (tester) async { + // arrange + const expectedLocale = Locale('en', 'US'); + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: 'es', + )); + when(languageCacheManager.getStoredLanguage()) + .thenReturn(const Locale('fi', 'FI')); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = expectedLocale; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, expectedLocale); + }); + + testWidgets( + 'should apply default language (English) ' + 'when server language is null ' + 'and cached language is null ' + 'and current locale is null ' + 'and device language is not supported', + (tester) async { + // arrange + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(null); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = const Locale('es', 'ES'); + Get.locale = null; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, LocalizationService.defaultLocale); + }); + + testWidgets( + 'should apply default language (English) ' + 'when server language is not null ' + 'and server language is not supported ' + 'and cached language is null ' + 'and current locale is null ' + 'and device language is not supported', + (tester) async { + // arrange + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: 'fi', + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(null); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = const Locale('es', 'ES'); + Get.locale = null; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, LocalizationService.defaultLocale); + }); + + testWidgets( + 'should apply default language (English) ' + 'when server language is null ' + 'and cached language is not null ' + 'and cached language is not supported ' + 'and current locale is null ' + 'and device language is not supported', + (tester) async { + // arrange + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()) + .thenReturn(const Locale('fi', 'FI')); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = const Locale('es', 'ES'); + Get.locale = null; + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, LocalizationService.defaultLocale); + }); + + testWidgets( + 'should apply default language (English) ' + 'when server language is null ' + 'and cached language is null ' + 'and current locale is not null ' + 'and current locale is not supported ' + 'and device language is not supported', + (tester) async { + // arrange + final success = GetServerSettingSuccess(TMailServerSettingOptions( + language: null, + )); + when(languageCacheManager.getStoredLanguage()).thenReturn(null); + TestWidgetsFlutterBinding + .instance + .platformDispatcher + .localeTestValue = const Locale('es', 'ES'); + Get.locale = const Locale('fi', 'FI'); + + // act + mailboxDashboardController.initializeAppLanguage(success); + await tester.pumpAndSettle(); + + // assert + expect(Get.locale, LocalizationService.defaultLocale); + }); + }); +} \ No newline at end of file