TF-3759 Handle mailbox SubAddressing action in search mailbox view

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-14 03:13:20 +07:00
committed by Dat H. Pham
parent 9bca14738e
commit b558dd48d1
5 changed files with 235 additions and 101 deletions
@@ -0,0 +1,117 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/empty_folder_name_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/invalid_mail_format_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/subaddressing_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/copy_subaddress_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
extension HandleMailboxActionTypeExtension on BaseMailboxController {
void copySubAddressAction(BuildContext context, String subAddress) {
Clipboard.setData(ClipboardData(text: subAddress));
appToast.showToastSuccessMessage(
context,
AppLocalizations.of(context).emailSubaddressCopiedToClipboard,
);
}
String getSubAddress(String userEmail, String folderName) {
if (folderName.isEmpty) {
throw EmptyFolderNameException(folderName);
}
final atIndex = userEmail.indexOf('@');
if (atIndex <= 0 || atIndex == userEmail.length - 1) {
throw InvalidMailFormatException(userEmail);
}
return '${userEmail.substring(0, atIndex)}+$folderName@${userEmail.substring(atIndex + 1)}';
}
void openConfirmationDialogSubAddressingAction(
BuildContext context,
MailboxId mailboxId,
String mailboxName,
String subAddress,
Map<String, List<String>?>? currentRights,
{
required AllowSubaddressingActionCallback onAllowSubAddressingAction
}
) {
if (responsiveUtils.isLandscapeMobile(context) ||
responsiveUtils.isPortraitMobile(context)) {
(ConfirmationDialogActionSheetBuilder(context)
..messageText(AppLocalizations.of(context)
.message_confirmation_dialog_allow_subaddressing_mobile(
mailboxName,
subAddress,
)
)
..onCancelAction(AppLocalizations.of(context).cancel, popBack)
..onConfirmAction(
AppLocalizations.of(context).allow,
() => onAllowSubAddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
))
).show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_subAddressing'),
imagePath: imagePaths,
title: AppLocalizations.of(context).allowSubaddressing,
textContent: AppLocalizations.of(context)
.message_confirmation_dialog_allow_subaddressing(mailboxName),
confirmText: AppLocalizations.of(context).allow,
cancelText: AppLocalizations.of(context).cancel,
additionalWidgetContent: CopySubaddressWidget(
imagePath: imagePaths,
subaddress: subAddress,
onCopyButtonAction: () => copySubAddressAction(
context,
subAddress,
),
),
onConfirmButtonAction: () => onAllowSubAddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
}
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,
);
}
}
@@ -5,7 +5,6 @@ import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
@@ -19,6 +18,7 @@ import 'package:model/model.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:rxdart/transformers.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/base/extensions/handle_mailbox_action_type_extension.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/launcher_application_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/mailbox_action_handler_mixin.dart';
@@ -32,8 +32,6 @@ import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/mailbox/domain/constants/mailbox_constants.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/empty_folder_name_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/invalid_mail_format_exception.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';
@@ -78,7 +76,6 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.d
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/copy_subaddress_widget.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
@@ -210,7 +207,7 @@ class MailboxController extends BaseMailboxController
} else if (success is SubscribeMultipleMailboxHasSomeSuccess) {
_handleUnsubscribeMultipleMailboxHasSomeSuccess(success);
} else if (success is SubaddressingSuccess) {
_handleSubaddressingSuccess(success);
handleSubAddressingSuccess(success);
} else if (success is CreateDefaultMailboxAllSuccess) {
_handleCreateDefaultFolderIfMissingSuccess(success);
}
@@ -226,7 +223,7 @@ class MailboxController extends BaseMailboxController
} else if (failure is DeleteMultipleMailboxFailure) {
_deleteMailboxFailure(failure);
} else if (failure is SubaddressingFailure) {
_handleSubaddressingFailure(failure);
handleSubAddressingFailure(failure);
}
}
@@ -1236,11 +1233,11 @@ class MailboxController extends BaseMailboxController
break;
case MailboxActions.copySubaddress:
try{
final subaddress = getSubaddress(
final subaddress = getSubAddress(
mailboxDashBoardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
copySubaddressAction(context, subaddress);
copySubAddressAction(context, subaddress);
} catch (error) {
appToast.showToastErrorMessage(context, AppLocalizations.of(context).errorWhileFetchingSubaddress);
}
@@ -1254,19 +1251,17 @@ class MailboxController extends BaseMailboxController
break;
case MailboxActions.allowSubaddressing:
try{
final subaddress = getSubaddress(
final subAddress = getSubAddress(
mailboxDashBoardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
openConfirmationDialogSubaddressingAction(
openConfirmationDialogSubAddressingAction(
context,
responsiveUtils,
imagePaths,
mailbox.id,
mailbox.getDisplayName(context),
subaddress,
subAddress,
mailbox.rights,
onAllowSubaddressingAction: _handleSubaddressingAction
onAllowSubAddressingAction: _handleSubaddressingAction,
);
} catch (error) {
appToast.showToastErrorMessage(context, AppLocalizations.of(context).errorWhileFetchingSubaddress);
@@ -1540,28 +1535,14 @@ class MailboxController extends BaseMailboxController
consumeState(_subaddressingInteractor.execute(session, accountId, allowSubaddressingRequest));
} else {
_handleSubaddressingFailure(SubaddressingFailure.withException(NullSessionOrAccountIdException()));
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();
@@ -1640,67 +1621,4 @@ class MailboxController extends BaseMailboxController
);
}
}
void openConfirmationDialogSubaddressingAction(
BuildContext context,
ResponsiveUtils responsiveUtils,
ImagePaths imagePaths,
MailboxId mailboxId,
String mailboxName,
String subaddress,
Map<String, List<String>?>? currentRights, {
required AllowSubaddressingActionCallback onAllowSubaddressingAction
}) {
if (responsiveUtils.isLandscapeMobile(context) || responsiveUtils.isPortraitMobile(context)) {
(ConfirmationDialogActionSheetBuilder(context)
..messageText(AppLocalizations.of(context).message_confirmation_dialog_allow_subaddressing_mobile(mailboxName, subaddress))
..onCancelAction(AppLocalizations.of(context).cancel, () => popBack())
..onConfirmAction(AppLocalizations.of(context).allow, () => onAllowSubaddressingAction(mailboxId, currentRights, MailboxActions.allowSubaddressing))
).show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_subaddressing'),
imagePath: imagePaths,
title: AppLocalizations.of(context).allowSubaddressing,
textContent: AppLocalizations.of(context).message_confirmation_dialog_allow_subaddressing(mailboxName),
confirmText: AppLocalizations.of(context).allow,
cancelText: AppLocalizations.of(context).cancel,
additionalWidgetContent: CopySubaddressWidget(
imagePath: imagePaths,
subaddress: subaddress,
onCopyButtonAction: () => copySubaddressAction(context, subaddress),
),
onConfirmButtonAction: () => onAllowSubaddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
}
void copySubaddressAction(BuildContext context, String subaddress) {
Clipboard.setData(ClipboardData(text: subaddress));
appToast.showToastSuccessMessage(context, AppLocalizations.of(context).emailSubaddressCopiedToClipboard);
}
String getSubaddress(String userEmail, String folderName) {
if (folderName.isEmpty) {
throw EmptyFolderNameException(folderName);
}
final atIndex = userEmail.indexOf('@');
if (atIndex <= 0 || atIndex == userEmail.length - 1) {
throw InvalidMailFormatException(userEmail);
}
return '${userEmail.substring(0, atIndex)}+$folderName@${userEmail.substring(atIndex + 1)}';
}
}
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_inte
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/search_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/model/mailbox_tree_builder.dart';
@@ -31,6 +32,16 @@ import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart';
class SearchMailboxBindings extends BaseBindings {
@override
void dependencies() {
_bindingsUtils();
super.dependencies();
}
void _bindingsUtils() {
Get.lazyPut(() => TreeBuilder());
}
@override
void bindingsController() {
Get.lazyPut(() => SearchMailboxController(
@@ -41,6 +52,7 @@ class SearchMailboxBindings extends BaseBindings {
Get.find<SubscribeMailboxInteractor>(),
Get.find<SubscribeMultipleMailboxInteractor>(),
Get.find<CreateNewMailboxInteractor>(),
Get.find<SubaddressingInteractor>(),
Get.find<TreeBuilder>(),
Get.find<VerifyNameInteractor>(),
Get.find<GetAllMailboxInteractor>(),
@@ -83,6 +95,8 @@ class SearchMailboxBindings extends BaseBindings {
Get.lazyPut(() => SearchMailboxInteractor());
Get.lazyPut(() => SubscribeMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => CreateNewMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubaddressingInteractor(Get.find<MailboxRepository>()));
}
@override
@@ -18,11 +18,15 @@ import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/base/extensions/handle_mailbox_action_type_extension.dart';
import 'package:tmail_ui_user/features/base/mixin/mailbox_action_handler_mixin.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
import 'package:tmail_ui_user/features/mailbox/domain/constants/mailbox_constants.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/set_mailbox_name_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_right_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';
@@ -38,6 +42,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.d
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/search_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_mailbox_interactor.dart';
@@ -47,6 +52,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_inte
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/search_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';
@@ -76,6 +82,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
final SubscribeMailboxInteractor _subscribeMailboxInteractor;
final SubscribeMultipleMailboxInteractor _subscribeMultipleMailboxInteractor;
final CreateNewMailboxInteractor _createNewMailboxInteractor;
final SubaddressingInteractor _subAddressingInteractor;
final dashboardController = Get.find<MailboxDashBoardController>();
@@ -100,6 +107,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
this._subscribeMailboxInteractor,
this._subscribeMultipleMailboxInteractor,
this._createNewMailboxInteractor,
this._subAddressingInteractor,
TreeBuilder treeBuilder,
VerifyNameInteractor verifyNameInteractor,
GetAllMailboxInteractor getAllMailboxInteractor,
@@ -121,19 +129,21 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
@override
void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure);
if (failure is SearchMailboxFailure) {
_handleSearchMailboxFailure(failure);
} else if (failure is CreateNewMailboxFailure) {
_createNewMailboxFailure(failure);
} else if (failure is RenameMailboxFailure) {
_renameMailboxFailure(failure);
} else if (failure is SubaddressingFailure) {
handleSubAddressingFailure(failure);
} else {
super.handleFailureViewState(failure);
}
}
@override
void handleSuccessViewState(Success success) async {
super.handleSuccessViewState(success);
if (success is GetAllMailboxSuccess) {
currentMailboxState = success.currentMailboxState;
await buildTree(success.mailboxList);
@@ -165,6 +175,10 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
_handleSubscribeMultipleMailboxHasSomeSuccess(success);
} else if (success is CreateNewMailboxSuccess) {
_createNewMailboxSuccess(success);
} else if (success is SubaddressingSuccess) {
handleSubAddressingSuccess(success);
} else {
super.handleSuccessViewState(success);
}
}
@@ -340,11 +354,81 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
case MailboxActions.recoverDeletedMessages:
dashboardController.gotoEmailRecovery();
break;
case MailboxActions.copySubaddress:
try {
final subAddress = getSubAddress(
dashboardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
copySubAddressAction(context, subAddress);
} catch (error) {
appToast.showToastErrorMessage(
context,
AppLocalizations.of(context).errorWhileFetchingSubaddress,
);
}
break;
case MailboxActions.allowSubaddressing:
try{
final subAddress = getSubAddress(
dashboardController.getOwnEmailAddress(),
findNodePathWithSeparator(mailbox.id, '.')!,
);
openConfirmationDialogSubAddressingAction(
context,
mailbox.id,
mailbox.getDisplayName(context),
subAddress,
mailbox.rights,
onAllowSubAddressingAction: _handleSubAddressingAction
);
} catch (error) {
appToast.showToastErrorMessage(
context,
AppLocalizations.of(context).errorWhileFetchingSubaddress,
);
}
break;
case MailboxActions.disallowSubaddressing:
_handleSubAddressingAction(mailbox.id, mailbox.rights, actions);
break;
default:
break;
}
}
void _handleSubAddressingAction(
MailboxId mailboxId,
Map<String, List<String>?>? currentRights,
MailboxActions subAddressingAction,
) {
final accountId = dashboardController.accountId.value;
final session = dashboardController.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 _renameMailboxAction(PresentationMailbox presentationMailbox, MailboxName newMailboxName) {
if (session != null && accountId != null) {
consumeState(_renameMailboxInteractor.execute(
@@ -18,6 +18,7 @@ import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:rxdart/subjects.dart';
import 'package:tmail_ui_user/features/base/extensions/handle_mailbox_action_type_extension.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
import 'package:tmail_ui_user/features/composer/presentation/manager/composer_manager.dart';
@@ -646,7 +647,7 @@ void main() {
test('should return subaddress with valid email and folder name', () {
const String userEmail = 'user@example.com';
const String folderName = 'folder';
final result = mailboxController.getSubaddress(userEmail, folderName);
final result = mailboxController.getSubAddress(userEmail, folderName);
expect(result, equals('user+folder@example.com'));
});
@@ -655,28 +656,28 @@ void main() {
const userEmail = '@example.com';
const folderName = 'folder';
expect(() => mailboxController.getSubaddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
expect(() => mailboxController.getSubAddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
});
test('should throw an error if empty folder name', () {
const userEmail = 'user@example.com';
const folderName = '';
expect(() => mailboxController.getSubaddress(userEmail, folderName), throwsA(isA<EmptyFolderNameException>()));
expect(() => mailboxController.getSubAddress(userEmail, folderName), throwsA(isA<EmptyFolderNameException>()));
});
test('should throw an error if empty domain', () {
const userEmail = 'user@';
const folderName = 'folder';
expect(() => mailboxController.getSubaddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
expect(() => mailboxController.getSubAddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
});
test('should throw an error if absent `@`', () {
const userEmail = 'invalid-email-format';
const folderName = 'folder';
expect(() => mailboxController.getSubaddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
expect(() => mailboxController.getSubAddress(userEmail, folderName), throwsA(isA<InvalidMailFormatException>()));
});
});
}