import 'package:core/data/network/config/dynamic_url_interceptors.dart'; import 'package:core/presentation/resources/image_paths.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: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/mail/email/email.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/presentation_email.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.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/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.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/model/search_query.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/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 'thread_controller_test.mocks.dart'; mockControllerCallback() => InternalFinalCallback(callback: () {}); const fallbackGenerators = { #onStart: mockControllerCallback, #onDelete: mockControllerCallback, }; @GenerateNiceMocks([ // Base controller mock specs MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), // Thread controller mock specs MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(fallbackGenerators: fallbackGenerators), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); // Declaration thread controller late ThreadController threadController; late MockNetworkConnectionController mockNetworkConnectionController; late MockSearchController mockSearchController; late MockMailboxDashBoardController mockMailboxDashBoardController; late MockGetEmailsInMailboxInteractor mockGetEmailsInMailboxInteractor; late MockRefreshChangesEmailsInMailboxInteractor mockRefreshChangesEmailsInMailboxInteractor; late MockLoadMoreEmailsInMailboxInteractor mockLoadMoreEmailsInMailboxInteractor; late MockSearchEmailInteractor mockSearchEmailInteractor; late MockSearchMoreEmailInteractor mockSearchMoreEmailInteractor; late MockGetEmailByIdInteractor mockGetEmailByIdInteractor; // Declaration base controller late MockCachingManager mockCachingManager; late MockLanguageCacheManager 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; late MockApplicationManager mockApplicationManager; late MockToastManager mockToastManager; setUpAll(() { Get.testMode = true; // 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(); mockApplicationManager = MockApplicationManager(); mockToastManager = MockToastManager(); 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.put(mockApplicationManager); Get.put(mockToastManager); // Mock thread controller mockNetworkConnectionController = MockNetworkConnectionController(); mockSearchController = MockSearchController(); mockMailboxDashBoardController = MockMailboxDashBoardController(); mockGetEmailsInMailboxInteractor = MockGetEmailsInMailboxInteractor(); mockRefreshChangesEmailsInMailboxInteractor = MockRefreshChangesEmailsInMailboxInteractor(); mockLoadMoreEmailsInMailboxInteractor = MockLoadMoreEmailsInMailboxInteractor(); mockSearchEmailInteractor = MockSearchEmailInteractor(); mockSearchMoreEmailInteractor = MockSearchMoreEmailInteractor(); mockGetEmailByIdInteractor = MockGetEmailByIdInteractor(); Get.put(mockNetworkConnectionController); Get.put(mockSearchController); Get.put(mockMailboxDashBoardController); threadController = ThreadController( mockGetEmailsInMailboxInteractor, mockRefreshChangesEmailsInMailboxInteractor, mockLoadMoreEmailsInMailboxInteractor, mockSearchEmailInteractor, mockSearchMoreEmailInteractor, mockGetEmailByIdInteractor); }); group('ThreadController::test', () { group('validateListEmailsLoadMore::test', () { final MailboxId selectedMailboxId = MailboxId(Id('mailboxA')); final emailsInCurrentMailbox = []; test('SHOULD returns filtered and synced emails', () { // Arrange final emailList = [ PresentationEmail( id: EmailId(Id('email1')), mailboxIds: {MailboxId(Id('mailbox1')): true}), PresentationEmail( id: EmailId(Id('email2')), mailboxIds: {selectedMailboxId: true}), PresentationEmail( id: EmailId(Id('email3')), mailboxIds: {selectedMailboxId: true}), ]; when(mockMailboxDashBoardController.selectedMailbox).thenReturn(Rxn(PresentationMailbox(selectedMailboxId))); when(mockMailboxDashBoardController.mapMailboxById).thenReturn({}); when(mockMailboxDashBoardController.emailsInCurrentMailbox).thenReturn(RxList(emailsInCurrentMailbox)); when(mockMailboxDashBoardController.searchController).thenReturn(mockSearchController); when(mockSearchController.searchQuery).thenReturn(SearchQuery('')); when(mockSearchController.isSearchEmailRunning).thenReturn(false); // Act final result = threadController.validateListEmailsLoadMore(emailList); // Assert expect(result.length, 2); expect( result.map((e) => e.id).toList(), containsAll([EmailId(Id('email2')), EmailId(Id('email3'))])); }); test('SHOULD filters out duplicated emails', () { // Arrange final emailList = [ PresentationEmail( id: EmailId(Id('email1')), mailboxIds: {MailboxId(Id('mailbox1')): true}), PresentationEmail( id: EmailId(Id('email2')), mailboxIds: {selectedMailboxId: true}), ]; emailsInCurrentMailbox.add( PresentationEmail( id: EmailId(Id('email2')), mailboxIds: {selectedMailboxId: true})); when(mockMailboxDashBoardController.selectedMailbox).thenReturn(Rxn(PresentationMailbox(selectedMailboxId))); when(mockMailboxDashBoardController.mapMailboxById).thenReturn({}); when(mockMailboxDashBoardController.emailsInCurrentMailbox).thenReturn(RxList(emailsInCurrentMailbox)); when(mockMailboxDashBoardController.searchController).thenReturn(mockSearchController); when(mockSearchController.searchQuery).thenReturn(SearchQuery('')); when(mockSearchController.isSearchEmailRunning).thenReturn(false); // Act final result = threadController.validateListEmailsLoadMore(emailList); // Assert expect(result.length, 0); }); test('SHOULD handles empty emailList', () { // Arrange final emailList = []; when(mockMailboxDashBoardController.selectedMailbox).thenReturn(Rxn(PresentationMailbox(selectedMailboxId))); when(mockMailboxDashBoardController.mapMailboxById).thenReturn({}); when(mockMailboxDashBoardController.emailsInCurrentMailbox).thenReturn(RxList(emailsInCurrentMailbox)); when(mockMailboxDashBoardController.searchController).thenReturn(mockSearchController); when(mockSearchController.searchQuery).thenReturn(SearchQuery('')); when(mockSearchController.isSearchEmailRunning).thenReturn(false); // Act final result = threadController.validateListEmailsLoadMore(emailList); // Assert expect(result.isEmpty, isTrue); }); }); }); }