From e6c3ebf0d7b2d9b15f9711f147d4242f7d206eca Mon Sep 17 00:00:00 2001 From: DatDang Date: Wed, 19 Mar 2025 16:36:57 +0700 Subject: [PATCH] TF-3579 E2E Mailbox mark as read --- .../robots/mailbox_menu_robot.dart | 5 + integration_test/robots/thread_robot.dart | 13 +- .../mark_mailbox_as_read_scenario.dart | 64 ++++++ .../mailbox/mark_mailbox_as_read_test.dart | 9 + .../handle_press_email_selection_action.dart | 1 + .../handle_press_email_selection_action.dart | 1 + ...election_mobile_app_bar_thread_widget.dart | 1 + .../bottom_bar_thread_selection_widget.dart | 197 ------------------ 8 files changed, 90 insertions(+), 201 deletions(-) create mode 100644 integration_test/scenarios/mailbox/mark_mailbox_as_read_scenario.dart create mode 100644 integration_test/tests/mailbox/mark_mailbox_as_read_test.dart delete mode 100644 lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart diff --git a/integration_test/robots/mailbox_menu_robot.dart b/integration_test/robots/mailbox_menu_robot.dart index fe962f58f..0fb88443f 100644 --- a/integration_test/robots/mailbox_menu_robot.dart +++ b/integration_test/robots/mailbox_menu_robot.dart @@ -175,4 +175,9 @@ class MailboxMenuRobot extends CoreRobot { Future tapAddNewFolderButton() async { await $(#add_new_folder_button).tap(); } + + Future tapMarkAsRead() async { + await $(AppLocalizations().mark_as_read).tap(); + await $.pumpAndSettle(); + } } \ No newline at end of file diff --git a/integration_test/robots/thread_robot.dart b/integration_test/robots/thread_robot.dart index d2b4dd753..93b2c53a9 100644 --- a/integration_test/robots/thread_robot.dart +++ b/integration_test/robots/thread_robot.dart @@ -113,13 +113,18 @@ class ThreadRobot extends CoreRobot { } Future moveEmailToMailboxWithName(String mailboxName) async { - await $(#move_selected_email_to_mailbox_button).tap(); + await $(#moreAction_selected_email_button).tap(); + await $.pumpAndTrySettle(); + + await $(#moveToMailbox_action).tap(); + await $.pumpAndTrySettle(); + await $(mailboxName).tap(); - await $.pumpAndSettle(); + await $.pumpAndTrySettle(); } Future moveEmailToTrash() async { - await $(#delete_selected_email_button).tap(); - await $.pumpAndSettle(); + await $(#moveToTrash_selected_email_button).tap(); + await $.pumpAndTrySettle(); } } \ No newline at end of file diff --git a/integration_test/scenarios/mailbox/mark_mailbox_as_read_scenario.dart b/integration_test/scenarios/mailbox/mark_mailbox_as_read_scenario.dart new file mode 100644 index 000000000..378d92b85 --- /dev/null +++ b/integration_test/scenarios/mailbox/mark_mailbox_as_read_scenario.dart @@ -0,0 +1,64 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:model/extensions/presentation_mailbox_extension.dart'; +import 'package:model/mailbox/presentation_mailbox.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/base_test_scenario.dart'; +import '../../models/provisioning_email.dart'; +import '../../robots/mailbox_menu_robot.dart'; +import '../../robots/thread_robot.dart'; + +class MarkMailboxAsReadScenario extends BaseTestScenario { + const MarkMailboxAsReadScenario(super.$); + + @override + Future runTestLogic() async { + const email = String.fromEnvironment('BASIC_AUTH_EMAIL'); + + final threadRobot = ThreadRobot($); + final mailboxMenuRobot = MailboxMenuRobot($); + + await provisionEmail([ProvisioningEmail( + toEmail: email, + subject: 'placeholder email', + content: '' + )]); + await $.pumpAndSettle(duration: const Duration(seconds: 2)); + await threadRobot.openMailbox(); + await $.pumpAndTrySettle(); + _expectInboxUnreadCountVisible(); + + await mailboxMenuRobot.longPressMailboxWithName( + AppLocalizations().inboxMailboxDisplayName, + ); + await mailboxMenuRobot.tapMarkAsRead(); + await threadRobot.openMailbox(); + await $.pumpAndTrySettle(); + _expectInboxUnreadCountInvisible(); + } + + void _expectInboxUnreadCountVisible() { + expect( + $(TrailingMailboxItemWidget).which((widget) { + final mailbox = widget.mailboxNode.item; + return mailbox.role == PresentationMailbox.roleInbox && + mailbox.countUnReadEmailsAsString.isNotEmpty; + }), + findsOneWidget, + ); + } + + void _expectInboxUnreadCountInvisible() { + expect( + $(TrailingMailboxItemWidget) + .which((widget) { + final mailbox = widget.mailboxNode.item; + return mailbox.role == PresentationMailbox.roleInbox + && mailbox.countUnReadEmailsAsString.isNotEmpty; + } + ), + findsNothing, + ); + } +} diff --git a/integration_test/tests/mailbox/mark_mailbox_as_read_test.dart b/integration_test/tests/mailbox/mark_mailbox_as_read_test.dart new file mode 100644 index 000000000..4cdd1e1b8 --- /dev/null +++ b/integration_test/tests/mailbox/mark_mailbox_as_read_test.dart @@ -0,0 +1,9 @@ +import '../../base/test_base.dart'; +import '../../scenarios/mailbox/mark_mailbox_as_read_scenario.dart'; + +void main() { + TestBase().runPatrolTest( + description: 'Should not see unread counter when mark mailbox as read', + scenarioBuilder: ($) => MarkMailboxAsReadScenario($), + ); +} diff --git a/lib/features/search/email/presentation/extension/handle_press_email_selection_action.dart b/lib/features/search/email/presentation/extension/handle_press_email_selection_action.dart index 83a3b80af..8d3a39621 100644 --- a/lib/features/search/email/presentation/extension/handle_press_email_selection_action.dart +++ b/lib/features/search/email/presentation/extension/handle_press_email_selection_action.dart @@ -71,6 +71,7 @@ extension HandlePressEmailSelectionActionExtension on SearchEmailController { AppLocalizations.of(context), imagePaths, category: action.category, + key: '${action.name}_action', )) .toList(); diff --git a/lib/features/thread/presentation/extensions/handle_press_email_selection_action.dart b/lib/features/thread/presentation/extensions/handle_press_email_selection_action.dart index e282faaf6..ab5aa5485 100644 --- a/lib/features/thread/presentation/extensions/handle_press_email_selection_action.dart +++ b/lib/features/thread/presentation/extensions/handle_press_email_selection_action.dart @@ -71,6 +71,7 @@ extension HandlePressEmailSelectionActionExtension on ThreadController { AppLocalizations.of(context), imagePaths, category: action.category, + key: '${action.name}_action', )) .toList(); diff --git a/lib/features/thread/presentation/widgets/app_bar/selection_mobile_app_bar_thread_widget.dart b/lib/features/thread/presentation/widgets/app_bar/selection_mobile_app_bar_thread_widget.dart index d2da5acd3..09b6fc877 100644 --- a/lib/features/thread/presentation/widgets/app_bar/selection_mobile_app_bar_thread_widget.dart +++ b/lib/features/thread/presentation/widgets/app_bar/selection_mobile_app_bar_thread_widget.dart @@ -64,6 +64,7 @@ class SelectionMobileAppBarThreadWidget extends StatelessWidget { ), ...emailSelectionActionTypes.map( (type) => TMailButtonWidget.fromIcon( + key: Key('${type.name}_selected_email_button'), icon: type.getIcon(imagePaths), iconColor: type.getIconColor(), iconSize: type.getIconSize(), diff --git a/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart b/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart deleted file mode 100644 index ae61fc923..000000000 --- a/lib/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart +++ /dev/null @@ -1,197 +0,0 @@ -import 'package:core/presentation/extensions/color_extension.dart'; -import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/presentation/utils/theme_utils.dart'; -import 'package:core/presentation/views/button/tmail_button_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:model/email/email_action_type.dart'; -import 'package:model/email/presentation_email.dart'; -import 'package:model/extensions/list_presentation_email_extension.dart'; -import 'package:model/extensions/presentation_mailbox_extension.dart'; -import 'package:model/mailbox/presentation_mailbox.dart'; -import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; - -typedef OnPressEmailSelectionActionClick = void Function(EmailActionType, List); - -class BottomBarThreadSelectionWidget extends StatelessWidget{ - - final ImagePaths _imagePaths; - final ResponsiveUtils _responsiveUtils; - final List _listSelectionEmail; - final PresentationMailbox? _currentMailbox; - final OnPressEmailSelectionActionClick? onPressEmailSelectionActionClick; - - const BottomBarThreadSelectionWidget( - this._imagePaths, - this._responsiveUtils, - this._listSelectionEmail, - this._currentMailbox, - { - super.key, - this.onPressEmailSelectionActionClick, - } - ); - - @override - Widget build(BuildContext context) { - return Container( - decoration: const BoxDecoration( - border: Border(top: BorderSide( - color: AppColor.colorDividerHorizontal, - width: 0.5, - )), - ), - child: IntrinsicHeight( - child: Row( - children: [ - if (_currentMailbox?.isDrafts == false) - Expanded( - child: TMailButtonWidget( - key: const Key('mark_as_read_selected_email_button'), - text: _listSelectionEmail.isAllEmailRead - ? AppLocalizations.of(context).unread - : AppLocalizations.of(context).read, - icon: _listSelectionEmail.isAllEmailRead ? _imagePaths.icUnread : _imagePaths.icRead, - borderRadius: 0, - iconSize: 20, - iconColor: AppColor.steelGrayA540, - flexibleText: true, - textAlign: TextAlign.center, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), - backgroundColor: Colors.transparent, - textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith( - fontSize: 12, - color: AppColor.steelGrayA540, - ), - verticalDirection: _verticalDirection(context), - onTapActionCallback: () { - onPressEmailSelectionActionClick?.call( - _listSelectionEmail.isAllEmailRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead, - _listSelectionEmail - ); - }, - ), - ), - Expanded( - child: TMailButtonWidget( - key: const Key('mark_as_star_selected_email_button'), - text: _listSelectionEmail.isAllEmailStarred - ? AppLocalizations.of(context).un_star - : AppLocalizations.of(context).star, - icon: _listSelectionEmail.isAllEmailStarred ? _imagePaths.icUnStar : _imagePaths.icStar, - borderRadius: 0, - iconSize: 20, - iconColor: _listSelectionEmail.isAllEmailStarred - ? AppColor.steelGrayA540 - : null, - flexibleText: true, - textAlign: TextAlign.center, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), - backgroundColor: Colors.transparent, - textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith( - fontSize: 12, - color: AppColor.steelGrayA540, - ), - verticalDirection: _verticalDirection(context), - onTapActionCallback: () { - onPressEmailSelectionActionClick?.call( - _listSelectionEmail.isAllEmailStarred ? EmailActionType.unMarkAsStarred : EmailActionType.markAsStarred, - _listSelectionEmail - ); - }, - ), - ), - if (_currentMailbox?.isDrafts == false) - Expanded( - child: TMailButtonWidget( - key: const Key('move_selected_email_to_mailbox_button'), - text: AppLocalizations.of(context).move, - icon: _imagePaths.icMoveMailbox, - borderRadius: 0, - iconSize: 20, - iconColor: AppColor.steelGrayA540, - textAlign: TextAlign.center, - flexibleText: true, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), - backgroundColor: Colors.transparent, - textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith( - fontSize: 12, - color: AppColor.steelGrayA540, - ), - verticalDirection: _verticalDirection(context), - onTapActionCallback: () { - onPressEmailSelectionActionClick?.call(EmailActionType.moveToMailbox, _listSelectionEmail); - }, - ), - ), - if (_currentMailbox?.isDrafts == false) - Expanded( - child: TMailButtonWidget( - key: const Key('move_selected_email_to_spam_button'), - text: _currentMailbox?.isSpam == true - ? AppLocalizations.of(context).un_spam - : AppLocalizations.of(context).spam, - icon: _currentMailbox?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam, - borderRadius: 0, - iconSize: 20, - iconColor: AppColor.steelGrayA540, - flexibleText: true, - textAlign: TextAlign.center, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), - backgroundColor: Colors.transparent, - textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith( - fontSize: 12, - color: AppColor.steelGrayA540, - ), - verticalDirection: _verticalDirection(context), - onTapActionCallback: () { - if (_currentMailbox?.isSpam == true) { - onPressEmailSelectionActionClick?.call(EmailActionType.unSpam, _listSelectionEmail); - } else { - onPressEmailSelectionActionClick?.call(EmailActionType.moveToSpam, _listSelectionEmail); - } - }, - ), - ), - Expanded( - child: TMailButtonWidget( - key: const Key('delete_selected_email_button'), - text: AppLocalizations.of(context).delete, - icon: _imagePaths.icDeleteComposer, - borderRadius: 0, - iconSize: 20, - iconColor: AppColor.steelGrayA540, - flexibleText: true, - textAlign: TextAlign.center, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), - backgroundColor: Colors.transparent, - textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith( - fontSize: 12, - color: AppColor.steelGrayA540, - ), - verticalDirection: _verticalDirection(context), - onTapActionCallback: () { - if (canDeletePermanently) { - onPressEmailSelectionActionClick?.call(EmailActionType.deletePermanently, _listSelectionEmail); - } else { - onPressEmailSelectionActionClick?.call(EmailActionType.moveToTrash, _listSelectionEmail); - } - }, - ), - ), - ] - ), - ) - ); - } - - bool get canDeletePermanently { - return _currentMailbox?.isTrash == true || _currentMailbox?.isDrafts == true || _currentMailbox?.isSpam == true; - } - - bool _verticalDirection(BuildContext context) { - return _responsiveUtils.isLandscapeMobile(context) || - _responsiveUtils.isPortraitMobile(context) || - _responsiveUtils.isTabletLarge(context); - } -} \ No newline at end of file