diff --git a/assets/images/ic_subaddressing_allow.svg b/assets/images/ic_subaddressing_allow.svg new file mode 100644 index 000000000..b9162f3b1 --- /dev/null +++ b/assets/images/ic_subaddressing_allow.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_subaddressing_disallow.svg b/assets/images/ic_subaddressing_disallow.svg new file mode 100644 index 000000000..f3d19f3d3 --- /dev/null +++ b/assets/images/ic_subaddressing_disallow.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index 4bf5cc9ac..a7c312c35 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -223,6 +223,8 @@ class ImagePaths { String get icLogoTwakeWelcome => _getImagePath('ic_logo_twake_welcome.svg'); String get icHelp => _getImagePath('ic_help.svg'); String get icDownloadAll => _getImagePath('ic_download_all.svg'); + String get icSubaddressingAllow => _getImagePath('ic_subaddressing_allow.svg'); + String get icSubaddressingDisallow => _getImagePath('ic_subaddressing_disallow.svg'); String _getImagePath(String imageName) { return AssetsPaths.images + imageName; diff --git a/lib/features/base/upgradeable/upgrade_hive_database_steps_v13.dart b/lib/features/base/upgradeable/upgrade_hive_database_steps_v13.dart new file mode 100644 index 000000000..481b8ef40 --- /dev/null +++ b/lib/features/base/upgradeable/upgrade_hive_database_steps_v13.dart @@ -0,0 +1,17 @@ + +import 'package:tmail_ui_user/features/base/upgradeable/upgrade_database_steps.dart'; +import 'package:tmail_ui_user/features/caching/caching_manager.dart'; + +class UpgradeHiveDatabaseStepsV13 extends UpgradeDatabaseSteps { + + final CachingManager _cachingManager; + + UpgradeHiveDatabaseStepsV13(this._cachingManager); + + @override + Future onUpgrade(int oldVersion, int newVersion) async { + if (oldVersion > 0 && oldVersion < newVersion && newVersion == 13) { + await _cachingManager.clearMailboxCache(); + } + } +} \ No newline at end of file diff --git a/lib/features/caching/caching_manager.dart b/lib/features/caching/caching_manager.dart index 613751f07..fb22bc36c 100644 --- a/lib/features/caching/caching_manager.dart +++ b/lib/features/caching/caching_manager.dart @@ -118,6 +118,12 @@ class CachingManager { ], eagerError: true); } + Future clearMailboxCache() { + return Future.wait([ + _mailboxCacheClient.clearAllData(), + ], eagerError: true); + } + Future storeCacheVersion(int newVersion) async { log('CachingManager::storeCacheVersion():newVersion = $newVersion'); return _hiveCacheVersionClient.storeVersion(newVersion); diff --git a/lib/features/caching/config/hive_cache_config.dart b/lib/features/caching/config/hive_cache_config.dart index 0a8b61c47..ea8df229a 100644 --- a/lib/features/caching/config/hive_cache_config.dart +++ b/lib/features/caching/config/hive_cache_config.dart @@ -9,6 +9,7 @@ import 'package:path_provider/path_provider.dart' as path_provider; import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v10.dart'; import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v11.dart'; import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v12.dart'; +import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v13.dart'; import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v7.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/caching/config/cache_version.dart'; @@ -70,6 +71,7 @@ class HiveCacheConfig { await UpgradeHiveDatabaseStepsV10(cachingManager).onUpgrade(oldVersion, newVersion); await UpgradeHiveDatabaseStepsV11(cachingManager).onUpgrade(oldVersion, newVersion); await UpgradeHiveDatabaseStepsV12(cachingManager).onUpgrade(oldVersion, newVersion); + await UpgradeHiveDatabaseStepsV13(cachingManager).onUpgrade(oldVersion, newVersion); if (oldVersion != newVersion) { await cachingManager.storeCacheVersion(newVersion); diff --git a/lib/features/mailbox/data/datasource/mailbox_datasource.dart b/lib/features/mailbox/data/datasource/mailbox_datasource.dart index dc5238178..5a70c5b6e 100644 --- a/lib/features/mailbox/data/datasource/mailbox_datasource.dart +++ b/lib/features/mailbox/data/datasource/mailbox_datasource.dart @@ -18,6 +18,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_ import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; @@ -49,6 +50,8 @@ abstract class MailboxDataSource { Future> subscribeMultipleMailbox(Session session, AccountId accountId, SubscribeMultipleMailboxRequest subscribeRequest); + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request); + Future> createDefaultMailbox(Session session, AccountId accountId, List listRole); Future setRoleDefaultMailbox(Session session, AccountId accountId, List listMailbox); diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart index 3c5496f13..29d609211 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart @@ -23,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_ import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; @@ -134,6 +135,11 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource { throw UnimplementedError(); } + @override + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request) { + throw UnimplementedError(); + } + @override Future> createDefaultMailbox(Session session, AccountId accountId, List listRole) { throw UnimplementedError(); diff --git a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart index fdcd4e7f5..2464f76bd 100644 --- a/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart +++ b/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart @@ -22,6 +22,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_ import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; @@ -121,6 +122,13 @@ class MailboxDataSourceImpl extends MailboxDataSource { }).catchError(_exceptionThrower.throwException); } + @override + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request) { + return Future.sync(() async { + return await mailboxAPI.handleMailboxRightRequest(session, accountId, request); + }).catchError(_exceptionThrower.throwException); + } + @override Future> createDefaultMailbox(Session session, AccountId accountId, List listRole) { return Future.sync(() async { diff --git a/lib/features/mailbox/data/extensions/mailbox_cache_extension.dart b/lib/features/mailbox/data/extensions/mailbox_cache_extension.dart index 84652e112..594eb3e3b 100644 --- a/lib/features/mailbox/data/extensions/mailbox_cache_extension.dart +++ b/lib/features/mailbox/data/extensions/mailbox_cache_extension.dart @@ -20,7 +20,8 @@ extension MailboxCacheExtension on MailboxCache { unreadThreads: unreadThreads != null ? UnreadThreads(UnsignedInt(unreadThreads!)) : null, myRights: myRights?.toMailboxRights(), isSubscribed: isSubscribed != null ? IsSubscribed(isSubscribed!) : null, - namespace: namespace != null ? Namespace(namespace!) : null + namespace: namespace != null ? Namespace(namespace!) : null, + rights: rights != null ? Map?>.from(rights!) : null, ); } } \ No newline at end of file diff --git a/lib/features/mailbox/data/extensions/mailbox_extension.dart b/lib/features/mailbox/data/extensions/mailbox_extension.dart index 6735803fe..965d606a7 100644 --- a/lib/features/mailbox/data/extensions/mailbox_extension.dart +++ b/lib/features/mailbox/data/extensions/mailbox_extension.dart @@ -17,7 +17,8 @@ extension MailboxExtension on Mailbox { unreadThreads: unreadThreads?.value.value.round(), myRights: myRights?.toMailboxRightsCache(), isSubscribed: isSubscribed?.value, - namespace: namespace?.value + namespace: namespace?.value, + rights: rights?.map((key, value) => MapEntry(key, value)), ); } } \ No newline at end of file diff --git a/lib/features/mailbox/data/model/mailbox_cache.dart b/lib/features/mailbox/data/model/mailbox_cache.dart index 05fe3e005..4463e7e45 100644 --- a/lib/features/mailbox/data/model/mailbox_cache.dart +++ b/lib/features/mailbox/data/model/mailbox_cache.dart @@ -48,6 +48,9 @@ class MailboxCache extends HiveObject with EquatableMixin { @HiveField(12) final String? namespace; + @HiveField(13) + final Map?>? rights; + MailboxCache( this.id, { @@ -63,6 +66,7 @@ class MailboxCache extends HiveObject with EquatableMixin { this.isSubscribed, this.lastOpened, this.namespace, + this.rights } ); @@ -80,5 +84,6 @@ class MailboxCache extends HiveObject with EquatableMixin { myRights, isSubscribed, namespace, + rights ]; } \ No newline at end of file diff --git a/lib/features/mailbox/data/network/mailbox_api.dart b/lib/features/mailbox/data/network/mailbox_api.dart index 462b72ebc..5d5332120 100644 --- a/lib/features/mailbox/data/network/mailbox_api.dart +++ b/lib/features/mailbox/data/network/mailbox_api.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:flutter/material.dart' hide State; +import 'package:get/get.dart'; import 'package:jmap_dart_client/http/http_client.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; @@ -26,20 +28,24 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/query/query_mailbox_method.da import 'package:jmap_dart_client/jmap/mail/mailbox/set/set_mailbox_method.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/set/set_mailbox_response.dart'; import 'package:model/error_type_handler/set_method_error_handler_mixin.dart'; +import 'package:model/mailbox/mailbox_constants.dart'; import 'package:model/model.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/mailbox/data/model/mailbox_change_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart'; import 'package:tmail_ui_user/features/mailbox/domain/exceptions/set_mailbox_method_exception.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/exceptions/set_mailbox_rights_exception.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/list_mailbox_id_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/role_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart'; @@ -401,6 +407,53 @@ class MailboxAPI with HandleSetErrorMixin { return listMailboxIdSubscribe ?? []; } + List _updateRightsForSubaddressing(MailboxSubaddressingAction action, List? currentRights) { + final updatedRights = List.from(currentRights ?? []); + + if (action == MailboxSubaddressingAction.allow) { + updatedRights.addIf(!updatedRights.contains(postingRight), postingRight); + } else { + updatedRights.remove(postingRight); + } + + return updatedRights; + } + + @visibleForTesting + List updateRightsForSubaddressing(MailboxSubaddressingAction action, List? currentRights) + => _updateRightsForSubaddressing(action, currentRights); + + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request) async { + final setMailboxMethod = SetMailboxMethod(accountId) + ..addUpdates({ + request.mailboxId.id : PatchObject({ + 'sharedWith/$anyoneIdentifier': _updateRightsForSubaddressing(request.subaddressingAction, request.currentRights?[anyoneIdentifier]) + }) + }); + + final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation()); + + final setMailboxInvocation = requestBuilder.invocation(setMailboxMethod); + + final capabilities = setMailboxMethod.requiredCapabilities + .toCapabilitiesSupportTeamMailboxes(session, accountId); + + final response = await (requestBuilder + ..usings(capabilities)) + .build() + .execute(); + + final setMailboxResponse = response.parse( + setMailboxInvocation.methodCallId, + SetMailboxResponse.deserialize); + + if (setMailboxResponse?.updated?.containsKey(request.mailboxId.id) ?? false) { + return true; + } else { + throw SetMailboxRightsException(); + } + } + Future> createDefaultMailbox( Session session, AccountId accountId, diff --git a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart index 0aa44a660..0ab32b1de 100644 --- a/lib/features/mailbox/data/repository/mailbox_repository_impl.dart +++ b/lib/features/mailbox/data/repository/mailbox_repository_impl.dart @@ -30,6 +30,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_respons import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; @@ -285,6 +286,11 @@ class MailboxRepositoryImpl extends MailboxRepository { return mapDataSource[DataSourceType.network]!.subscribeMultipleMailbox(session, accountId, subscribeRequest); } + @override + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request) { + return mapDataSource[DataSourceType.network]!.handleMailboxRightRequest(session, accountId, request); + } + @override Future> createDefaultMailbox(Session session, AccountId accountId, List listRole) { return mapDataSource[DataSourceType.network]!.createDefaultMailbox(session, accountId, listRole); diff --git a/lib/features/mailbox/domain/constants/mailbox_constants.dart b/lib/features/mailbox/domain/constants/mailbox_constants.dart index 36f7d97bf..36b221ba8 100644 --- a/lib/features/mailbox/domain/constants/mailbox_constants.dart +++ b/lib/features/mailbox/domain/constants/mailbox_constants.dart @@ -16,7 +16,8 @@ class MailboxConstants { MailboxProperty.unreadEmails, MailboxProperty.unreadThreads, MailboxProperty.myRights, - MailboxProperty.namespace + MailboxProperty.namespace, + MailboxProperty.rights }); static final List defaultMailboxRoles = [ diff --git a/lib/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart b/lib/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart new file mode 100644 index 000000000..2e9bc3e7b --- /dev/null +++ b/lib/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart @@ -0,0 +1,8 @@ + +class NullSessionOrAccountIdException implements Exception { + + NullSessionOrAccountIdException(); + + @override + String toString() => 'NullSessionOrAccountIdException: session and accountId should not be null'; +} diff --git a/lib/features/mailbox/domain/exceptions/set_mailbox_rights_exception.dart b/lib/features/mailbox/domain/exceptions/set_mailbox_rights_exception.dart new file mode 100644 index 000000000..211c4b3ce --- /dev/null +++ b/lib/features/mailbox/domain/exceptions/set_mailbox_rights_exception.dart @@ -0,0 +1,8 @@ + +class SetMailboxRightsException implements Exception { + + SetMailboxRightsException(); + + @override + String toString() => 'Failed to update mailbox rights.'; +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/model/mailbox_right_request.dart b/lib/features/mailbox/domain/model/mailbox_right_request.dart new file mode 100644 index 000000000..cf09072c2 --- /dev/null +++ b/lib/features/mailbox/domain/model/mailbox_right_request.dart @@ -0,0 +1,23 @@ +import 'package:equatable/equatable.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart'; + +class MailboxRightRequest with EquatableMixin { + + final MailboxSubaddressingAction subaddressingAction; + final MailboxId mailboxId; + final Map?>? currentRights; + + MailboxRightRequest( + this.mailboxId, + this.currentRights, + this.subaddressingAction + ); + + @override + List get props => [ + mailboxId, + currentRights, + subaddressingAction, + ]; +} diff --git a/lib/features/mailbox/domain/model/mailbox_subaddressing_action.dart b/lib/features/mailbox/domain/model/mailbox_subaddressing_action.dart new file mode 100644 index 000000000..cef83f61e --- /dev/null +++ b/lib/features/mailbox/domain/model/mailbox_subaddressing_action.dart @@ -0,0 +1,4 @@ +enum MailboxSubaddressingAction { + allow, + disallow, +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/repository/mailbox_repository.dart b/lib/features/mailbox/domain/repository/mailbox_repository.dart index 57b8b17de..8f65b1ff9 100644 --- a/lib/features/mailbox/domain/repository/mailbox_repository.dart +++ b/lib/features/mailbox/domain/repository/mailbox_repository.dart @@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; abstract class MailboxRepository { Stream getAllMailbox(Session session, AccountId accountId, {Properties? properties}); @@ -46,6 +47,8 @@ abstract class MailboxRepository { Future> subscribeMultipleMailbox(Session session, AccountId accountId, SubscribeMultipleMailboxRequest subscribeRequest); + Future handleMailboxRightRequest(Session session, AccountId accountId, MailboxRightRequest request); + Future> createDefaultMailbox(Session session, AccountId accountId, List listRole); Future setRoleDefaultMailbox(Session session, AccountId accountId, List listMailbox); diff --git a/lib/features/mailbox/domain/state/subaddressing_mailbox_state.dart b/lib/features/mailbox/domain/state/subaddressing_mailbox_state.dart new file mode 100644 index 000000000..44a1ccb5f --- /dev/null +++ b/lib/features/mailbox/domain/state/subaddressing_mailbox_state.dart @@ -0,0 +1,37 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; +import 'package:tmail_ui_user/features/base/state/ui_action_state.dart'; +import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart'; + +class LoadingSubaddressingMailbox extends LoadingState {} + +class SubaddressingSuccess extends UIActionState { + final MailboxId mailboxId; + final MailboxSubaddressingAction subaddressingAction; + + SubaddressingSuccess( + this.mailboxId, + this.subaddressingAction, + { + jmap.State? currentEmailState, + jmap.State? currentMailboxState, + } + ) : super(currentEmailState, currentMailboxState); + + @override + List get props => [ + mailboxId, + subaddressingAction, + ...super.props + ]; +} + +class SubaddressingFailure extends FeatureFailure { + + SubaddressingFailure(dynamic exception) : super(exception: exception); + + SubaddressingFailure.withException(Exception exception) + : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/mailbox/domain/usecases/subaddressing_interactor.dart b/lib/features/mailbox/domain/usecases/subaddressing_interactor.dart new file mode 100644 index 000000000..30361e4a5 --- /dev/null +++ b/lib/features/mailbox/domain/usecases/subaddressing_interactor.dart @@ -0,0 +1,36 @@ +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/session/session.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/subaddressing_mailbox_state.dart'; + +class SubaddressingInteractor { + final MailboxRepository _mailboxRepository; + + SubaddressingInteractor(this._mailboxRepository); + + Stream> execute(Session session, AccountId accountId, MailboxRightRequest mailboxRightRequest) async* { + try { + yield Right(LoadingSubaddressingMailbox()); + + final currentMailboxState = await _mailboxRepository.getMailboxState(session, accountId); + + final result = await _mailboxRepository.handleMailboxRightRequest(session, accountId, mailboxRightRequest); + + if (result) { + yield Right(SubaddressingSuccess( + mailboxRightRequest.mailboxId, + currentMailboxState: currentMailboxState, + mailboxRightRequest.subaddressingAction)); + } else { + yield Left(SubaddressingFailure(null)); + } + + } catch (exception) { + yield Left(SubaddressingFailure(exception)); + } + } +} \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_bindings.dart b/lib/features/mailbox/presentation/mailbox_bindings.dart index 9fd2fd2a1..4af501999 100644 --- a/lib/features/mailbox/presentation/mailbox_bindings.dart +++ b/lib/features/mailbox/presentation/mailbox_bindings.dart @@ -23,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_i import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; @@ -57,6 +58,7 @@ class MailboxBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), + Get.find(), Get.find(), Get.find(), Get.find(), @@ -107,6 +109,7 @@ class MailboxBindings extends BaseBindings { Get.lazyPut(() => MoveMailboxInteractor(Get.find())); Get.lazyPut(() => SubscribeMailboxInteractor(Get.find())); Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find())); + Get.lazyPut(() => SubaddressingInteractor(Get.find())); Get.lazyPut(() => CreateDefaultMailboxInteractor(Get.find())); } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index f2b0eb9cb..1958f89d8 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -31,11 +31,14 @@ import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.d import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import 'package:tmail_ui_user/features/mailbox/domain/constants/mailbox_constants.dart'; import 'package:tmail_ui_user/features/mailbox/domain/exceptions/set_mailbox_name_exception.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_right_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_request.dart'; @@ -47,6 +50,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.d import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/subaddressing_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_default_mailbox_interactor.dart'; @@ -56,6 +60,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_i import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart'; @@ -101,6 +106,7 @@ class MailboxController extends BaseMailboxController final MoveMailboxInteractor _moveMailboxInteractor; final SubscribeMailboxInteractor _subscribeMailboxInteractor; final SubscribeMultipleMailboxInteractor _subscribeMultipleMailboxInteractor; + final SubaddressingInteractor _subaddressingInteractor; final CreateDefaultMailboxInteractor _createDefaultMailboxInteractor; IOSSharingManager? _iosSharingManager; @@ -131,6 +137,7 @@ class MailboxController extends BaseMailboxController this._moveMailboxInteractor, this._subscribeMailboxInteractor, this._subscribeMultipleMailboxInteractor, + this._subaddressingInteractor, this._createDefaultMailboxInteractor, TreeBuilder treeBuilder, VerifyNameInteractor verifyNameInteractor, @@ -190,6 +197,8 @@ class MailboxController extends BaseMailboxController _handleUnsubscribeMultipleMailboxAllSuccess(success); } else if (success is SubscribeMultipleMailboxHasSomeSuccess) { _handleUnsubscribeMultipleMailboxHasSomeSuccess(success); + } else if (success is SubaddressingSuccess) { + _handleSubaddressingSuccess(success); } } @@ -202,6 +211,8 @@ class MailboxController extends BaseMailboxController _renameMailboxFailure(failure); } else if (failure is DeleteMultipleMailboxFailure) { _deleteMailboxFailure(failure); + } else if (failure is SubaddressingFailure) { + _handleSubaddressingFailure(failure); } } @@ -1244,6 +1255,10 @@ class MailboxController extends BaseMailboxController case MailboxActions.disableMailbox: _unsubscribeMailboxAction(mailbox.id); break; + case MailboxActions.allowSubaddressing: + case MailboxActions.disallowSubaddressing: + _handleSubaddressingAction(mailbox.id, mailbox.rights, actions); + break; case MailboxActions.emptyTrash: emptyTrashAction(context, mailbox, mailboxDashBoardController); break; @@ -1495,6 +1510,41 @@ class MailboxController extends BaseMailboxController } } + void _handleSubaddressingAction(MailboxId mailboxId, Map?>? currentRights, MailboxActions subaddressingAction) { + final accountId = mailboxDashBoardController.accountId.value; + final session = mailboxDashBoardController.sessionCurrent; + + if (session != null && accountId != null) { + final allowSubaddressingRequest = MailboxRightRequest( + mailboxId, + currentRights, + subaddressingAction == MailboxActions.allowSubaddressing ? MailboxSubaddressingAction.allow : MailboxSubaddressingAction.disallow + ); + + consumeState(_subaddressingInteractor.execute(session, accountId, allowSubaddressingRequest)); + } else { + _handleSubaddressingFailure(SubaddressingFailure.withException(NullSessionOrAccountIdException())); + } + + popBack(); + } + + void _handleSubaddressingFailure(SubaddressingFailure failure) { + if (currentOverlayContext != null && currentContext != null) { + final messageError = AppLocalizations.of(currentContext!).toastMessageSubaddressingFailure; + appToast.showToastErrorMessage(currentOverlayContext!, messageError); + } + } + + void _handleSubaddressingSuccess(SubaddressingSuccess success) { + appToast.showToastSuccessMessage( + currentOverlayContext!, + success.subaddressingAction == MailboxSubaddressingAction.allow + ? AppLocalizations.of(currentContext!).toastMessageAllowSubaddressingSuccess + : AppLocalizations.of(currentContext!).toastMessageDisallowSubaddressingSuccess, + ); + } + void _mailboxListScrollControllerListener() { _handleScrollTop(); _handleScrollBottom(); diff --git a/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart b/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart index 6d4d2b0d0..d1abfa29b 100644 --- a/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart +++ b/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart @@ -62,6 +62,10 @@ mixin MailboxWidgetMixin { MailboxActions.markAsRead, MailboxActions.move, MailboxActions.rename, + if (mailbox.isSubaddressingAllowed) + MailboxActions.disallowSubaddressing + else + MailboxActions.allowSubaddressing, if (mailbox.isSubscribedMailbox) MailboxActions.disableMailbox else diff --git a/lib/features/mailbox/presentation/model/mailbox_actions.dart b/lib/features/mailbox/presentation/model/mailbox_actions.dart index 722d55baa..2cb018b00 100644 --- a/lib/features/mailbox/presentation/model/mailbox_actions.dart +++ b/lib/features/mailbox/presentation/model/mailbox_actions.dart @@ -24,7 +24,9 @@ enum MailboxActions { emptySpam, newSubfolder, confirmMailSpam, - recoverDeletedMessages; + recoverDeletedMessages, + allowSubaddressing, + disallowSubaddressing; } extension MailboxActionsExtension on MailboxActions { @@ -74,6 +76,10 @@ extension MailboxActionsExtension on MailboxActions { return AppLocalizations.of(context).confirmAllEmailHereAreSpam; case MailboxActions.recoverDeletedMessages: return AppLocalizations.of(context).recoverDeletedMessages; + case MailboxActions.allowSubaddressing: + return AppLocalizations.of(context).allowSubaddressing; + case MailboxActions.disallowSubaddressing: + return AppLocalizations.of(context).disallowSubaddressing; default: return ''; } @@ -109,6 +115,10 @@ extension MailboxActionsExtension on MailboxActions { return imagePaths.icMarkAsRead; case MailboxActions.recoverDeletedMessages: return imagePaths.icRecoverDeletedMessages; + case MailboxActions.allowSubaddressing: + return imagePaths.icSubaddressingAllow; + case MailboxActions.disallowSubaddressing: + return imagePaths.icSubaddressingDisallow; default: return ''; } @@ -183,6 +193,8 @@ extension MailboxActionsExtension on MailboxActions { case MailboxActions.emptySpam: case MailboxActions.confirmMailSpam: case MailboxActions.recoverDeletedMessages: + case MailboxActions.allowSubaddressing: + case MailboxActions.disallowSubaddressing: return ContextMenuItemState.activated; case MailboxActions.markAsRead: return mailbox.countUnReadEmailsAsString.isNotEmpty diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index cd88bbc4f..9b2862ae5 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -2352,6 +2352,36 @@ "placeholders_order": [], "placeholders": {} }, + "allowSubaddressing": "Allow subaddressing", + "@allowSubaddressing": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "disallowSubaddressing": "Disallow subaddressing", + "@disallowSubaddressing": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageAllowSubaddressingSuccess": "You have successfully allowed subaddressing for this folder", + "@toastMessageAllowSubaddressingSuccess": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageDisallowSubaddressingSuccess": "You have successfully disallowed subaddressing for this folder", + "@toastMessageDisallowSubaddressingSuccess": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "toastMessageSubaddressingFailure": "There was an error dealing with the request", + "@toastMessageSubaddressingFailure": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, "requestReadReceipt": "Request read receipt", "@requestReadReceipt": { "type": "text", diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index bbd081bc4..5c36da0f7 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2422,6 +2422,36 @@ class AppLocalizations { name: 'selectParentFolder'); } + String get allowSubaddressing { + return Intl.message( + 'Allow subaddressing', + name: 'allowSubaddressing'); + } + + String get disallowSubaddressing { + return Intl.message( + 'Disallow subaddressing', + name: 'disallowSubaddressing'); + } + + String get toastMessageAllowSubaddressingSuccess { + return Intl.message( + 'You have successfully allowed subaddressing for this folder', + name: 'toastMessageAllowSubaddressingSuccess'); + } + + String get toastMessageDisallowSubaddressingSuccess { + return Intl.message( + 'You have successfully disallowed subaddressing for this folder', + name: 'toastMessageDisallowSubaddressingSuccess'); + } + + String get toastMessageSubaddressingFailure { + return Intl.message( + 'There was an error dealing with the request', + name: 'toastMessageSubaddressingFailure'); + } + String get requestReadReceipt { return Intl.message( 'Request read receipt', @@ -2798,6 +2828,7 @@ class AppLocalizations { 'This folder is already displayed in your primary folder', name: 'toastMessageShowFolderSuccess'); } + String get folderVisibility { return Intl.message( 'Folder visibility', diff --git a/model/lib/extensions/mailbox_extension.dart b/model/lib/extensions/mailbox_extension.dart index 6219188be..d5f0d2719 100644 --- a/model/lib/extensions/mailbox_extension.dart +++ b/model/lib/extensions/mailbox_extension.dart @@ -34,6 +34,7 @@ extension MailboxExtension on Mailbox { myRights: myRights, isSubscribed: isSubscribed, namespace: namespace, + rights: rights ); } @@ -51,6 +52,7 @@ extension MailboxExtension on Mailbox { myRights: updatedProperties.contain(MailboxProperty.myRights) ? newMailbox.myRights : myRights, isSubscribed: updatedProperties.contain(MailboxProperty.isSubscribed) ? newMailbox.isSubscribed : isSubscribed, namespace: updatedProperties.contain(MailboxProperty.namespace) ? newMailbox.namespace : namespace, + rights: updatedProperties.contain(MailboxProperty.rights) ? newMailbox.rights : rights, ); } @@ -68,6 +70,7 @@ extension MailboxExtension on Mailbox { myRights: myRights, isSubscribed: isSubscribed, namespace: namespace, + rights: rights ); } diff --git a/model/lib/extensions/presentation_mailbox_extension.dart b/model/lib/extensions/presentation_mailbox_extension.dart index 6b1f57d36..eb58c78aa 100644 --- a/model/lib/extensions/presentation_mailbox_extension.dart +++ b/model/lib/extensions/presentation_mailbox_extension.dart @@ -2,6 +2,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/namespace.dart'; import 'package:model/mailbox/mailbox_state.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:model/mailbox/mailbox_constants.dart'; import 'package:model/mailbox/select_mode.dart'; extension PresentationMailboxExtension on PresentationMailbox { @@ -49,6 +50,8 @@ extension PresentationMailboxExtension on PresentationMailbox { bool get isSubscribedMailbox => isSubscribed != null && isSubscribed?.value == true; + bool get isSubaddressingAllowed => rights != null && rights?[anyoneIdentifier]?.contains(postingRight) == true; + bool get allowedToDisplayCountOfUnreadEmails => !(isTrash || isSpam || isDrafts || isTemplates || isSent) && countUnreadEmails > 0; bool get allowedToDisplayCountOfTotalEmails => (isTrash || isSpam || isDrafts) && countTotalEmails > 0; @@ -100,6 +103,7 @@ extension PresentationMailboxExtension on PresentationMailbox { state: state, namespace: namespace, displayName: displayName, + rights: rights ); } @@ -121,6 +125,7 @@ extension PresentationMailboxExtension on PresentationMailbox { state: state, namespace: namespace, displayName: displayName, + rights: rights ); } @@ -142,6 +147,7 @@ extension PresentationMailboxExtension on PresentationMailbox { state: newMailboxState, namespace: namespace, displayName: displayName, + rights: rights ); } @@ -159,6 +165,7 @@ extension PresentationMailboxExtension on PresentationMailbox { myRights: myRights, isSubscribed: isSubscribed, namespace: namespace, + rights: rights ); } @@ -180,6 +187,7 @@ extension PresentationMailboxExtension on PresentationMailbox { state: state, namespace: namespace, displayName: displayName, + rights: rights ); } @@ -201,6 +209,7 @@ extension PresentationMailboxExtension on PresentationMailbox { state: state, namespace: namespace, displayName: displayName, + rights: rights ); } } \ No newline at end of file diff --git a/model/lib/mailbox/mailbox_constants.dart b/model/lib/mailbox/mailbox_constants.dart new file mode 100644 index 000000000..ae75773f9 --- /dev/null +++ b/model/lib/mailbox/mailbox_constants.dart @@ -0,0 +1,2 @@ +const String anyoneIdentifier = 'anyone'; +const String postingRight = 'p'; diff --git a/model/lib/mailbox/mailbox_property.dart b/model/lib/mailbox/mailbox_property.dart index 6fc134627..9e152e95b 100644 --- a/model/lib/mailbox/mailbox_property.dart +++ b/model/lib/mailbox/mailbox_property.dart @@ -12,4 +12,5 @@ class MailboxProperty { static const String myRights = 'myRights'; static const String isSubscribed = 'isSubscribed'; static const String namespace = 'namespace'; + static const String rights = 'rights'; } \ No newline at end of file diff --git a/model/lib/mailbox/presentation_mailbox.dart b/model/lib/mailbox/presentation_mailbox.dart index 576597513..00d225b48 100644 --- a/model/lib/mailbox/presentation_mailbox.dart +++ b/model/lib/mailbox/presentation_mailbox.dart @@ -48,6 +48,7 @@ class PresentationMailbox with EquatableMixin { final MailboxState? state; final Namespace? namespace; final String? displayName; + final Map?>? rights; PresentationMailbox( this.id, @@ -67,6 +68,7 @@ class PresentationMailbox with EquatableMixin { this.state = MailboxState.activated, this.namespace, this.displayName, + this.rights } ); @@ -88,6 +90,7 @@ class PresentationMailbox with EquatableMixin { state, namespace, displayName, + rights ]; PresentationMailbox copyWith({ diff --git a/test/features/mailbox/data/update_rights_for_subaddressing_test.dart b/test/features/mailbox/data/update_rights_for_subaddressing_test.dart new file mode 100644 index 000000000..2c5398b4e --- /dev/null +++ b/test/features/mailbox/data/update_rights_for_subaddressing_test.dart @@ -0,0 +1,54 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:jmap_dart_client/http/http_client.dart'; +import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart'; +import 'package:uuid/uuid.dart'; + +void main() { + group('MailboxAPI.updateRightsForSubaddressing tests', () { + const postingRight = 'p'; + final mailboxAPI = MailboxAPI(HttpClient(Dio()), const Uuid()); + + test('should add postingRight when action is allow and currentRights is empty', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.allow, []); + expect(result, contains(postingRight)); + expect(result.length, 1); + }); + + test('should add postingRight when action is allow and currentRights does not contain postingRight', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.allow, ['r', 'w']); + expect(result, contains(postingRight)); + expect(result.length, 3); + }); + + test('should not add postingRight if action is allow and postingRight already present', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.allow, ['r', postingRight, 'w']); + expect(result.where((right) => right == postingRight).length, 1); + expect(result.length, 3); + }); + + test('should remove postingRight if present and action is disallow', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.disallow, ['r', postingRight, 'w']); + expect(result, isNot(contains(postingRight))); + expect(result.length, 2); + }); + + test('should do nothing if postingRight is not present and action is disallow', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.disallow, ['r', 'w']); + expect(result, isNot(contains(postingRight))); + expect(result.length, 2); + }); + + test('should return empty list if action is disallow and currentRights is null', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.disallow, null); + expect(result, isEmpty); + }); + + test('should return list with only postingRight if action is allow and currentRights is null', () { + final result = mailboxAPI.updateRightsForSubaddressing(MailboxSubaddressingAction.allow, null); + expect(result, contains(postingRight)); + expect(result.length, 1); + }); + }); +} diff --git a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart index 706467b32..7401027b1 100644 --- a/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart +++ b/test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart @@ -44,6 +44,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_r import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; @@ -147,6 +148,7 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), + MockSpec(), MockSpec(), MockSpec(), MockSpec(), @@ -251,6 +253,7 @@ void main() { final moveMailboxInteractor = MockMoveMailboxInteractor(); final subscribeMailboxInteractor = MockSubscribeMailboxInteractor(); final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor(); + final subaddressingInteractor = MockSubaddressingInteractor(); final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor(); final treeBuilder = MockTreeBuilder(); final verifyNameInteractor = MockVerifyNameInteractor(); @@ -363,6 +366,7 @@ void main() { moveMailboxInteractor, subscribeMailboxInteractor, subscribeMultipleMailboxInteractor, + subaddressingInteractor, createDefaultMailboxInteractor, treeBuilder, verifyNameInteractor, diff --git a/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart b/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart index 2484a4c71..3a69bf292 100644 --- a/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart +++ b/test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart @@ -44,6 +44,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_r import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart'; @@ -151,6 +152,7 @@ const fallbackGenerators = { MockSpec(), MockSpec(), MockSpec(), + MockSpec(), MockSpec(), MockSpec(), MockSpec(), @@ -240,6 +242,7 @@ void main() { final moveMailboxInteractor = MockMoveMailboxInteractor(); final subscribeMailboxInteractor = MockSubscribeMailboxInteractor(); final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor(); + final subaddressingInteractor = MockSubaddressingInteractor(); final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor(); final treeBuilder = MockTreeBuilder(); final verifyNameInteractor = MockVerifyNameInteractor(); @@ -356,6 +359,7 @@ void main() { moveMailboxInteractor, subscribeMailboxInteractor, subscribeMultipleMailboxInteractor, + subaddressingInteractor, createDefaultMailboxInteractor, treeBuilder, verifyNameInteractor,