From 33b90d3c658012d004afcca1f879b0f307c7b791 Mon Sep 17 00:00:00 2001 From: DatDang Date: Mon, 24 Feb 2025 10:38:03 +0700 Subject: [PATCH] TF-3487 Handle search email failure --- .../presentation/search_email_controller.dart | 1 + .../domain/state/search_email_state.dart | 2 +- .../usecases/search_email_interactor.dart | 14 ++++++++++++- .../presentation/thread_controller.dart | 1 + .../search_email_interactor_test.dart | 20 ++++++++++++------- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/features/search/email/presentation/search_email_controller.dart b/lib/features/search/email/presentation/search_email_controller.dart index d85380e28..3481428fe 100644 --- a/lib/features/search/email/presentation/search_email_controller.dart +++ b/lib/features/search/email/presentation/search_email_controller.dart @@ -483,6 +483,7 @@ class SearchEmailController extends BaseController void _searchEmailsFailure(SearchEmailFailure failure) { listResultSearch.clear(); resultSearchViewState.value = Left(failure); + showRetryToast(failure); } void searchMoreEmailsAction() { diff --git a/lib/features/thread/domain/state/search_email_state.dart b/lib/features/thread/domain/state/search_email_state.dart index 05599e9de..b78bc20df 100644 --- a/lib/features/thread/domain/state/search_email_state.dart +++ b/lib/features/thread/domain/state/search_email_state.dart @@ -17,5 +17,5 @@ class SearchEmailSuccess extends UIState { class SearchEmailFailure extends FeatureFailure { - SearchEmailFailure(dynamic exception) : super(exception: exception); + SearchEmailFailure(dynamic exception, {super.onRetry}) : super(exception: exception); } \ No newline at end of file diff --git a/lib/features/thread/domain/usecases/search_email_interactor.dart b/lib/features/thread/domain/usecases/search_email_interactor.dart index 6d75a963b..1e6ccceea 100644 --- a/lib/features/thread/domain/usecases/search_email_interactor.dart +++ b/lib/features/thread/domain/usecases/search_email_interactor.dart @@ -55,7 +55,19 @@ class SearchEmailInteractor { yield Right(SearchEmailSuccess(presentationEmailList)); } catch (e) { - yield Left(SearchEmailFailure(e)); + yield Left(SearchEmailFailure( + e, + onRetry: execute( + session, + accountId, + filter: filter, + limit: limit, + position: position, + sort: sort, + properties: properties, + needRefreshSearchState: true, + ), + )); } } } \ No newline at end of file diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 1f2d70951..c9bb7a9d8 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -201,6 +201,7 @@ class ThreadController extends BaseController with EmailActionController { mailboxDashBoardController.updateRefreshAllEmailState(Left(RefreshAllEmailFailure())); canSearchMore = false; mailboxDashBoardController.emailsInCurrentMailbox.clear(); + showRetryToast(failure); } else if (failure is SearchMoreEmailFailure) { loadingMoreStatus.value = LoadingMoreStatus.completed; canSearchMore = true; diff --git a/test/features/thread/domain/usecases/search_email_interactor_test.dart b/test/features/thread/domain/usecases/search_email_interactor_test.dart index 507f2b8d3..954d5c11f 100644 --- a/test/features/thread/domain/usecases/search_email_interactor_test.dart +++ b/test/features/thread/domain/usecases/search_email_interactor_test.dart @@ -1,3 +1,5 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; import 'package:dartz/dartz.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart'; @@ -100,7 +102,7 @@ void main() { test( 'should return Failure when threadRepository.searchEmails returns Failure', - () { + () async { // arrange final exception = Exception(); when( @@ -119,15 +121,19 @@ void main() { SessionFixtures.aliceSession, AccountFixtures.aliceAccountId, filter: EmailFilterCondition(text: 'test'), - ); + ).asBroadcastStream(); // assert + final firstState = await result.first; + final lastState = await result.last; + expect(firstState, Right(SearchingState())); expect( - result, - emitsInOrder([ - Right(SearchingState()), - Left(SearchEmailFailure(exception)), - ]), + lastState.fold((failure) { + return failure is SearchEmailFailure + && failure.exception == exception + && failure.onRetry is Stream>; + }, (success) => false), + true, ); }, );