From f1fda99ff58e3d08f8f348ea3ce6627a030bbc13 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 16 May 2024 11:39:04 +0700 Subject: [PATCH] TF-825 Synchronize download messages as EML like download attachments --- .../data/datasource/email_datasource.dart | 9 - .../email_datasource_impl.dart | 19 -- .../email_hive_cache_datasource_impl.dart | 12 - .../email/data/network/email_api.dart | 49 +---- .../repository/email_repository_impl.dart | 17 -- .../email/data/utils/download_utils.dart | 60 ----- .../domain/exceptions/email_exceptions.dart | 2 - .../domain/repository/email_repository.dart | 9 - .../download_attachment_for_web_state.dart | 7 +- .../state/download_message_as_eml_state.dart | 11 - .../state/view_attachment_for_web_state.dart | 2 +- ...ownload_attachment_for_web_interactor.dart | 2 +- .../download_message_as_eml_interactor.dart | 66 ------ .../view_attachment_for_web_interactor.dart | 2 +- .../presentation/bindings/email_bindings.dart | 9 +- .../controller/single_email_controller.dart | 52 ++--- lib/l10n/intl_messages.arb | 6 +- lib/main/bindings/core/core_bindings.dart | 2 - .../bindings/network/network_bindings.dart | 2 - .../network/network_isolate_binding.dart | 4 +- lib/main/localizations/app_localizations.dart | 6 +- model/lib/email/eml_attachment.dart | 15 ++ .../presentation_email_extension.dart | 11 + pubspec.lock | 2 +- pubspec.yaml | 2 - .../email/data/network/email_api_test.dart | 206 ------------------ .../email/data/utils/download_utils_test.dart | 81 ------- ...ew_attachment_for_web_interactor_test.dart | 4 +- .../single_email_controller_test.dart | 4 - .../authorization_interceptor_test.dart | 2 +- 30 files changed, 58 insertions(+), 617 deletions(-) delete mode 100644 lib/features/email/data/utils/download_utils.dart delete mode 100644 lib/features/email/domain/state/download_message_as_eml_state.dart delete mode 100644 lib/features/email/domain/usecases/download_message_as_eml_interactor.dart create mode 100644 model/lib/email/eml_attachment.dart delete mode 100644 test/features/email/data/network/email_api_test.dart delete mode 100644 test/features/email/data/utils/download_utils_test.dart diff --git a/lib/features/email/data/datasource/email_datasource.dart b/lib/features/email/data/datasource/email_datasource.dart index 28597f22f9..db3d4c2832 100644 --- a/lib/features/email/data/datasource/email_datasource.dart +++ b/lib/features/email/data/datasource/email_datasource.dart @@ -9,7 +9,6 @@ import 'package:dio/dio.dart'; import 'package:email_recovery/email_recovery/email_recovery_action.dart'; import 'package:email_recovery/email_recovery/email_recovery_action_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -113,12 +112,4 @@ abstract class EmailDataSource { Future restoreDeletedMessage(RestoredDeletedMessageRequest restoredDeletedMessageRequest); Future getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId); - - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail - ); } \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/email_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_datasource_impl.dart index f93817c1e0..76a5e7ee83 100644 --- a/lib/features/email/data/datasource_impl/email_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_datasource_impl.dart @@ -10,7 +10,6 @@ import 'package:email_recovery/email_recovery/email_recovery_action.dart'; import 'package:email_recovery/email_recovery/email_recovery_action_id.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -253,22 +252,4 @@ class EmailDataSourceImpl extends EmailDataSource { return await emailAPI.getRestoredDeletedMessage(emailRecoveryActionId); }).catchError(_exceptionThrower.throwException); } - - @override - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail - ) { - return Future.sync(() async { - return await emailAPI.downloadMessageAsEML( - accountId, - baseDownloadUrl, - accountRequest, - blobId, - subjectEmail); - }).catchError(_exceptionThrower.throwException); - } } \ No newline at end of file diff --git a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart index b5c03f6550..c188147467 100644 --- a/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart @@ -12,7 +12,6 @@ import 'package:dio/dio.dart'; import 'package:email_recovery/email_recovery/email_recovery_action.dart'; import 'package:email_recovery/email_recovery/email_recovery_action_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -304,15 +303,4 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource { Future getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId) { throw UnimplementedError(); } - - @override - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail - ) { - throw UnimplementedError(); - } } \ No newline at end of file diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index deffe3f05d..2540ba130b 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -59,7 +59,6 @@ import 'package:path_provider/path_provider.dart'; import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart'; import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; @@ -77,15 +76,8 @@ class EmailAPI with HandleSetErrorMixin { final DownloadManager _downloadManager; final DioClient _dioClient; final Uuid _uuid; - final DownloadUtils _downloadUtils; - EmailAPI( - this._httpClient, - this._downloadManager, - this._dioClient, - this._uuid, - this._downloadUtils, - ); + EmailAPI(this._httpClient, this._downloadManager, this._dioClient, this._uuid); Future getEmailContent(Session session, AccountId accountId, EmailId emailId) async { final processingInvocation = ProcessingInvocation(); @@ -742,43 +734,4 @@ class EmailAPI with HandleSetErrorMixin { throw NotFoundEmailRecoveryActionException(); } } - - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail, - ) async { - final authentication = accountRequest.authenticationType == AuthenticationType.oidc - ? accountRequest.bearerToken - : accountRequest.basicAuth; - - final fileName = _downloadUtils.createEMLFileName(subjectEmail); - - final downloadUrl = _downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: subjectEmail - ); - - final headerParam = _dioClient.getHeaders(); - headerParam[HttpHeaders.authorizationHeader] = authentication; - headerParam[HttpHeaders.acceptHeader] = DioClient.jmapHeader; - - final result = await _dioClient.get( - downloadUrl, - options: Options( - headers: headerParam, - responseType: ResponseType.bytes - ) - ); - - if (result is Uint8List) { - _downloadManager.createAnchorElementDownloadFileWeb(result, fileName); - } else { - throw NotFoundByteFileDownloadedException(); - } - } } \ No newline at end of file diff --git a/lib/features/email/data/repository/email_repository_impl.dart b/lib/features/email/data/repository/email_repository_impl.dart index 276752e73b..014bca06ba 100644 --- a/lib/features/email/data/repository/email_repository_impl.dart +++ b/lib/features/email/data/repository/email_repository_impl.dart @@ -11,7 +11,6 @@ import 'package:dio/dio.dart'; import 'package:email_recovery/email_recovery/email_recovery_action.dart'; import 'package:email_recovery/email_recovery/email_recovery_action_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -238,20 +237,4 @@ class EmailRepositoryImpl extends EmailRepository { Future printEmail(EmailPrint emailPrint) { return _printFileDataSource.printEmail(emailPrint); } - - @override - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail - ) { - return emailDataSource[DataSourceType.network]!.downloadMessageAsEML( - accountId, - baseDownloadUrl, - accountRequest, - blobId, - subjectEmail); - } } \ No newline at end of file diff --git a/lib/features/email/data/utils/download_utils.dart b/lib/features/email/data/utils/download_utils.dart deleted file mode 100644 index 970035180c..0000000000 --- a/lib/features/email/data/utils/download_utils.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:core/data/constants/constant.dart'; -import 'package:core/utils/app_logger.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:model/extensions/account_id_extensions.dart'; -import 'package:uri/uri.dart'; -import 'package:uuid/uuid.dart'; - -class DownloadUtils { - static const String accountIdProperty = 'accountId'; - static const String blobIdProperty = 'blobId'; - static const String nameProperty = 'name'; - static const String typeProperty = 'type'; - - final Uuid _uuid; - - DownloadUtils(this._uuid); - - String getDownloadUrl({ - required String baseDownloadUrl, - required AccountId accountId, - required Id blobId, - String? fileName, - String? mimeType, - }) { - final downloadUriTemplate = UriTemplate(baseDownloadUrl); - final downloadUri = downloadUriTemplate.expand({ - accountIdProperty : accountId.asString, - blobIdProperty : blobId.value, - nameProperty : fileName ?? '', - typeProperty : mimeType ?? '', - }); - final downloadUriDecoded = Uri.decodeFull(downloadUri); - log('DownloadUtils::getDownloadUrl: $downloadUriDecoded'); - return downloadUriDecoded; - } - - String getEMLDownloadUrl({ - required String baseDownloadUrl, - required AccountId accountId, - required Id blobId, - required String subject, - }) { - final fileName = createEMLFileName(subject); - - final downloadUrl = getDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - fileName: fileName, - mimeType: Constant.octetStreamMimeType - ); - log('DownloadUtils::getEMLDownloadUrl: $downloadUrl'); - return downloadUrl; - } - - String createEMLFileName(String subject) { - return subject.isEmpty ? '${_uuid.v1()}.eml' : '$subject.eml'; - } -} \ No newline at end of file diff --git a/lib/features/email/domain/exceptions/email_exceptions.dart b/lib/features/email/domain/exceptions/email_exceptions.dart index 37ab4d3f89..8057441639 100644 --- a/lib/features/email/domain/exceptions/email_exceptions.dart +++ b/lib/features/email/domain/exceptions/email_exceptions.dart @@ -6,6 +6,4 @@ class EmptyEmailContentException implements Exception {} class NotFoundEmailRecoveryActionException implements Exception {} -class NotFoundByteFileDownloadedException implements Exception {} - class NotFoundEmailBlobIdException implements Exception {} \ No newline at end of file diff --git a/lib/features/email/domain/repository/email_repository.dart b/lib/features/email/domain/repository/email_repository.dart index 298ebc5bc6..53bb1daf5f 100644 --- a/lib/features/email/domain/repository/email_repository.dart +++ b/lib/features/email/domain/repository/email_repository.dart @@ -10,7 +10,6 @@ import 'package:dio/dio.dart'; import 'package:email_recovery/email_recovery/email_recovery_action.dart'; import 'package:email_recovery/email_recovery/email_recovery_action_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -116,12 +115,4 @@ abstract class EmailRepository { Future getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId); Future printEmail(EmailPrint emailPrint); - - Future downloadMessageAsEML( - AccountId accountId, - String baseDownloadUrl, - AccountRequest accountRequest, - Id blobId, - String subjectEmail - ); } \ No newline at end of file diff --git a/lib/features/email/domain/state/download_attachment_for_web_state.dart b/lib/features/email/domain/state/download_attachment_for_web_state.dart index 72082f0571..77fcc7c9b6 100644 --- a/lib/features/email/domain/state/download_attachment_for_web_state.dart +++ b/lib/features/email/domain/state/download_attachment_for_web_state.dart @@ -1,7 +1,6 @@ import 'dart:typed_data'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:model/download/download_task_id.dart'; import 'package:model/email/attachment.dart'; @@ -59,14 +58,14 @@ class DownloadAttachmentForWebSuccess extends UIState { class DownloadAttachmentForWebFailure extends FeatureFailure { final DownloadTaskId? taskId; - final Id? attachmentBlobId; + final Attachment? attachment; DownloadAttachmentForWebFailure({ - required this.attachmentBlobId, + this.attachment, this.taskId, dynamic exception }) : super(exception: exception); @override - List get props => [taskId, ...super.props]; + List get props => [attachment, taskId, ...super.props]; } \ No newline at end of file diff --git a/lib/features/email/domain/state/download_message_as_eml_state.dart b/lib/features/email/domain/state/download_message_as_eml_state.dart deleted file mode 100644 index a6dcf74306..0000000000 --- a/lib/features/email/domain/state/download_message_as_eml_state.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class StartDownloadMessageAsEML extends LoadingState {} - -class DownloadMessageAsEMLSuccess extends UIState {} - -class DownloadMessageAsEMLFailure extends FeatureFailure { - - DownloadMessageAsEMLFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/email/domain/state/view_attachment_for_web_state.dart b/lib/features/email/domain/state/view_attachment_for_web_state.dart index d1e812465a..96dcaab065 100644 --- a/lib/features/email/domain/state/view_attachment_for_web_state.dart +++ b/lib/features/email/domain/state/view_attachment_for_web_state.dart @@ -22,7 +22,7 @@ class ViewAttachmentForWebSuccess extends DownloadAttachmentForWebSuccess { class ViewAttachmentForWebFailure extends DownloadAttachmentForWebFailure { ViewAttachmentForWebFailure({ - required super.attachmentBlobId, + required super.attachment, super.taskId, super.exception, }); diff --git a/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart b/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart index 9e7b820887..3715d76478 100644 --- a/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart +++ b/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart @@ -72,7 +72,7 @@ class DownloadAttachmentForWebInteractor { } catch (exception) { yield Left( DownloadAttachmentForWebFailure( - attachmentBlobId: attachment.blobId, + attachment: attachment, taskId: taskId, exception: exception ) diff --git a/lib/features/email/domain/usecases/download_message_as_eml_interactor.dart b/lib/features/email/domain/usecases/download_message_as_eml_interactor.dart deleted file mode 100644 index d22cf7b76d..0000000000 --- a/lib/features/email/domain/usecases/download_message_as_eml_interactor.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'dart:async'; - -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/id.dart'; -import 'package:jmap_dart_client/jmap/core/user_name.dart'; -import 'package:model/account/account_request.dart'; -import 'package:model/account/authentication_type.dart'; -import 'package:model/account/password.dart'; -import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; -import 'package:tmail_ui_user/features/email/domain/state/download_message_as_eml_state.dart'; -import 'package:tmail_ui_user/features/login/domain/repository/account_repository.dart'; -import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart'; -import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; - -class DownloadMessageAsEMLInteractor { - final EmailRepository _emailRepository; - final CredentialRepository _credentialRepository; - final AccountRepository _accountRepository; - final AuthenticationOIDCRepository _authenticationOIDCRepository; - - DownloadMessageAsEMLInteractor( - this._emailRepository, - this._credentialRepository, - this._accountRepository, - this._authenticationOIDCRepository - ); - - Stream> execute( - AccountId accountId, - String baseDownloadUrl, - Id blobId, - String subjectEmail - ) async* { - try { - yield Right(StartDownloadMessageAsEML()); - - final currentAccount = await _accountRepository.getCurrentAccount(); - AccountRequest? accountRequest; - - if (currentAccount.authenticationType == AuthenticationType.oidc) { - final tokenOidc = await _authenticationOIDCRepository.getStoredTokenOIDC(currentAccount.id); - accountRequest = AccountRequest.withOidc(token: tokenOidc); - } else { - final authenticationInfoCache = await _credentialRepository.getAuthenticationInfoStored(); - accountRequest = AccountRequest.withBasic( - userName: UserName(authenticationInfoCache.username), - password: Password(authenticationInfoCache.password), - ); - } - - await _emailRepository.downloadMessageAsEML( - accountId, - baseDownloadUrl, - accountRequest, - blobId, - subjectEmail); - - yield Right(DownloadMessageAsEMLSuccess()); - } catch (exception) { - yield Left(DownloadMessageAsEMLFailure(exception)); - } - } -} \ No newline at end of file diff --git a/lib/features/email/domain/usecases/view_attachment_for_web_interactor.dart b/lib/features/email/domain/usecases/view_attachment_for_web_interactor.dart index f69ff81d82..fc318bf9e3 100644 --- a/lib/features/email/domain/usecases/view_attachment_for_web_interactor.dart +++ b/lib/features/email/domain/usecases/view_attachment_for_web_interactor.dart @@ -34,7 +34,7 @@ class ViewAttachmentForWebInteractor { (failure) { if (failure is DownloadAttachmentForWebFailure) { return Left(ViewAttachmentForWebFailure( - attachmentBlobId: attachment.blobId, + attachment: attachment, taskId: failure.taskId, exception: failure.exception, )); diff --git a/lib/features/email/presentation/bindings/email_bindings.dart b/lib/features/email/presentation/bindings/email_bindings.dart index dcdcabb6df..19f0b8aeba 100644 --- a/lib/features/email/presentation/bindings/email_bindings.dart +++ b/lib/features/email/presentation/bindings/email_bindings.dart @@ -14,7 +14,6 @@ import 'package:tmail_ui_user/features/email/data/repository/email_repository_im import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart'; -import 'package:tmail_ui_user/features/email/domain/usecases/download_message_as_eml_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_stored_email_state_interactor.dart'; @@ -70,8 +69,7 @@ class EmailBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find(), - Get.find(), + Get.find() )); } @@ -154,11 +152,6 @@ class EmailBindings extends BaseBindings { Get.find())); Get.lazyPut(() => StoreOpenedEmailInteractor(Get.find())); Get.lazyPut(() => PrintEmailInteractor(Get.find())); - Get.lazyPut(() => DownloadMessageAsEMLInteractor( - Get.find(), - Get.find(), - Get.find(), - Get.find())); IdentityInteractorsBindings().dependencies(); } diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 1d97a9afb2..4c81c87ee6 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -20,6 +20,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mdn/disposition.dart'; import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; import 'package:mime/mime.dart'; +import 'package:model/email/eml_attachment.dart'; import 'package:model/model.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; @@ -43,7 +44,6 @@ import 'package:tmail_ui_user/features/email/domain/state/calendar_event_reject_ import 'package:tmail_ui_user/features/email/domain/state/calendar_event_reply_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/download_attachment_for_web_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/download_attachments_state.dart'; -import 'package:tmail_ui_user/features/email/domain/state/download_message_as_eml_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; @@ -59,7 +59,6 @@ import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_even import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_reject_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart'; -import 'package:tmail_ui_user/features/email/domain/usecases/download_message_as_eml_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; @@ -126,7 +125,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin { final StoreOpenedEmailInteractor _storeOpenedEmailInteractor; final ViewAttachmentForWebInteractor _viewAttachmentForWebInteractor; final PrintEmailInteractor _printEmailInteractor; - final DownloadMessageAsEMLInteractor _downloadMessageAsEMLInteractor; CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor; SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor; @@ -175,7 +173,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin { this._storeOpenedEmailInteractor, this._viewAttachmentForWebInteractor, this._printEmailInteractor, - this._downloadMessageAsEMLInteractor, ); @override @@ -236,8 +233,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin { _handlePrintEmailSuccess(success); } else if (success is CalendarEventReplySuccess) { _calendarEventSuccess(success); - } else if (success is StartDownloadMessageAsEML) { - _showMessageWhenStartingDownloadMessageAsEML(); } } @@ -817,7 +812,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { } else { consumeState(Stream.value( Left(DownloadAttachmentForWebFailure( - attachmentBlobId: attachment.blobId, + attachment: attachment, exception: NotFoundSessionException())) )); } @@ -838,7 +833,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin { } else { consumeState(Stream.value( Left(ViewAttachmentForWebFailure( - attachmentBlobId: attachment.blobId, + attachment: attachment, exception: NotFoundSessionException())) )); } @@ -883,12 +878,16 @@ class SingleEmailController extends BaseController with AppLoaderMixin { mailboxDashBoardController.deleteDownloadTask(failure.taskId!); } - _updateAttachmentsViewState(failure.attachmentBlobId, Left(failure)); + if (failure.attachment != null) { + _updateAttachmentsViewState(failure.attachment?.blobId, Left(failure)); + } if (currentOverlayContext != null && currentContext != null) { appToast.showToastErrorMessage( currentOverlayContext!, - AppLocalizations.of(currentContext!).attachment_download_failed); + failure.attachment is EMLAttachment + ? AppLocalizations.of(currentContext!).downloadMessageAsEMLFailed + : AppLocalizations.of(currentContext!).attachment_download_failed); } } @@ -1784,37 +1783,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin { } void _downloadMessageAsEML(PresentationEmail presentationEmail) { - final accountId = mailboxDashBoardController.accountId.value; - final session = mailboxDashBoardController.sessionCurrent; - - if (accountId == null || session == null) { - consumeState(Stream.value(Left(DownloadMessageAsEMLFailure(NotFoundSessionException())))); - return; - } - - final blobId = presentationEmail.blobId; - if (blobId == null) { - consumeState(Stream.value(Left(DownloadMessageAsEMLFailure(NotFoundEmailBlobIdException())))); + final emlAttachment = presentationEmail.createEMLAttachment(); + if (emlAttachment.blobId == null) { + consumeState(Stream.value(Left(DownloadAttachmentForWebFailure(exception: NotFoundEmailBlobIdException())))); return; } - final baseDownloadUrl = session.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl); - - consumeState(_downloadMessageAsEMLInteractor.execute( - accountId, - baseDownloadUrl, - blobId, - presentationEmail.getEmailTitle() - )); - } - - void _showMessageWhenStartingDownloadMessageAsEML() { - if (currentOverlayContext != null && currentContext != null) { - appToast.showToastMessage( - currentOverlayContext!, - AppLocalizations.of(currentContext!).downloadMessageAsEMLInProgress, - leadingSVGIconColor: AppColor.primaryColor, - leadingSVGIcon: imagePaths.icDownloadAttachment); - } + downloadAttachmentForWeb(emlAttachment); } } \ No newline at end of file diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 29fadaca47..81ce7423e4 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2024-05-15T11:16:30.181676", + "@@last_modified": "2024-05-16T11:36:53.008027", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -3726,8 +3726,8 @@ "placeholders_order": [], "placeholders": {} }, - "downloadMessageAsEMLInProgress": "Download message as EML in progress", - "@downloadMessageAsEMLInProgress": { + "downloadMessageAsEMLFailed": "Download message as EML failed", + "@downloadMessageAsEMLFailed": { "type": "text", "placeholders_order": [], "placeholders": {} diff --git a/lib/main/bindings/core/core_bindings.dart b/lib/main/bindings/core/core_bindings.dart index 65f585edc3..389a91fcb9 100644 --- a/lib/main/bindings/core/core_bindings.dart +++ b/lib/main/bindings/core/core_bindings.dart @@ -11,7 +11,6 @@ import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; @@ -63,7 +62,6 @@ class CoreBindings extends Bindings { Get.put(AppConfigLoader()); Get.put(FileUtils()); Get.put(PrintUtils()); - Get.put(DownloadUtils(Get.find())); } void _bindingIsolate() { diff --git a/lib/main/bindings/network/network_bindings.dart b/lib/main/bindings/network/network_bindings.dart index 203244aab9..2a015626b8 100644 --- a/lib/main/bindings/network/network_bindings.dart +++ b/lib/main/bindings/network/network_bindings.dart @@ -13,7 +13,6 @@ import 'package:jmap_dart_client/http/http_client.dart'; import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; import 'package:tmail_ui_user/features/home/data/network/session_api.dart'; import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart'; import 'package:tmail_ui_user/features/login/data/local/authentication_info_cache_manager.dart'; @@ -112,7 +111,6 @@ class NetworkBindings extends Bindings { Get.find(), Get.find(), Get.find(), - Get.find(), )); Get.put(RuleFilterAPI(Get.find())); Get.put(VacationAPI(Get.find())); diff --git a/lib/main/bindings/network/network_isolate_binding.dart b/lib/main/bindings/network/network_isolate_binding.dart index 66ebe59386..91f8862b5e 100644 --- a/lib/main/bindings/network/network_isolate_binding.dart +++ b/lib/main/bindings/network/network_isolate_binding.dart @@ -6,7 +6,6 @@ import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/http/http_client.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart'; import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart'; import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_base.dart'; @@ -64,8 +63,7 @@ class NetworkIsolateBindings extends Bindings { httpClient, Get.find(tag: BindingTag.isolateTag), Get.find(tag: BindingTag.isolateTag), - Get.find(), - Get.find(), + Get.find() ), tag: BindingTag.isolateTag); } diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index d16eb61415..2f8f746615 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -3887,10 +3887,10 @@ class AppLocalizations { ); } - String get downloadMessageAsEMLInProgress { + String get downloadMessageAsEMLFailed { return Intl.message( - 'Download message as EML in progress', - name: 'downloadMessageAsEMLInProgress' + 'Download message as EML failed', + name: 'downloadMessageAsEMLFailed', ); } } \ No newline at end of file diff --git a/model/lib/email/eml_attachment.dart b/model/lib/email/eml_attachment.dart new file mode 100644 index 0000000000..08189e14be --- /dev/null +++ b/model/lib/email/eml_attachment.dart @@ -0,0 +1,15 @@ + +import 'package:model/email/attachment.dart'; + +class EMLAttachment extends Attachment { + + EMLAttachment({ + super.partId, + super.blobId, + super.size, + super.name, + super.type, + super.cid, + super.disposition, + }); +} \ No newline at end of file diff --git a/model/lib/extensions/presentation_email_extension.dart b/model/lib/extensions/presentation_email_extension.dart index e16c7e05a7..1ca8061f4b 100644 --- a/model/lib/extensions/presentation_email_extension.dart +++ b/model/lib/extensions/presentation_email_extension.dart @@ -1,14 +1,17 @@ import 'dart:ui'; +import 'package:core/data/constants/constant.dart'; import 'package:core/domain/extensions/datetime_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:http_parser/http_parser.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:dartz/dartz.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/email/email_action_type.dart'; +import 'package:model/email/eml_attachment.dart'; import 'package:model/email/presentation_email.dart'; import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/list_email_address_extension.dart'; @@ -269,4 +272,12 @@ extension PresentationEmailExtension on PresentationEmail { return false; } + + EMLAttachment createEMLAttachment() { + return EMLAttachment( + blobId: blobId, + name: getEmailTitle().isEmpty ? '${blobId?.value}.eml' : '${getEmailTitle()}.eml', + type: MediaType.parse(Constant.octetStreamMimeType) + ); + } } \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index c9a9af4f9c..95382eb089 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1758,7 +1758,7 @@ packages: source: hosted version: "2.2.2" uri: - dependency: "direct main" + dependency: transitive description: name: uri sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" diff --git a/pubspec.yaml b/pubspec.yaml index 41ede2c62a..713b1693ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -232,8 +232,6 @@ dependencies: mime: 1.0.4 - uri: 1.0.0 - dev_dependencies: flutter_test: sdk: flutter diff --git a/test/features/email/data/network/email_api_test.dart b/test/features/email/data/network/email_api_test.dart deleted file mode 100644 index 57ea1d491f..0000000000 --- a/test/features/email/data/network/email_api_test.dart +++ /dev/null @@ -1,206 +0,0 @@ -import 'dart:io'; - -import 'package:core/data/constants/constant.dart'; -import 'package:core/data/network/dio_client.dart'; -import 'package:core/data/network/download/download_manager.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:jmap_dart_client/http/http_client.dart' as jmap; -import 'package:mockito/mockito.dart'; -import 'package:mockito/annotations.dart'; -import 'package:dio/dio.dart'; -import 'package:model/model.dart'; -import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; -import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart'; -import 'package:uuid/uuid.dart'; -import 'dart:typed_data'; - -import 'email_api_test.mocks.dart'; - -@GenerateNiceMocks([ - MockSpec(), - MockSpec(), - MockSpec(), - MockSpec(), - MockSpec(), -]) -void main() { - late MockDioClient dioClient; - late MockDownloadManager downloadManager; - late MockUuid uuid; - late MockHttpClient httpClient; - late MockDownloadUtils downloadUtils; - late EmailAPI emailAPI; - - final accountId = AccountId(Id('abc123')); - const baseDownloadUrl = 'https://example.com/download/{accountId}/{blobId}?type={type}&name={name}'; - final blobId = Id('xyz123'); - - setUp(() { - dioClient = MockDioClient(); - downloadManager = MockDownloadManager(); - uuid = MockUuid(); - httpClient = MockHttpClient(); - downloadUtils = MockDownloadUtils(); - emailAPI = EmailAPI( - httpClient, - downloadManager, - dioClient, - uuid, - downloadUtils - ); - }); - - group('downloadMessageAsEML method test', () { - test('should call createAnchorElementDownloadFileWeb when download email as EML file success and return Uint8List', () async { - final accountRequestFixture = AccountRequest( - authenticationType: AuthenticationType.oidc, - token: TokenOIDC( - 'accessToken', - TokenId('token-id'), - 'refreshToken' - ), - ); - const subjectEmailFixture = 'hello'; - const fileNameFixture = '$subjectEmailFixture.eml'; - final downloadUrlFixture = 'https://example.com/download/${accountId.asString}/${blobId.value}?type=${Constant.octetStreamMimeType}&name=$fileNameFixture'; - final responseFixture = Uint8List.fromList([1, 2, 3, 4]); - - when( - downloadUtils.createEMLFileName(subjectEmailFixture) - ).thenAnswer((_) => fileNameFixture); - - when( - downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: subjectEmailFixture - ) - ).thenAnswer((_) => downloadUrlFixture); - - when(dioClient.getHeaders()).thenAnswer((_) => {}); - - when( - dioClient.get( - any, - options: anyNamed('options'), - ) - ).thenAnswer((_) async => responseFixture); - - await emailAPI.downloadMessageAsEML( - accountId, - baseDownloadUrl, - accountRequestFixture, - blobId, - subjectEmailFixture); - - verify(downloadUtils.createEMLFileName(subjectEmailFixture)).called(1); - - verify( - downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: subjectEmailFixture, - ) - ).called(1); - - verify(dioClient.getHeaders()).called(1); - - verify( - dioClient.get( - downloadUrlFixture, - options: argThat( - isA() - .having((o) => o.headers?[HttpHeaders.authorizationHeader], 'authorization header', accountRequestFixture.bearerToken) - .having((o) => o.headers?[HttpHeaders.acceptHeader], 'accept header', DioClient.jmapHeader) - .having((o) => o.responseType, 'responseType', ResponseType.bytes), - named: 'options', - ), - )).called(1); - - verify( - downloadManager.createAnchorElementDownloadFileWeb( - responseFixture, - fileNameFixture - ) - ).called(1); - }); - - test('should throw an NotFoundByteFileDownloadedException exception if response is not Uint8List', () async { - final accountRequestFixture = AccountRequest( - authenticationType: AuthenticationType.oidc, - token: TokenOIDC( - 'accessToken', - TokenId('token-id'), - 'refreshToken' - ), - ); - const subjectEmailFixture = 'hello'; - const fileNameFixture = '$subjectEmailFixture.eml'; - final downloadUrlFixture = 'https://example.com/download/${accountId.asString}/${blobId.value}?type=${Constant.octetStreamMimeType}&name=$fileNameFixture'; - - when( - downloadUtils.createEMLFileName(subjectEmailFixture) - ).thenAnswer((_) => fileNameFixture); - - when( - downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: subjectEmailFixture - ) - ).thenAnswer((_) => downloadUrlFixture); - - when(dioClient.getHeaders()).thenAnswer((_) => {}); - - when( - dioClient.get( - any, - options: anyNamed('options'), - ) - ).thenAnswer((_) async => 'Unexpected response'); - - expect( - () async => await emailAPI.downloadMessageAsEML( - accountId, - baseDownloadUrl, - accountRequestFixture, - blobId, - subjectEmailFixture - ), - throwsA(isA()), - ); - - verify(downloadUtils.createEMLFileName(subjectEmailFixture)).called(1); - - verify( - downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: subjectEmailFixture, - ) - ).called(1); - - verify(dioClient.getHeaders()).called(1); - - verify( - dioClient.get( - downloadUrlFixture, - options: argThat( - isA() - .having((o) => o.headers?[HttpHeaders.authorizationHeader], 'authorization header', accountRequestFixture.bearerToken) - .having((o) => o.headers?[HttpHeaders.acceptHeader], 'accept header', DioClient.jmapHeader) - .having((o) => o.responseType, 'responseType', ResponseType.bytes), - named: 'options', - ), - ) - ).called(1); - }); - }); -} diff --git a/test/features/email/data/utils/download_utils_test.dart b/test/features/email/data/utils/download_utils_test.dart deleted file mode 100644 index d0ef4517fd..0000000000 --- a/test/features/email/data/utils/download_utils_test.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:jmap_dart_client/jmap/account_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'package:tmail_ui_user/features/email/data/utils/download_utils.dart'; -import 'package:uuid/uuid.dart'; - -import 'download_utils_test.mocks.dart'; - -@GenerateNiceMocks([ - MockSpec(), -]) -void main() { - late MockUuid uuid; - late DownloadUtils downloadUtils; - - final accountId = AccountId(Id('abc123')); - const baseDownloadUrl = 'https://example.com/download/{accountId}/{blobId}?type={type}&name={name}'; - final blobId = Id('xyz123'); - - setUp(() { - uuid = MockUuid(); - downloadUtils = DownloadUtils(uuid); - }); - - group('getDownloadUrl method test', () { - test('should be url decoded correctly in case of fileName & mimeType are not null', () async { - const expectedDownloadUrl = 'https://example.com/download/abc123/xyz123?type=&name='; - - final downloadUrl = downloadUtils.getDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId); - - expect(downloadUrl, expectedDownloadUrl); - }); - - test('should be url decoded correctly in case of fileName & mimeType are null', () async { - const expectedDownloadUrl = 'https://example.com/download/abc123/xyz123?type=application/octet-stream&name=hello.eml'; - - final downloadUrl = downloadUtils.getDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - fileName: 'hello.eml', - mimeType: 'application/octet-stream'); - - expect(downloadUrl, expectedDownloadUrl); - }); - }); - - group('getEMLDownloadUrl method test', () { - test('should be url decoded correctly in case of subject is not empty', () async { - const expectedDownloadUrl = 'https://example.com/download/abc123/xyz123?type=application/octet-stream&name=hello.eml'; - - final downloadUrl = downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: 'hello'); - - expect(downloadUrl, expectedDownloadUrl); - }); - - test('should be url decoded correctly in case of subject is empty', () async { - const nameFixture = '12345678'; - const expectedDownloadUrl = 'https://example.com/download/abc123/xyz123?type=application/octet-stream&name=$nameFixture.eml'; - - when(uuid.v1()).thenAnswer((_) => nameFixture); - - final downloadUrl = downloadUtils.getEMLDownloadUrl( - baseDownloadUrl: baseDownloadUrl, - accountId: accountId, - blobId: blobId, - subject: ''); - - expect(downloadUrl, expectedDownloadUrl); - }); - }); -} diff --git a/test/features/email/domain/usecases/view_attachment_for_web_interactor_test.dart b/test/features/email/domain/usecases/view_attachment_for_web_interactor_test.dart index 6b947149c1..ba4fe053c7 100644 --- a/test/features/email/domain/usecases/view_attachment_for_web_interactor_test.dart +++ b/test/features/email/domain/usecases/view_attachment_for_web_interactor_test.dart @@ -55,7 +55,7 @@ void main() { (_) => Stream.value( Left( DownloadAttachmentForWebFailure( - attachmentBlobId: testAttachment.blobId, + attachment: testAttachment, taskId: testDownloadTaskId, exception: testException, ), @@ -75,7 +75,7 @@ void main() { emitsInOrder([ Left( ViewAttachmentForWebFailure( - attachmentBlobId: testAttachment.blobId, + attachment: testAttachment, taskId: testDownloadTaskId, exception: testException, ), diff --git a/test/features/email/presentation/controller/single_email_controller_test.dart b/test/features/email/presentation/controller/single_email_controller_test.dart index 04eb78cba9..9b0bfc9808 100644 --- a/test/features/email/presentation/controller/single_email_controller_test.dart +++ b/test/features/email/presentation/controller/single_email_controller_test.dart @@ -22,7 +22,6 @@ import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_even import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_reject_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart'; -import 'package:tmail_ui_user/features/email/domain/usecases/download_message_as_eml_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; @@ -82,7 +81,6 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), - MockSpec(), ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -114,7 +112,6 @@ void main() { final responsiveUtils = MockResponsiveUtils(); final uuid = MockUuid(); final printEmailInteractor = MockPrintEmailInteractor(); - final downloadMessageAsEMLInteractor = MockDownloadMessageAsEMLInteractor(); late SingleEmailController singleEmailController; @@ -164,7 +161,6 @@ void main() { storeOpenedEmailInteractor, viewAttachmentForWebInteractor, printEmailInteractor, - downloadMessageAsEMLInteractor, ); }); diff --git a/test/features/interceptor/authorization_interceptor_test.dart b/test/features/interceptor/authorization_interceptor_test.dart index b614309c53..fcc70b1cc5 100644 --- a/test/features/interceptor/authorization_interceptor_test.dart +++ b/test/features/interceptor/authorization_interceptor_test.dart @@ -59,7 +59,7 @@ void main() { }; final baseOption = BaseOptions(headers: headers); dio = Dio(baseOption) - ..options.baseUrl = baseUrl;; + ..options.baseUrl = baseUrl; authenticationClient = MockAuthenticationClientBase(); tokenOidcCacheManager = MockTokenOidcCacheManager();