TF-4141 Add widget tests for displaying of virtual folder: action required

This commit is contained in:
dab246
2026-01-02 11:55:13 +07:00
committed by Dat H. Pham
parent 42a838f263
commit 48f83f00f0
4 changed files with 362 additions and 5 deletions
@@ -17,10 +17,12 @@ import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/email_extension.dart';
import 'package:model/extensions/email_id_extensions.dart';
import 'package:model/extensions/mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:rxdart/subjects.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';
import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/delete_email_permanently_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/delete_multiple_emails_permanently_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_restored_deleted_message_interactor.dart';
@@ -41,6 +43,8 @@ import 'package:tmail_ui_user/features/login/domain/usecases/get_oidc_user_info_
import 'package:tmail_ui_user/features/login/domain/usecases/get_stored_oidc_configuration_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_token_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/update_account_cache_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/create_default_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/clear_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_default_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart';
@@ -55,7 +59,11 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_int
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';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view_web.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart';
@@ -69,7 +77,6 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_re
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_email_sort_order_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart';
import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart';
@@ -103,6 +110,7 @@ import 'package:tmail_ui_user/features/thread/domain/usecases/search_more_email_
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations_delegate.dart';
import 'package:tmail_ui_user/main/localizations/localization_service.dart';
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
@@ -114,6 +122,7 @@ import '../../../../fixtures/account_fixtures.dart';
import '../../../../fixtures/email_fixtures.dart';
import '../../../../fixtures/mailbox_fixtures.dart';
import '../../../../fixtures/session_fixtures.dart';
import '../../../../fixtures/widget_fixtures.dart';
import 'mailbox_dashboard_view_widget_test.mocks.dart';
mockControllerCallback() => InternalFinalCallback<void>(callback: () {});
@@ -313,7 +322,7 @@ void main() {
);
}
group('MailboxDashboardView::WidgetTest::OnWeb', () {
group('MailboxDashboardView', () {
setUp(() {
Get.testMode = true;
@@ -413,7 +422,8 @@ void main() {
getAllMailboxInteractor,
refreshAllMailboxInteractor
);
mailboxController.onReady();
Get.put(mailboxController);
// mailboxController.onReady();
threadController = ThreadController(
getEmailsInMailboxInteractor,
@@ -434,7 +444,7 @@ void main() {
mailboxDashboardController.accountId.value = AccountFixtures.aliceAccountId;
});
group('ThreadView::test', () {
group('ThreadView', () {
testWidgets(
'WHEN switch from old mailbox to new mailbox\n'
'AND old mailbox and new mailbox both have emails\n'
@@ -735,6 +745,292 @@ void main() {
});
});
group('MailboxView', () {
testWidgets(
'GIVEN AI Needs Action is enabled and session supports AI '
'WHEN mailboxes are loaded '
'THEN Action Required folder is displayed',
(tester) async {
final currentMailboxList = <PresentationMailbox>[
MailboxFixtures.inboxMailbox.toPresentationMailbox(),
MailboxFixtures.sentMailbox.toPresentationMailbox(),
MailboxFixtures.folder1.toPresentationMailbox(),
MailboxFixtures.mailboxA.toPresentationMailbox(),
MailboxFixtures.mailboxB.toPresentationMailbox(),
MailboxFixtures.mailboxC.toPresentationMailbox(),
MailboxFixtures.mailboxD.toPresentationMailbox(),
];
final defaultTree = MailboxTree(
MailboxNode(
MailboxNode.rootItem(),
childrenItems: [
MailboxNode(
MailboxFixtures.inboxMailbox.toPresentationMailbox()),
MailboxNode(
MailboxFixtures.sentMailbox.toPresentationMailbox()),
],
),
);
final personalTree = MailboxTree(
MailboxNode(
MailboxNode.rootItem(),
childrenItems: [
MailboxNode(MailboxFixtures.folder1.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxA.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxB.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxC.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxD.toPresentationMailbox()),
],
),
);
final teamTree = MailboxTree(MailboxNode.root());
final currentSession = SessionFixtures.aliceSessionWithAICapability;
// Arrange
when(
mailboxDashboardController
.appGridDashboardController.listLinagoraApp,
).thenReturn(RxList([]));
when(
createDefaultMailboxInteractor.execute(any, any, any),
).thenAnswer(
(_) => Stream.value(Right(CreateDefaultMailboxAllSuccess([]))),
);
when(
treeBuilder.generateMailboxTreeInUI(
allMailboxes: anyNamed('allMailboxes'),
currentDefaultTree: anyNamed('currentDefaultTree'),
currentPersonalTree: anyNamed('currentPersonalTree'),
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
mailboxIdSelected: anyNamed('mailboxIdSelected'),
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
),
).thenAnswer(
(_) async => (
allMailboxes: currentMailboxList,
defaultTree: defaultTree,
personalTree: personalTree,
teamMailboxTree: teamTree,
),
);
when(uuid.v1()).thenReturn('dab123456789');
mailboxDashboardController.isAINeedsActionSettingEnabled.value = true;
mailboxDashboardController.sessionCurrent = currentSession;
// Act
await WidgetFixtures.pumpResponsiveWidget(
tester,
WidgetFixtures.makeTestableWidget(
child: MailboxView(),
),
logicalSize: const Size(1920, 1080),
platform: TargetPlatform.macOS,
);
mailboxController.consumeState(
Stream.value(
Right(
GetAllMailboxSuccess(
mailboxList: currentMailboxList,
currentMailboxState: MailboxFixtures.currentState,
),
),
),
);
await tester.pump();
mailboxController.defaultMailboxTree.refresh();
await tester.pump();
// Assert
verify(
treeBuilder.generateMailboxTreeInUI(
allMailboxes: anyNamed('allMailboxes'),
currentDefaultTree: anyNamed('currentDefaultTree'),
currentPersonalTree: anyNamed('currentPersonalTree'),
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
mailboxIdSelected: anyNamed('mailboxIdSelected'),
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
),
).called(1);
verify(
createDefaultMailboxInteractor.execute(any, any, any),
).called(1);
expect(find.byType(MailboxView), findsOneWidget);
expect(find.byType(MailboxItemWidget), findsAtLeastNWidgets(1));
expect(
find.byWidgetPredicate(
(widget) =>
widget is MailboxItemWidget &&
widget.mailboxNode.item.id ==
PresentationMailbox.actionRequiredFolder.id,
),
findsOneWidget,
);
expect(
find.text(AppLocalizations().actionRequiredMailboxDisplayName),
findsOneWidget,
);
WidgetFixtures.resetResponsive(tester);
},
);
testWidgets(
'GIVEN AI Needs Action is disabled or session not supports AI '
'WHEN mailboxes are loaded '
'THEN Action Required folder is not displayed',
(tester) async {
final currentMailboxList = <PresentationMailbox>[
MailboxFixtures.inboxMailbox.toPresentationMailbox(),
MailboxFixtures.sentMailbox.toPresentationMailbox(),
MailboxFixtures.folder1.toPresentationMailbox(),
MailboxFixtures.mailboxA.toPresentationMailbox(),
MailboxFixtures.mailboxB.toPresentationMailbox(),
MailboxFixtures.mailboxC.toPresentationMailbox(),
MailboxFixtures.mailboxD.toPresentationMailbox(),
];
final defaultTree = MailboxTree(
MailboxNode(
MailboxNode.rootItem(),
childrenItems: [
MailboxNode(
MailboxFixtures.inboxMailbox.toPresentationMailbox()),
MailboxNode(
MailboxFixtures.sentMailbox.toPresentationMailbox()),
],
),
);
final personalTree = MailboxTree(
MailboxNode(
MailboxNode.rootItem(),
childrenItems: [
MailboxNode(MailboxFixtures.folder1.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxA.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxB.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxC.toPresentationMailbox()),
MailboxNode(MailboxFixtures.mailboxD.toPresentationMailbox()),
],
),
);
final teamTree = MailboxTree(MailboxNode.root());
final currentSession =
SessionFixtures.aliceSessionWithoutAICapability;
// Arrange
when(
mailboxDashboardController
.appGridDashboardController.listLinagoraApp,
).thenReturn(RxList([]));
when(
createDefaultMailboxInteractor.execute(any, any, any),
).thenAnswer(
(_) => Stream.value(Right(CreateDefaultMailboxAllSuccess([]))),
);
when(
treeBuilder.generateMailboxTreeInUI(
allMailboxes: anyNamed('allMailboxes'),
currentDefaultTree: anyNamed('currentDefaultTree'),
currentPersonalTree: anyNamed('currentPersonalTree'),
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
mailboxIdSelected: anyNamed('mailboxIdSelected'),
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
),
).thenAnswer(
(_) async => (
allMailboxes: currentMailboxList,
defaultTree: defaultTree,
personalTree: personalTree,
teamMailboxTree: teamTree,
),
);
when(uuid.v1()).thenReturn('dab123456789');
mailboxDashboardController.isAINeedsActionSettingEnabled.value =
false;
mailboxDashboardController.sessionCurrent = currentSession;
// Act
await WidgetFixtures.pumpResponsiveWidget(
tester,
WidgetFixtures.makeTestableWidget(
child: MailboxView(),
),
logicalSize: const Size(1920, 1080),
platform: TargetPlatform.macOS,
);
mailboxController.consumeState(
Stream.value(
Right(
GetAllMailboxSuccess(
mailboxList: currentMailboxList,
currentMailboxState: MailboxFixtures.currentState,
),
),
),
);
await tester.pump();
mailboxController.defaultMailboxTree.refresh();
await tester.pump();
// Assert
verify(
treeBuilder.generateMailboxTreeInUI(
allMailboxes: anyNamed('allMailboxes'),
currentDefaultTree: anyNamed('currentDefaultTree'),
currentPersonalTree: anyNamed('currentPersonalTree'),
currentTeamMailboxTree: anyNamed('currentTeamMailboxTree'),
mailboxIdSelected: anyNamed('mailboxIdSelected'),
mailboxIdExpanded: anyNamed('mailboxIdExpanded'),
),
).called(1);
verify(
createDefaultMailboxInteractor.execute(any, any, any),
).called(1);
expect(find.byType(MailboxView), findsOneWidget);
expect(find.byType(MailboxItemWidget), findsAtLeastNWidgets(1));
expect(
find.byWidgetPredicate(
(widget) =>
widget is MailboxItemWidget &&
widget.mailboxNode.item.id ==
PresentationMailbox.actionRequiredFolder.id,
),
findsNothing,
);
expect(
find.text(AppLocalizations().actionRequiredMailboxDisplayName),
findsNothing,
);
WidgetFixtures.resetResponsive(tester);
},
);
});
tearDown(Get.deleteAll);
});
}
@@ -145,7 +145,8 @@ void main() {
testWidgets(
'does not show AI Action tag',
(tester) async {
await tester.pumpWidget(
await WidgetFixtures.pumpResponsiveWidget(
tester,
WidgetFixtures.makeTestableWidget(
child: EmailTileBuilder(
presentationEmail: emailWithNeedsAction,
@@ -154,9 +155,12 @@ void main() {
isAINeedsActionEnabled: false,
),
),
logicalSize: const Size(375, 812),
);
expect(find.byType(AiActionTagWidget), findsNothing);
WidgetFixtures.resetResponsive(tester);
},
);
});
+7
View File
@@ -1,7 +1,9 @@
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox_rights.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
class MailboxFixtures {
static final inboxMailbox = Mailbox(
@@ -100,4 +102,9 @@ class MailboxFixtures {
static final mailboxB = Mailbox(id: MailboxId(Id('B')));
static final mailboxC = Mailbox(id: MailboxId(Id('C')));
static final mailboxD = Mailbox(id: MailboxId(Id('D')));
static final actionRequiredPresentationMailbox =
PresentationMailbox.actionRequiredFolder;
static final currentState = State('2c9f1b12-b35a-43e6-9af2-0106fb53a943');
}
+50
View File
@@ -12,6 +12,8 @@ import 'package:jmap_dart_client/jmap/core/sort/collation_identifier.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:scribe/scribe/ai/presentation/model/ai_capability.dart';
import 'package:scribe/scribe/ai/presentation/utils/ai_scribe_constants.dart';
import 'account_fixtures.dart';
@@ -202,4 +204,52 @@ class SessionFixtures {
'http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943'),
);
static final aliceSessionWithAICapability = Session(
{
AiScribeConstants.aiCapability: AICapability(),
},
{
AccountFixtures.aliceAccountId: Account(
AccountName('alice@domain.tld'),
true,
false,
{
AiScribeConstants.aiCapability: AICapability(),
},
)
},
{
AiScribeConstants.aiCapability: AccountFixtures.aliceAccountId,
},
UserName('alice@domain.tld'),
Uri.parse('http://domain.com/jmap'),
Uri.parse(
'http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
Uri.parse('http://domain.com/upload/{accountId}'),
Uri.parse(
'http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943'),
);
static final aliceSessionWithoutAICapability = Session(
{},
{
AccountFixtures.aliceAccountId: Account(
AccountName('alice@domain.tld'),
true,
false,
{},
)
},
{},
UserName('alice@domain.tld'),
Uri.parse('http://domain.com/jmap'),
Uri.parse(
'http://domain.com/download/{accountId}/{blobId}/?type={type}&name={name}'),
Uri.parse('http://domain.com/upload/{accountId}'),
Uri.parse(
'http://domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}'),
State('2c9f1b12-b35a-43e6-9af2-0106fb53a943'),
);
}