TF-3707 Add integration test for case empty trash

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-05-06 23:44:24 +07:00
committed by Dat H. Pham
parent afbebb7eb7
commit b6de5d9391
7 changed files with 116 additions and 8 deletions
@@ -10,6 +10,7 @@ import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/jmap_request.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/set/set_email_method.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_state.dart';
@@ -31,6 +32,7 @@ mixin ScenarioUtilsMixin {
List<ProvisioningEmail> provisioningEmails, {
bool refreshEmailView = true,
bool requestReadReceipt = true,
Role? folderLocationRole,
}) async {
ComposerBindings().dependencies();
@@ -56,7 +58,9 @@ mixin ScenarioUtilsMixin {
emailContent: provisioningEmail.content,
toRecipients: {EmailAddress(null, provisioningEmail.toEmail)},
outboxMailboxId: mailboxDashBoardController.outboxMailbox?.mailboxId,
sentMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
sentMailboxId: folderLocationRole != null
? mailboxDashBoardController.mapDefaultMailboxIdByRole[folderLocationRole]
: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
identity: identity,
attachments: attachments,
hasRequestReadReceipt: requestReadReceipt,
@@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:tmail_ui_user/features/base/widget/compose_floating_button.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import '../base/core_robot.dart';
@@ -33,4 +34,10 @@ class ThreadRobot extends CoreRobot {
Future<void> openMailbox() async {
await $(#mobile_mailbox_menu_button).tap();
}
Future<void> tapEmptyTrashBanner() => $(#empty_trash_banner).tap();
Future<void> tapDeleteAllButtonOnEmptyTrashConfirmDialog(
AppLocalizations appLocalizations,
) => $(appLocalizations.delete_all).tap();
}
@@ -0,0 +1,79 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/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 EmptyTrashScenario extends BaseTestScenario {
const EmptyTrashScenario(super.$);
@override
Future<void> runTestLogic() async {
const emailUser = String.fromEnvironment('BASIC_AUTH_EMAIL');
const subject = 'Empty trash';
final threadRobot = ThreadRobot($);
final mailboxMenuRobot = MailboxMenuRobot($);
final appLocalizations = AppLocalizations();
await provisionEmail(
[
ProvisioningEmail(
toEmail: emailUser,
subject: subject,
content: subject,
),
],
folderLocationRole: PresentationMailbox.roleTrash,
);
await $.pumpAndSettle();
await threadRobot.openMailbox();
await _expectMailboxViewVisible();
await _expectFolderVisible(appLocalizations.trashMailboxDisplayName);
await mailboxMenuRobot.openFolderByName(
appLocalizations.trashMailboxDisplayName,
);
await $.pumpAndSettle();
await _expectEmptyTrashBannerVisible();
await _expectEmailWithSubjectVisible(subject);
await threadRobot.tapEmptyTrashBanner();
await _expectEmptyTrashConfirmDialogVisible(appLocalizations);
await threadRobot.tapDeleteAllButtonOnEmptyTrashConfirmDialog(
appLocalizations,
);
await $.pumpAndSettle(duration: const Duration(seconds: 3));
await _expectEmptyViewVisible();
}
Future<void> _expectMailboxViewVisible() => expectViewVisible($(MailboxView));
Future<void> _expectFolderVisible(String folderName) {
return expectViewVisible($(MailboxItemWidget)
.$(LabelMailboxItemWidget)
.$(find.text(folderName)));
}
Future<void> _expectEmptyTrashBannerVisible() =>
expectViewVisible($(#empty_trash_banner));
Future<void> _expectEmailWithSubjectVisible(String subject) =>
expectViewVisible($(subject));
Future<void> _expectEmptyTrashConfirmDialogVisible(
AppLocalizations appLocalizations,
) => expectViewVisible($(appLocalizations.empty_trash_dialog_message));
Future<void> _expectEmptyViewVisible() =>
expectViewVisible($(#empty_thread_view));
}
@@ -0,0 +1,9 @@
import '../../base/test_base.dart';
import '../../scenarios/mailbox/empty_trash_scenario.dart';
void main() {
TestBase().runPatrolTest(
description: 'Should empty view and hide empty trash banner when empty trash successfully',
scenarioBuilder: ($) => EmptyTrashScenario($),
);
}
@@ -116,7 +116,9 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
final presentationMailbox = controller.selectedMailbox.value;
if (controller.isEmptyTrashBannerEnabledOnWeb(context, presentationMailbox)) {
return BannerEmptyTrashWidget(
onTapAction: controller.emptyTrashAction
responsiveUtils: controller.responsiveUtils,
imagePaths: controller.imagePaths,
onTapAction: controller.emptyTrashAction,
);
} else {
return const SizedBox.shrink();
@@ -152,9 +152,13 @@ class ThreadView extends GetWidget<ThreadController>
final presentationMailbox = controller.mailboxDashBoardController.selectedMailbox.value;
if (controller.mailboxDashBoardController.isEmptyTrashBannerEnabledOnMobile(context, presentationMailbox)) {
return BannerEmptyTrashWidget(
key: const Key('empty_trash_banner'),
responsiveUtils: controller.responsiveUtils,
imagePaths: controller.imagePaths,
onTapAction: () => controller.deleteSelectionEmailsPermanently(
context,
DeleteActionType.all)
DeleteActionType.all,
),
);
} else {
return const SizedBox.shrink();
@@ -3,21 +3,24 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/thread/presentation/styles/banner_empty_trash_styles.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class BannerEmptyTrashWidget extends StatelessWidget {
final VoidCallback onTapAction;
final ResponsiveUtils responsiveUtils;
final ImagePaths imagePaths;
const BannerEmptyTrashWidget({super.key, required this.onTapAction});
const BannerEmptyTrashWidget({
super.key,
required this.responsiveUtils,
required this.imagePaths,
required this.onTapAction,
});
@override
Widget build(BuildContext context) {
final imagePaths = Get.find<ImagePaths>();
final responsiveUtils = Get.find<ResponsiveUtils>();
return Container(
decoration: const ShapeDecoration(
color: BannerEmptyTrashStyles.backgroundColor,