From c367d29584578e592c0f53f55393cf3200bcfdcc Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 2 Oct 2024 00:56:51 +0700 Subject: [PATCH] TF-3025 Correctly update the action for the selection list when performing some action `read/start/...` on each element --- .../widgets/app_bar_selection_mode.dart | 188 ++++++++---------- .../usecases/search_email_interactor.dart | 7 +- .../presentation/thread_controller.dart | 25 ++- .../controller/thread_controller_test.dart | 179 +++++++++++++++++ 4 files changed, 288 insertions(+), 111 deletions(-) diff --git a/lib/features/search/email/presentation/widgets/app_bar_selection_mode.dart b/lib/features/search/email/presentation/widgets/app_bar_selection_mode.dart index 4da6f2f578..7a2b0e96ba 100644 --- a/lib/features/search/email/presentation/widgets/app_bar_selection_mode.dart +++ b/lib/features/search/email/presentation/widgets/app_bar_selection_mode.dart @@ -1,9 +1,8 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/views/button/icon_button_web.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/email/email_action_type.dart'; @@ -37,114 +36,103 @@ class AppBarSelectionMode extends StatelessWidget { final isAllBelongToTheSameMailbox = listEmail.isAllBelongToTheSameMailbox(mapMailbox); return Row(children: [ - buildIconWeb( - icon: SvgPicture.asset( - _imagePaths.icClose, - colorFilter: AppColor.colorTextButton.asFilter(), - fit: BoxFit.fill), - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - tooltip: AppLocalizations.of(context).cancel, - onTap: onCancelSelection), - Expanded(child: Text( + TMailButtonWidget.fromIcon( + icon: _imagePaths.icClose, + iconSize: 25, + iconColor: AppColor.colorTextButton, + backgroundColor: Colors.transparent, + tooltipMessage: AppLocalizations.of(context).cancel, + onTapActionCallback: onCancelSelection, + ), + Expanded( + child: Text( AppLocalizations.of(context).count_email_selected(listEmail.length), + maxLines: 1, + overflow: TextOverflow.ellipsis, style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w500, - color: AppColor.colorTextButton))), - buildIconWeb( - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - icon: SvgPicture.asset( - listEmail.isAllEmailRead - ? _imagePaths.icUnread - : _imagePaths.icRead, - fit: BoxFit.fill), - tooltip: listEmail.isAllEmailRead - ? AppLocalizations.of(context).unread - : AppLocalizations.of(context).read, - onTap: () => onHandleEmailAction?.call( - listEmail.isAllEmailRead - ? EmailActionType.markAsUnread - : EmailActionType.markAsRead, - listEmail)), + fontSize: 17, + fontWeight: FontWeight.w500, + color: AppColor.colorTextButton + ) + ) + ), + TMailButtonWidget.fromIcon( + icon: listEmail.isAllEmailRead + ? _imagePaths.icUnread + : _imagePaths.icRead, + iconSize: 25, + backgroundColor: Colors.transparent, + tooltipMessage: listEmail.isAllEmailRead + ? AppLocalizations.of(context).unread + : AppLocalizations.of(context).read, + onTapActionCallback: () => onHandleEmailAction?.call( + listEmail.isAllEmailRead + ? EmailActionType.markAsUnread + : EmailActionType.markAsRead, + listEmail + ), + ), const SizedBox(width: 5), - buildIconWeb( - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - icon: SvgPicture.asset( - listEmail.isAllEmailStarred - ? _imagePaths.icUnStar - : _imagePaths.icStar, - fit: BoxFit.fill), - tooltip: listEmail.isAllEmailStarred - ? AppLocalizations.of(context).not_starred - : AppLocalizations.of(context).starred, - onTap: () => onHandleEmailAction?.call( - listEmail.isAllEmailStarred - ? EmailActionType.unMarkAsStarred - : EmailActionType.markAsStarred, - listEmail)), + TMailButtonWidget.fromIcon( + icon: listEmail.isAllEmailStarred + ? _imagePaths.icUnStar + : _imagePaths.icStar, + iconSize: 25, + backgroundColor: Colors.transparent, + tooltipMessage: listEmail.isAllEmailStarred + ? AppLocalizations.of(context).not_starred + : AppLocalizations.of(context).starred, + onTapActionCallback: () => onHandleEmailAction?.call( + listEmail.isAllEmailStarred + ? EmailActionType.unMarkAsStarred + : EmailActionType.markAsStarred, + listEmail + ), + ), const SizedBox(width: 5), if (canSpamAndMove) ... [ - buildIconWeb( - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).move, - onTap: () => onHandleEmailAction?.call(EmailActionType.moveToMailbox, listEmail)), + TMailButtonWidget.fromIcon( + icon: _imagePaths.icMove, + iconSize: 25, + backgroundColor: Colors.transparent, + tooltipMessage: AppLocalizations.of(context).move, + onTapActionCallback: () => onHandleEmailAction?.call( + EmailActionType.moveToMailbox, + listEmail + ), + ), const SizedBox(width: 5), - buildIconWeb( - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - icon: SvgPicture.asset(isAllSpam - ? _imagePaths.icNotSpam - : _imagePaths.icSpam, - fit: BoxFit.fill), - tooltip: isAllSpam - ? AppLocalizations.of(context).un_spam - : AppLocalizations.of(context).mark_as_spam, - onTap: () => isAllSpam - ? onHandleEmailAction?.call(EmailActionType.unSpam, listEmail) - : onHandleEmailAction?.call(EmailActionType.moveToSpam, listEmail.listEmailCanSpam(mapMailbox))), + TMailButtonWidget.fromIcon( + icon: isAllSpam + ? _imagePaths.icNotSpam + : _imagePaths.icSpam, + iconSize: 25, + backgroundColor: Colors.transparent, + tooltipMessage: isAllSpam + ? AppLocalizations.of(context).un_spam + : AppLocalizations.of(context).mark_as_spam, + onTapActionCallback: () => isAllSpam + ? onHandleEmailAction?.call(EmailActionType.unSpam, listEmail) + : onHandleEmailAction?.call(EmailActionType.moveToSpam, listEmail.listEmailCanSpam(mapMailbox)), + ), const SizedBox(width: 5), ], if (isAllBelongToTheSameMailbox) - ...[ - buildIconWeb( - minSize: 25, - iconSize: 25, - iconPadding: const EdgeInsets.all(5), - splashRadius: 15, - icon: SvgPicture.asset( - canDeletePermanently - ? _imagePaths.icDeleteComposer - : _imagePaths.icDelete, - colorFilter: canDeletePermanently - ? AppColor.colorDeletePermanentlyButton.asFilter() - : AppColor.primaryColor.asFilter(), - width: 20, - height: 20, - fit: BoxFit.fill), - tooltip: canDeletePermanently - ? AppLocalizations.of(context).delete_permanently - : AppLocalizations.of(context).move_to_trash, - onTap: () => canDeletePermanently - ? onHandleEmailAction?.call(EmailActionType.deletePermanently, listEmail) - : onHandleEmailAction?.call(EmailActionType.moveToTrash, listEmail)), - const SizedBox(width: 10) - ], + TMailButtonWidget.fromIcon( + icon: _imagePaths.icDeleteComposer, + iconSize: 20, + backgroundColor: Colors.transparent, + iconColor: canDeletePermanently + ? AppColor.colorDeletePermanentlyButton + : AppColor.primaryColor, + tooltipMessage: canDeletePermanently + ? AppLocalizations.of(context).delete_permanently + : AppLocalizations.of(context).move_to_trash, + onTapActionCallback: () => canDeletePermanently + ? onHandleEmailAction?.call(EmailActionType.deletePermanently, listEmail) + : onHandleEmailAction?.call(EmailActionType.moveToTrash, listEmail), + ), ]); } } \ 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 6a096dcdb5..383256ad92 100644 --- a/lib/features/thread/domain/usecases/search_email_interactor.dart +++ b/lib/features/thread/domain/usecases/search_email_interactor.dart @@ -1,5 +1,6 @@ -import 'package:core/core.dart'; +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; import 'package:dartz/dartz.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/filter/filter.dart'; @@ -26,11 +27,11 @@ class SearchEmailInteractor { Set? sort, Filter? filter, Properties? properties, - bool isRefreshChange = false, + bool needRefreshSearchState = false, } ) async* { try { - if (isRefreshChange) { + if (needRefreshSearchState) { yield Right(RefreshingSearchState()); } else { yield Right(SearchingState()); diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index bac4ccf637..d58b75886a 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -111,6 +111,8 @@ class ThreadController extends BaseController with EmailActionController { final ScrollController listEmailController = ScrollController(); final FocusNode focusNodeKeyBoard = FocusNode(); final latestEmailSelectedOrUnselected = Rxn(); + @visibleForTesting + bool isListEmailScrollViewJumping = false; StreamSubscription? _resizeBrowserStreamSubscription; @@ -458,7 +460,9 @@ class ThreadController extends BaseController with EmailActionController { isSearchEmailRunning: searchController.isSearchEmailRunning ); mailboxDashBoardController.updateEmailList(newListEmail); - + if (mailboxDashBoardController.isSelectionEnabled()) { + mailboxDashBoardController.listEmailSelected.value = listEmailSelected; + } canLoadMore = newListEmail.length >= ThreadConstants.maxCountEmails; if (listEmailController.hasClients) { @@ -490,7 +494,9 @@ class ThreadController extends BaseController with EmailActionController { isSearchEmailRunning: searchController.isSearchEmailRunning ); mailboxDashBoardController.updateEmailList(emailListSynced); - + if (mailboxDashBoardController.isSelectionEnabled()) { + mailboxDashBoardController.listEmailSelected.value = listEmailSelected; + } canLoadMore = newListEmail.length >= ThreadConstants.maxCountEmails; if (mailboxDashBoardController.emailsInCurrentMailbox.isEmpty) { @@ -578,7 +584,7 @@ class ThreadController extends BaseController with EmailActionController { void _refreshEmailChanges({jmap.State? currentEmailState}) { log('ThreadController::_refreshEmailChanges(): currentEmailState: $currentEmailState'); if (searchController.isSearchEmailRunning) { - _searchEmail(limit: limitEmailFetched, isRefreshChange: true); + _searchEmail(limit: limitEmailFetched, needRefreshSearchState: true); } else { final newEmailState = currentEmailState ?? _currentEmailState; log('ThreadController::_refreshEmailChanges(): newEmailState: $newEmailState'); @@ -802,12 +808,13 @@ class ThreadController extends BaseController with EmailActionController { searchController.clearTextSearch(); } - void _searchEmail({UnsignedInt? limit, bool isRefreshChange = false}) { + void _searchEmail({UnsignedInt? limit, bool needRefreshSearchState = false}) { if (_session != null && _accountId != null) { - if (!isRefreshChange && listEmailController.hasClients) { + if (!needRefreshSearchState && listEmailController.hasClients) { + isListEmailScrollViewJumping = true; listEmailController.jumpTo(0); } - if (!isRefreshChange) { + if (!needRefreshSearchState) { mailboxDashBoardController.emailsInCurrentMailbox.clear(); } canSearchMore = false; @@ -828,7 +835,7 @@ class ThreadController extends BaseController with EmailActionController { moreFilterCondition: _getFilterCondition() ), properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!), - isRefreshChange: isRefreshChange + needRefreshSearchState: needRefreshSearchState )); } else { consumeState(Stream.value(Left(SearchEmailFailure(NotFoundSessionException())))); @@ -868,7 +875,9 @@ class ThreadController extends BaseController with EmailActionController { isSearchEmailRunning: searchController.isSearchEmailRunning ); mailboxDashBoardController.updateEmailList(newEmailListSynced); - + if (mailboxDashBoardController.isSelectionEnabled()) { + mailboxDashBoardController.listEmailSelected.value = listEmailSelected; + } canSearchMore = newEmailListSynced.length >= ThreadConstants.maxCountEmails; if (PlatformInfo.isWeb) { diff --git a/test/features/thread/presentation/controller/thread_controller_test.dart b/test/features/thread/presentation/controller/thread_controller_test.dart index 7a1385f1dd..094c73e95b 100644 --- a/test/features/thread/presentation/controller/thread_controller_test.dart +++ b/test/features/thread/presentation/controller/thread_controller_test.dart @@ -1,38 +1,55 @@ import 'package:core/data/network/config/dynamic_url_interceptors.dart'; import 'package:core/presentation/resources/image_paths.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:core/utils/application_manager.dart'; +import 'package:dartz/dartz.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; +import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import 'package:model/email/mark_star_action.dart'; import 'package:model/email/presentation_email.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:model/mailbox/select_mode.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart'; +import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; +import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.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/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/search_email_filter.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/features/network_connection/presentation/network_connection_controller.dart'; +import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart'; +import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; +import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/get_email_by_id_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/get_emails_in_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/load_more_emails_in_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/search_email_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/usecases/search_more_email_interactor.dart'; +import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart'; import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; import 'package:tmail_ui_user/main/utils/toast_manager.dart'; import 'package:uuid/uuid.dart'; +import '../../../../fixtures/account_fixtures.dart'; +import '../../../../fixtures/session_fixtures.dart'; import 'thread_controller_test.mocks.dart'; mockControllerCallback() => InternalFinalCallback(callback: () {}); @@ -239,5 +256,167 @@ void main() { expect(result.isEmpty, isTrue); }); }); + + group('_refreshEmailChanges::test', () { + test( + 'WHEN thread controller in searching\n' + 'AND `MarkAsStarEmailSuccess` is coming\n' + 'THEN `SearchEmailInteractor` is invoked with proper arguments\n' + 'AND `listEmailController` should not jumped\n' + 'AND `mailboxDashBoardController.emailsInCurrentMailbox` should not be cleared', + () async { + // Arrange + final updatedEmail = Email( + id: EmailId(Id('email1')), + keywords: {KeyWordIdentifier.emailFlagged: true} + ); + final emailList = [ + PresentationEmail( + id: EmailId(Id('email1')), + subject: 'hello', + keywords: {KeyWordIdentifier.emailFlagged: true}), + PresentationEmail( + id: EmailId(Id('email2')), + subject: 'hello') + ]; + + when(mockMailboxDashBoardController.sessionCurrent).thenReturn(SessionFixtures.aliceSession); + when(mockMailboxDashBoardController.accountId).thenReturn(Rxn(AccountFixtures.aliceAccountId)); + when(mockMailboxDashBoardController.viewState).thenReturn(Rx(Right(SearchEmailSuccess(emailList)))); + when(mockMailboxDashBoardController.emailsInCurrentMailbox).thenReturn(RxList(emailList)); + when(mockMailboxDashBoardController.selectedMailbox).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.searchController).thenReturn(mockSearchController); + when(mockMailboxDashBoardController.dashBoardAction).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.emailUIAction).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.viewState).thenReturn(Rx(Right(UIState.idle))); + when(mockMailboxDashBoardController.filterMessageOption).thenReturn(Rx(FilterMessageOption.all)); + when(mockSearchController.searchState).thenReturn(Rx(SearchState.initial())); + when(mockSearchController.isAdvancedSearchViewOpen).thenReturn(RxBool(false)); + when(mockSearchController.isSearchEmailRunning).thenReturn(true); + when(mockSearchController.searchEmailFilter).thenReturn(Rx(SearchEmailFilter.initial())); + when(mockSearchEmailInteractor.execute( + any, + any, + limit: anyNamed('limit'), + position: anyNamed('position'), + sort:anyNamed('sort'), + filter: anyNamed('filter'), + properties: anyNamed('properties'), + needRefreshSearchState: anyNamed('needRefreshSearchState'), + )).thenAnswer((_) => Stream.value(Right(SearchEmailSuccess(emailList)))); + + // Act + threadController.onInit(); + + final markAsStarEmailSuccess = MarkAsStarEmailSuccess( + updatedEmail, + MarkStarAction.markStar); + mockMailboxDashBoardController.viewState.value = Right(markAsStarEmailSuccess); + + await untilCalled(mockSearchEmailInteractor.execute( + any, + any, + limit: anyNamed('limit'), + position: anyNamed('position'), + sort:anyNamed('sort'), + filter: anyNamed('filter'), + properties: anyNamed('properties'), + needRefreshSearchState: anyNamed('needRefreshSearchState'), + )); + + // Assert + verify(mockSearchEmailInteractor.execute( + SessionFixtures.aliceSession, + AccountFixtures.aliceAccountId, + limit: UnsignedInt(emailList.length), + position: null, + sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(), + filter: SearchEmailFilter.initial().mappingToEmailFilterCondition(), + properties: EmailUtils.getPropertiesForEmailGetMethod( + SessionFixtures.aliceSession, + AccountFixtures.aliceAccountId), + needRefreshSearchState: true + )).called(1); + expect(mockMailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty, isTrue); + expect(mockMailboxDashBoardController.emailsInCurrentMailbox.length, emailList.length); + expect(threadController.isListEmailScrollViewJumping, isFalse); + }); + + test( + 'WHEN thread controller in searching\n' + 'AND `StartSearchEmailAction` is coming\n' + 'THEN `SearchEmailInteractor` is invoked with proper arguments\n' + 'AND `listEmailController` should jumped\n' + 'AND `mailboxDashBoardController.emailsInCurrentMailbox` should be cleared', + () async { + // Arrange + final emailList = [ + PresentationEmail( + id: EmailId(Id('email1')), + subject: 'hello'), + PresentationEmail( + id: EmailId(Id('email2')), + subject: 'hello') + ]; + + when(mockMailboxDashBoardController.sessionCurrent).thenReturn(SessionFixtures.aliceSession); + when(mockMailboxDashBoardController.accountId).thenReturn(Rxn(AccountFixtures.aliceAccountId)); + when(mockMailboxDashBoardController.viewState).thenReturn(Rx(Right(SearchEmailSuccess(emailList)))); + when(mockMailboxDashBoardController.emailsInCurrentMailbox).thenReturn(RxList(emailList)); + when(mockMailboxDashBoardController.selectedMailbox).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.searchController).thenReturn(mockSearchController); + when(mockMailboxDashBoardController.dashBoardAction).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.emailUIAction).thenReturn(Rxn(null)); + when(mockMailboxDashBoardController.viewState).thenReturn(Rx(Right(UIState.idle))); + when(mockMailboxDashBoardController.filterMessageOption).thenReturn(Rx(FilterMessageOption.all)); + when(mockMailboxDashBoardController.currentSelectMode).thenReturn(Rx(SelectMode.INACTIVE)); + when(mockMailboxDashBoardController.listEmailSelected).thenReturn(RxList([])); + when(mockSearchController.searchState).thenReturn(Rx(SearchState.initial())); + when(mockSearchController.isAdvancedSearchViewOpen).thenReturn(RxBool(false)); + when(mockSearchController.isSearchEmailRunning).thenReturn(true); + when(mockSearchController.searchEmailFilter).thenReturn(Rx(SearchEmailFilter.initial())); + when(mockSearchEmailInteractor.execute( + any, + any, + limit: anyNamed('limit'), + position: anyNamed('position'), + sort:anyNamed('sort'), + filter: anyNamed('filter'), + properties: anyNamed('properties'), + needRefreshSearchState: anyNamed('needRefreshSearchState'), + )).thenAnswer((_) => Stream.value(Right(SearchEmailSuccess(emailList)))); + + // Act + threadController.onInit(); + mockMailboxDashBoardController.dashBoardAction.value = StartSearchEmailAction(); + + await untilCalled(mockSearchEmailInteractor.execute( + any, + any, + limit: anyNamed('limit'), + position: anyNamed('position'), + sort:anyNamed('sort'), + filter: anyNamed('filter'), + properties: anyNamed('properties'), + needRefreshSearchState: anyNamed('needRefreshSearchState'), + )); + + // Assert + verify(mockSearchEmailInteractor.execute( + SessionFixtures.aliceSession, + AccountFixtures.aliceAccountId, + limit: ThreadConstants.defaultLimit, + position: null, + sort: EmailSortOrderType.mostRecent.getSortOrder().toNullable(), + filter: SearchEmailFilter.initial().mappingToEmailFilterCondition(), + properties: EmailUtils.getPropertiesForEmailGetMethod( + SessionFixtures.aliceSession, + AccountFixtures.aliceAccountId), + needRefreshSearchState: false + )).called(1); + expect(mockMailboxDashBoardController.emailsInCurrentMailbox.isEmpty, isTrue); + expect(mockMailboxDashBoardController.emailsInCurrentMailbox.length, equals(0)); + }); + }); }); } \ No newline at end of file