From 79765414d55a27a6510517bb4ead23012423a0d3 Mon Sep 17 00:00:00 2001 From: Dat PHAM HOANG Date: Mon, 6 May 2024 17:44:46 +0700 Subject: [PATCH] TW-2835 Add right exception thrower for database operation of AuthenticationOIDCDatasource --- .../reloadable/reloadable_controller.dart | 1 + .../authentication_oidc_datasource_impl.dart | 12 +- .../credential/credential_bindings.dart | 1 + .../presentation/home_controller_test.dart | 138 ++++++++++++++++++ 4 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 test/features/home/presentation/home_controller_test.dart diff --git a/lib/features/base/reloadable/reloadable_controller.dart b/lib/features/base/reloadable/reloadable_controller.dart index cb12e36f5e..71ecafff7d 100644 --- a/lib/features/base/reloadable/reloadable_controller.dart +++ b/lib/features/base/reloadable/reloadable_controller.dart @@ -33,6 +33,7 @@ abstract class ReloadableController extends BaseController { if (failure is GetCredentialFailure || failure is GetStoredTokenOidcFailure || failure is GetAuthenticatedAccountFailure) { + log('ReloadableController::handleFailureViewState(): failure: $failure'); goToLogin(); } else if (failure is GetSessionFailure) { _handleGetSessionFailure(failure.exception); diff --git a/lib/features/login/data/datasource_impl/authentication_oidc_datasource_impl.dart b/lib/features/login/data/datasource_impl/authentication_oidc_datasource_impl.dart index dbaa6e0163..7f5a83b91a 100644 --- a/lib/features/login/data/datasource_impl/authentication_oidc_datasource_impl.dart +++ b/lib/features/login/data/datasource_impl/authentication_oidc_datasource_impl.dart @@ -13,13 +13,15 @@ class AuthenticationOIDCDataSourceImpl extends AuthenticationOIDCDataSource { final TokenOidcCacheManager _tokenOidcCacheManager; final OidcConfigurationCacheManager _oidcConfigurationCacheManager; final ExceptionThrower _exceptionThrower; + final ExceptionThrower _cacheExceptionThrower; AuthenticationOIDCDataSourceImpl( this._oidcHttpClient, this._authenticationClient, this._tokenOidcCacheManager, this._oidcConfigurationCacheManager, - this._exceptionThrower + this._exceptionThrower, + this._cacheExceptionThrower ); @override @@ -54,28 +56,28 @@ class AuthenticationOIDCDataSourceImpl extends AuthenticationOIDCDataSource { Future getStoredTokenOIDC(String tokenIdHash) { return Future.sync(() async { return await _tokenOidcCacheManager.getTokenOidc(tokenIdHash); - }).catchError(_exceptionThrower.throwException); + }).catchError(_cacheExceptionThrower.throwException); } @override Future persistTokenOIDC(TokenOIDC tokenOidc) { return Future.sync(() async { return await _tokenOidcCacheManager.persistOneTokenOidc(tokenOidc); - }).catchError(_exceptionThrower.throwException); + }).catchError(_cacheExceptionThrower.throwException); } @override Future getStoredOidcConfiguration() { return Future.sync(() async { return await _oidcConfigurationCacheManager.getOidcConfiguration(); - }).catchError(_exceptionThrower.throwException); + }).catchError(_cacheExceptionThrower.throwException); } @override Future persistAuthorityOidc(String authority) { return Future.sync(() async { return await _oidcConfigurationCacheManager.persistAuthorityOidc(authority); - }).catchError(_exceptionThrower.throwException); + }).catchError(_cacheExceptionThrower.throwException); } @override diff --git a/lib/main/bindings/credential/credential_bindings.dart b/lib/main/bindings/credential/credential_bindings.dart index 15c0f2798e..f2b7699b19 100644 --- a/lib/main/bindings/credential/credential_bindings.dart +++ b/lib/main/bindings/credential/credential_bindings.dart @@ -78,6 +78,7 @@ class CredentialBindings extends InteractorsBindings { Get.find(), Get.find(), Get.find(), + Get.find(), )); } diff --git a/test/features/home/presentation/home_controller_test.dart b/test/features/home/presentation/home_controller_test.dart new file mode 100644 index 0000000000..76f74939df --- /dev/null +++ b/test/features/home/presentation/home_controller_test.dart @@ -0,0 +1,138 @@ +import 'package:core/data/network/config/dynamic_url_interceptors.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:core/presentation/utils/app_toast.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:dartz/dartz.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:model/account/authentication_type.dart'; +import 'package:tmail_ui_user/features/caching/caching_manager.dart'; +import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_email_cache_interactor.dart'; +import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_url_cache_interactor.dart'; +import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_username_interactor.dart'; +import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_search_cache_interactor.dart'; +import 'package:tmail_ui_user/features/home/domain/usecases/get_session_interactor.dart'; +import 'package:tmail_ui_user/features/home/presentation/home_controller.dart'; +import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart'; +import 'package:tmail_ui_user/features/login/domain/state/get_stored_token_oidc_state.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/get_authenticated_account_interactor.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/update_authentication_account_interactor.dart'; +import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart'; +import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart'; +import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; +import 'package:uuid/uuid.dart'; + +import '../../email/presentation/controller/single_email_controller_test.mocks.dart'; +import '../../mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.mocks.dart'; +import 'home_controller_test.mocks.dart'; + +@GenerateNiceMocks([ + MockSpec(), + MockSpec(), + MockSpec(), + MockSpec(), +]) +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + + late HomeController homeController; + late MockCleanupEmailCacheInteractor cleanupEmailCacheInteractor; + late MockEmailReceiveManager emailReceiveManager; + late MockCleanupRecentSearchCacheInteractor cleanupRecentSearchCacheInteractor; + late MockCleanupRecentLoginUrlCacheInteractor cleanupRecentLoginUrlCacheInteractor; + late MockCleanupRecentLoginUsernameCacheInteractor cleanupRecentLoginUsernameCacheInteractor; + + late MockGetSessionInteractor mockGetSessionInteractor; + late MockGetAuthenticatedAccountInteractor mockGetAuthenticatedAccountInteractor; + late MockUpdateAuthenticationAccountInteractor mockUpdateAuthenticationAccountInteractor; + + late CachingManager mockCachingManager; + late LanguageCacheManager mockLanguageCacheManager; + late MockAuthorizationInterceptors mockAuthorizationInterceptors; + late MockDynamicUrlInterceptors mockDynamicUrlInterceptors; + late MockDeleteCredentialInteractor mockDeleteCredentialInteractor; + late MockLogoutOidcInteractor mockLogoutOidcInteractor; + late MockDeleteAuthorityOidcInteractor mockDeleteAuthorityOidcInteractor; + late MockAppToast mockAppToast; + late MockImagePaths mockImagePaths; + late MockResponsiveUtils mockResponsiveUtils; + late MockUuid mockUuid; + + setUpAll(() { + cleanupEmailCacheInteractor = MockCleanupEmailCacheInteractor(); + emailReceiveManager = MockEmailReceiveManager(); + cleanupRecentSearchCacheInteractor = MockCleanupRecentSearchCacheInteractor(); + cleanupRecentLoginUrlCacheInteractor = MockCleanupRecentLoginUrlCacheInteractor(); + cleanupRecentLoginUsernameCacheInteractor = MockCleanupRecentLoginUsernameCacheInteractor(); + + // mock reloadable controller + mockGetSessionInteractor = MockGetSessionInteractor(); + mockGetAuthenticatedAccountInteractor = MockGetAuthenticatedAccountInteractor(); + mockUpdateAuthenticationAccountInteractor = MockUpdateAuthenticationAccountInteractor(); + + //mock base controller + mockCachingManager = MockCachingManager(); + mockLanguageCacheManager = MockLanguageCacheManager(); + mockAuthorizationInterceptors = MockAuthorizationInterceptors(); + mockDynamicUrlInterceptors = MockDynamicUrlInterceptors(); + mockDeleteCredentialInteractor = MockDeleteCredentialInteractor(); + mockLogoutOidcInteractor = MockLogoutOidcInteractor(); + mockDeleteAuthorityOidcInteractor = MockDeleteAuthorityOidcInteractor(); + mockAppToast = MockAppToast(); + mockImagePaths = MockImagePaths(); + mockResponsiveUtils = MockResponsiveUtils(); + mockUuid = MockUuid(); + + Get.put(mockGetSessionInteractor); + Get.put(mockGetAuthenticatedAccountInteractor); + Get.put(mockUpdateAuthenticationAccountInteractor); + + Get.put(mockCachingManager); + Get.put(mockLanguageCacheManager); + Get.put(mockAuthorizationInterceptors); + Get.put( + mockAuthorizationInterceptors, + tag: BindingTag.isolateTag, + ); + Get.put(mockDynamicUrlInterceptors); + Get.put(mockDeleteCredentialInteractor); + Get.put(mockLogoutOidcInteractor); + Get.put(mockDeleteAuthorityOidcInteractor); + Get.put(mockAppToast); + Get.put(mockImagePaths); + Get.put(mockResponsiveUtils); + Get.put(mockUuid); + Get.testMode = true; + + homeController = HomeController( + cleanupEmailCacheInteractor, + emailReceiveManager, + cleanupRecentSearchCacheInteractor, + cleanupRecentLoginUrlCacheInteractor, + cleanupRecentLoginUsernameCacheInteractor + ); + }); + + group("HomeController::onData test", () { + test("WHEN onData receive `GetStoredTokenOidcFailure` " + "THEN handleFailureViewState should be called", () { + // Arrange + final failure = Left(GetStoredTokenOidcFailure(Exception())); + when(mockAuthorizationInterceptors.authenticationType).thenReturn(AuthenticationType.oidc); + + // Act + homeController.onData(failure); + + // Assert + verifyNever(mockAppToast.showToastMessage(any, any)); + verifyNever(mockAppToast.showToastErrorMessage(any, any)); + }); + }); +} \ No newline at end of file