TF-3535 E2E composer attachment and inline
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:io' hide HttpClient;
|
import 'dart:io' hide HttpClient;
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
@@ -33,6 +34,7 @@ import 'package:uuid/uuid.dart';
|
|||||||
|
|
||||||
import '../models/provisioning_email.dart';
|
import '../models/provisioning_email.dart';
|
||||||
import '../models/provisioning_identity.dart';
|
import '../models/provisioning_identity.dart';
|
||||||
|
import '../resources/test_images.dart';
|
||||||
|
|
||||||
mixin ScenarioUtilsMixin {
|
mixin ScenarioUtilsMixin {
|
||||||
Future<void> provisionEmail(
|
Future<void> provisionEmail(
|
||||||
@@ -44,7 +46,8 @@ mixin ScenarioUtilsMixin {
|
|||||||
ComposerBindings().dependencies();
|
ComposerBindings().dependencies();
|
||||||
|
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
final createNewAndSendEmailInteractor = Get.find<CreateNewAndSendEmailInteractor>();
|
final createNewAndSendEmailInteractor =
|
||||||
|
Get.find<CreateNewAndSendEmailInteractor>();
|
||||||
final threadController = Get.find<ThreadController>();
|
final threadController = Get.find<ThreadController>();
|
||||||
|
|
||||||
final identity = await getIdentity();
|
final identity = await getIdentity();
|
||||||
@@ -53,27 +56,33 @@ mixin ScenarioUtilsMixin {
|
|||||||
|
|
||||||
// Provision emails
|
// Provision emails
|
||||||
await Future.wait(provisioningEmails.map((provisioningEmail) async {
|
await Future.wait(provisioningEmails.map((provisioningEmail) async {
|
||||||
final attachments = await uploadAttachments(provisioningEmail.attachmentPaths);
|
final attachments =
|
||||||
|
await uploadAttachments(provisioningEmail.attachmentPaths);
|
||||||
|
|
||||||
// Create and send email
|
// Create and send email
|
||||||
return await createNewAndSendEmailInteractor.execute(
|
return await createNewAndSendEmailInteractor
|
||||||
createEmailRequest: CreateEmailRequest(
|
.execute(
|
||||||
session: mailboxDashBoardController.sessionCurrent!,
|
createEmailRequest: CreateEmailRequest(
|
||||||
accountId: mailboxDashBoardController.accountId.value!,
|
session: mailboxDashBoardController.sessionCurrent!,
|
||||||
emailActionType: EmailActionType.compose,
|
accountId: mailboxDashBoardController.accountId.value!,
|
||||||
ownEmailAddress: mailboxDashBoardController.ownEmailAddress.value,
|
emailActionType: EmailActionType.compose,
|
||||||
subject: provisioningEmail.subject,
|
ownEmailAddress: mailboxDashBoardController.ownEmailAddress.value,
|
||||||
emailContent: provisioningEmail.content,
|
subject: provisioningEmail.subject,
|
||||||
toRecipients: {EmailAddress(null, provisioningEmail.toEmail)},
|
emailContent: provisioningEmail.content,
|
||||||
outboxMailboxId: mailboxDashBoardController.outboxMailbox?.mailboxId,
|
toRecipients: {EmailAddress(null, provisioningEmail.toEmail)},
|
||||||
sentMailboxId: folderLocationRole != null
|
outboxMailboxId:
|
||||||
? mailboxDashBoardController.mapDefaultMailboxIdByRole[folderLocationRole]
|
mailboxDashBoardController.outboxMailbox?.mailboxId,
|
||||||
: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
|
sentMailboxId: folderLocationRole != null
|
||||||
identity: identity,
|
? mailboxDashBoardController
|
||||||
attachments: attachments,
|
.mapDefaultMailboxIdByRole[folderLocationRole]
|
||||||
hasRequestReadReceipt: requestReadReceipt,
|
: mailboxDashBoardController
|
||||||
),
|
.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
|
||||||
).last;
|
identity: identity,
|
||||||
|
attachments: attachments,
|
||||||
|
hasRequestReadReceipt: requestReadReceipt,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.last;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Refresh view after provisioning emails
|
// Refresh view after provisioning emails
|
||||||
@@ -90,12 +99,10 @@ mixin ScenarioUtilsMixin {
|
|||||||
bool? isStar,
|
bool? isStar,
|
||||||
}) async {
|
}) async {
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
final emails = mailboxDashBoardController
|
final emails = mailboxDashBoardController.emailsInCurrentMailbox
|
||||||
.emailsInCurrentMailbox
|
.where(
|
||||||
.where((presentationEmail) => subjects.contains(
|
(presentationEmail) => subjects.contains(presentationEmail.subject))
|
||||||
presentationEmail.subject
|
.toList();
|
||||||
))
|
|
||||||
.toList();
|
|
||||||
final session = mailboxDashBoardController.sessionCurrent;
|
final session = mailboxDashBoardController.sessionCurrent;
|
||||||
final accountId = mailboxDashBoardController.accountId.value;
|
final accountId = mailboxDashBoardController.accountId.value;
|
||||||
if (session == null || accountId == null) return;
|
if (session == null || accountId == null) return;
|
||||||
@@ -110,26 +117,22 @@ mixin ScenarioUtilsMixin {
|
|||||||
if (isRead != null) {
|
if (isRead != null) {
|
||||||
final markEmailAsReadMethod = SetEmailMethod(accountId)
|
final markEmailAsReadMethod = SetEmailMethod(accountId)
|
||||||
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsRead(
|
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsRead(
|
||||||
isRead ? ReadActions.markAsRead : ReadActions.markAsUnread
|
isRead ? ReadActions.markAsRead : ReadActions.markAsUnread));
|
||||||
));
|
|
||||||
requestBuilder.invocation(markEmailAsReadMethod);
|
requestBuilder.invocation(markEmailAsReadMethod);
|
||||||
capabilities.addAll(markEmailAsReadMethod
|
capabilities.addAll(markEmailAsReadMethod.requiredCapabilities
|
||||||
.requiredCapabilities
|
.toCapabilitiesSupportTeamMailboxes(session, accountId));
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as star/unstar
|
// Mark as star/unstar
|
||||||
if (isStar != null) {
|
if (isStar != null) {
|
||||||
final markEmailAsStarMethod = SetEmailMethod(accountId)
|
final markEmailAsStarMethod = SetEmailMethod(accountId)
|
||||||
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsStar(
|
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsStar(
|
||||||
isStar ? MarkStarAction.markStar : MarkStarAction.unMarkStar
|
isStar ? MarkStarAction.markStar : MarkStarAction.unMarkStar));
|
||||||
));
|
|
||||||
requestBuilder.invocation(markEmailAsStarMethod);
|
requestBuilder.invocation(markEmailAsStarMethod);
|
||||||
capabilities.addAll(markEmailAsStarMethod
|
capabilities.addAll(markEmailAsStarMethod.requiredCapabilities
|
||||||
.requiredCapabilities
|
.toCapabilitiesSupportTeamMailboxes(session, accountId));
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await (requestBuilder..usings(capabilities)).build().execute();
|
await (requestBuilder..usings(capabilities)).build().execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +142,15 @@ mixin ScenarioUtilsMixin {
|
|||||||
return file.writeAsString(content);
|
return file.writeAsString(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<File> preparingPngWithName(String pngName) async {
|
||||||
|
final bytes = base64Decode(TestImages.base64);
|
||||||
|
final directory = await getTemporaryDirectory();
|
||||||
|
final file = File('${directory.path}/$pngName.png');
|
||||||
|
return file.writeAsBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<Attachment>> uploadAttachments(
|
Future<List<Attachment>> uploadAttachments(
|
||||||
List<String> attachmentPaths
|
List<String> attachmentPaths) async {
|
||||||
) async {
|
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
|
|
||||||
final attachments = <Attachment>[];
|
final attachments = <Attachment>[];
|
||||||
@@ -156,20 +165,22 @@ mixin ScenarioUtilsMixin {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final uploadUri = mailboxDashBoardController.sessionCurrent!.getUploadUri(
|
final uploadUri =
|
||||||
|
mailboxDashBoardController.sessionCurrent!.getUploadUri(
|
||||||
mailboxDashBoardController.accountId.value!,
|
mailboxDashBoardController.accountId.value!,
|
||||||
jmapUrl: mailboxDashBoardController.dynamicUrlInterceptors.jmapUrl,
|
jmapUrl: mailboxDashBoardController.dynamicUrlInterceptors.jmapUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
final uploadAttachmentInteractor = Get.find<UploadAttachmentInteractor>();
|
final uploadAttachmentInteractor =
|
||||||
final uploadAttachmentState = await uploadAttachmentInteractor
|
Get.find<UploadAttachmentInteractor>();
|
||||||
.execute(fileInfo, uploadUri)
|
final uploadAttachmentState =
|
||||||
.last;
|
await uploadAttachmentInteractor.execute(fileInfo, uploadUri).last;
|
||||||
final attachment = await uploadAttachmentState.fold(
|
final attachment = await uploadAttachmentState.fold(
|
||||||
(failure) => null,
|
(failure) => null,
|
||||||
(success) async {
|
(success) async {
|
||||||
if (success is UploadAttachmentSuccess) {
|
if (success is UploadAttachmentSuccess) {
|
||||||
final uploadAttachment = await success.uploadAttachment.progressState.last;
|
final uploadAttachment =
|
||||||
|
await success.uploadAttachment.progressState.last;
|
||||||
return uploadAttachment.fold(
|
return uploadAttachment.fold(
|
||||||
(failure) => null,
|
(failure) => null,
|
||||||
(success) {
|
(success) {
|
||||||
@@ -196,10 +207,12 @@ mixin ScenarioUtilsMixin {
|
|||||||
Future<Identity?> getIdentity() async {
|
Future<Identity?> getIdentity() async {
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
final getAllIdentitiesInteractor = Get.find<GetAllIdentitiesInteractor>();
|
final getAllIdentitiesInteractor = Get.find<GetAllIdentitiesInteractor>();
|
||||||
final getAllIdentities = await getAllIdentitiesInteractor.execute(
|
final getAllIdentities = await getAllIdentitiesInteractor
|
||||||
mailboxDashBoardController.sessionCurrent!,
|
.execute(
|
||||||
mailboxDashBoardController.accountId.value!,
|
mailboxDashBoardController.sessionCurrent!,
|
||||||
).last;
|
mailboxDashBoardController.accountId.value!,
|
||||||
|
)
|
||||||
|
.last;
|
||||||
return getAllIdentities.fold(
|
return getAllIdentities.fold(
|
||||||
(failure) => null,
|
(failure) => null,
|
||||||
(success) {
|
(success) {
|
||||||
@@ -211,45 +224,50 @@ mixin ScenarioUtilsMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMatchingEmailList(List<EmailAddress> emailList, Set<String> allowedEmails) {
|
bool isMatchingEmailList(
|
||||||
|
List<EmailAddress> emailList, Set<String> allowedEmails) {
|
||||||
if (emailList.length != allowedEmails.length) {
|
if (emailList.length != allowedEmails.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<String> emails = emailList.map((e) => e.email).whereType<String>().toSet();
|
final Set<String> emails =
|
||||||
|
emailList.map((e) => e.email).whereType<String>().toSet();
|
||||||
|
|
||||||
return emails.length == allowedEmails.length && emails.containsAll(allowedEmails);
|
return emails.length == allowedEmails.length &&
|
||||||
|
emails.containsAll(allowedEmails);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> provisionIdentities(List<ProvisioningIdentity> provisioningIdentities) async {
|
Future<void> provisionIdentities(
|
||||||
|
List<ProvisioningIdentity> provisioningIdentities) async {
|
||||||
IdentityInteractorsBindings().dependencies();
|
IdentityInteractorsBindings().dependencies();
|
||||||
|
|
||||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
final createNewIdentityInteractor = Get.find<CreateNewIdentityInteractor>();
|
final createNewIdentityInteractor = Get.find<CreateNewIdentityInteractor>();
|
||||||
final createNewDefaultIdentityInteractor = Get.find<CreateNewDefaultIdentityInteractor>();
|
final createNewDefaultIdentityInteractor =
|
||||||
|
Get.find<CreateNewDefaultIdentityInteractor>();
|
||||||
const uuid = Uuid();
|
const uuid = Uuid();
|
||||||
|
|
||||||
final session = mailboxDashBoardController.sessionCurrent;
|
final session = mailboxDashBoardController.sessionCurrent;
|
||||||
final accountId = mailboxDashBoardController.accountId.value;
|
final accountId = mailboxDashBoardController.accountId.value;
|
||||||
final listIdentityRequest = provisioningIdentities
|
final listIdentityRequest = provisioningIdentities
|
||||||
.map((provisioningIdentity) => CreateNewIdentityRequest(
|
.map((provisioningIdentity) => CreateNewIdentityRequest(
|
||||||
Id(uuid.v1()),
|
Id(uuid.v1()),
|
||||||
provisioningIdentity.identity,
|
provisioningIdentity.identity,
|
||||||
isDefaultIdentity: provisioningIdentity.isDefault,
|
isDefaultIdentity: provisioningIdentity.isDefault,
|
||||||
));
|
));
|
||||||
|
|
||||||
for (var identityRequest in listIdentityRequest) {
|
for (var identityRequest in listIdentityRequest) {
|
||||||
if (identityRequest.isDefaultIdentity) {
|
if (identityRequest.isDefaultIdentity) {
|
||||||
await createNewDefaultIdentityInteractor
|
await createNewDefaultIdentityInteractor
|
||||||
.execute(session!, accountId!, identityRequest)
|
.execute(session!, accountId!, identityRequest)
|
||||||
.last;
|
.last;
|
||||||
} else {
|
} else {
|
||||||
await createNewIdentityInteractor
|
await createNewIdentityInteractor
|
||||||
.execute(session!, accountId!, identityRequest)
|
.execute(session!, accountId!, identityRequest)
|
||||||
.last;
|
.last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityInteractorsBindings().dispose();
|
IdentityInteractorsBindings().dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,13 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:core/presentation/resources/image_paths.dart';
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:model/email/prefix_email_address.dart';
|
import 'package:model/email/prefix_email_address.dart';
|
||||||
|
import 'package:model/extensions/session_extension.dart';
|
||||||
|
import 'package:model/upload/file_info.dart';
|
||||||
import 'package:rich_text_composer/rich_text_composer.dart';
|
import 'package:rich_text_composer/rich_text_composer.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
|
||||||
@@ -12,6 +17,7 @@ import 'package:tmail_ui_user/features/composer/presentation/widgets/mobile/from
|
|||||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_composer_widget.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_composer_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_suggestion_item_widget.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_suggestion_item_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/subject_composer_widget.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/subject_composer_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/domain/state/local_image_picker_state.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
import '../base/core_robot.dart';
|
import '../base/core_robot.dart';
|
||||||
@@ -24,26 +30,29 @@ class ComposerRobot extends CoreRobot {
|
|||||||
required PrefixEmailAddress prefixEmailAddress,
|
required PrefixEmailAddress prefixEmailAddress,
|
||||||
required String email,
|
required String email,
|
||||||
}) async {
|
}) async {
|
||||||
final finder = $(RecipientComposerWidget)
|
final finder = $(RecipientComposerWidget).which<RecipientComposerWidget>(
|
||||||
.which<RecipientComposerWidget>((widget) => widget.prefix == prefixEmailAddress);
|
(widget) => widget.prefix == prefixEmailAddress);
|
||||||
final isTextFieldFocused = finder
|
final isTextFieldFocused = finder
|
||||||
.which<RecipientComposerWidget>((view) => view.focusNode?.hasFocus ?? false)
|
.which<RecipientComposerWidget>(
|
||||||
.exists;
|
(view) => view.focusNode?.hasFocus ?? false)
|
||||||
|
.exists;
|
||||||
if (!isTextFieldFocused) {
|
if (!isTextFieldFocused) {
|
||||||
await finder.tap();
|
await finder.tap();
|
||||||
}
|
}
|
||||||
await finder.enterTextWithoutTapAction(email);
|
await finder.enterTextWithoutTapAction(email);
|
||||||
|
|
||||||
await $(RecipientSuggestionItemWidget)
|
await $(RecipientSuggestionItemWidget)
|
||||||
.which<RecipientSuggestionItemWidget>((widget) => widget.emailAddress.email?.contains(email) ?? false)
|
.which<RecipientSuggestionItemWidget>(
|
||||||
.tap();
|
(widget) => widget.emailAddress.email?.contains(email) ?? false)
|
||||||
|
.tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addSubject(String subject) async {
|
Future<void> addSubject(String subject) async {
|
||||||
final finder = $(SubjectComposerWidget);
|
final finder = $(SubjectComposerWidget);
|
||||||
final isTextFieldFocused = finder
|
final isTextFieldFocused = finder
|
||||||
.which<SubjectComposerWidget>((view) => view.focusNode?.hasFocus ?? false)
|
.which<SubjectComposerWidget>(
|
||||||
.exists;
|
(view) => view.focusNode?.hasFocus ?? false)
|
||||||
|
.exists;
|
||||||
if (!isTextFieldFocused) {
|
if (!isTextFieldFocused) {
|
||||||
await finder.tap();
|
await finder.tap();
|
||||||
}
|
}
|
||||||
@@ -53,38 +62,45 @@ class ComposerRobot extends CoreRobot {
|
|||||||
Future<void> addContent(String content) async {
|
Future<void> addContent(String content) async {
|
||||||
ComposerController? composerController;
|
ComposerController? composerController;
|
||||||
await $(ComposerView)
|
await $(ComposerView)
|
||||||
.which<ComposerView>((widget) {
|
.which<ComposerView>((widget) {
|
||||||
composerController = widget.controller;
|
composerController = widget.controller;
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.$(MobileEditorView).$(HtmlEditor).$(InAppWebView).tap();
|
.$(MobileEditorView)
|
||||||
|
.$(HtmlEditor)
|
||||||
|
.$(InAppWebView)
|
||||||
|
.tap();
|
||||||
|
|
||||||
await composerController?.htmlEditorApi?.requestFocusLastChild();
|
await composerController?.htmlEditorApi?.requestFocusLastChild();
|
||||||
|
|
||||||
await composerController!.htmlEditorApi!.insertHtml('$content <br><br>');
|
await composerController!.htmlEditorApi!.insertHtml('$content <br><br>');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sendEmail(ImagePaths imagePaths) async {
|
Future<void> sendEmail(ImagePaths imagePaths) async {
|
||||||
await $(AppBarComposerWidget)
|
await $(AppBarComposerWidget)
|
||||||
.$(TMailButtonWidget)
|
.$(TMailButtonWidget)
|
||||||
.which<TMailButtonWidget>((widget) => widget.icon == imagePaths.icSendMobile)
|
.which<TMailButtonWidget>(
|
||||||
.tap();
|
(widget) => widget.icon == imagePaths.icSendMobile)
|
||||||
|
.tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> grantContactPermission() async {
|
Future<void> grantContactPermission() async {
|
||||||
if (await $.native.isPermissionDialogVisible(timeout: const Duration(seconds: 5))) {
|
if (await $.native
|
||||||
|
.isPermissionDialogVisible(timeout: const Duration(seconds: 5))) {
|
||||||
await $.native.grantPermissionWhenInUse();
|
await $.native.grantPermissionWhenInUse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> tapCloseComposer(ImagePaths imagePaths) async {
|
Future<void> tapCloseComposer(ImagePaths imagePaths) async {
|
||||||
await $(AppBarComposerWidget)
|
await $(AppBarComposerWidget)
|
||||||
.$(TMailButtonWidget)
|
.$(TMailButtonWidget)
|
||||||
.which<TMailButtonWidget>((widget) => widget.icon == imagePaths.icCancel)
|
.which<TMailButtonWidget>(
|
||||||
.tap();
|
(widget) => widget.icon == imagePaths.icCancel)
|
||||||
|
.tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> tapSaveButtonOnSaveDraftConfirmDialog(AppLocalizations appLocalizations) async {
|
Future<void> tapSaveButtonOnSaveDraftConfirmDialog(
|
||||||
|
AppLocalizations appLocalizations) async {
|
||||||
await $(find.text(appLocalizations.save)).tap();
|
await $(find.text(appLocalizations.save)).tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,9 +130,37 @@ class ComposerRobot extends CoreRobot {
|
|||||||
|
|
||||||
Future<void> saveAsTemplate() async {
|
Future<void> saveAsTemplate() async {
|
||||||
await $(AppBarComposerWidget)
|
await $(AppBarComposerWidget)
|
||||||
.$(TMailButtonWidget)
|
.$(TMailButtonWidget)
|
||||||
.which<TMailButtonWidget>((widget) => widget.icon == ImagePaths().icMore)
|
.which<TMailButtonWidget>(
|
||||||
.tap();
|
(widget) => widget.icon == ImagePaths().icMore)
|
||||||
|
.tap();
|
||||||
await $(AppLocalizations().saveAsTemplate).tap();
|
await $(AppLocalizations().saveAsTemplate).tap();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Future<void> addAttachment(File file) async {
|
||||||
|
final controller = Get.find<ComposerController>();
|
||||||
|
controller.uploadController.justUploadAttachmentsAction(
|
||||||
|
uploadFiles: [
|
||||||
|
FileInfo(
|
||||||
|
fileName: file.path.split('/').last,
|
||||||
|
fileSize: await file.length(),
|
||||||
|
filePath: file.path,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
uploadUri:
|
||||||
|
controller.mailboxDashBoardController.sessionCurrent!.getUploadUri(
|
||||||
|
controller.mailboxDashBoardController.accountId.value!,
|
||||||
|
jmapUrl: controller.dynamicUrlInterceptors.jmapUrl,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> addInline(File file) async {
|
||||||
|
final controller = Get.find<ComposerController>();
|
||||||
|
controller.handleSuccessViewState(LocalImagePickerSuccess(FileInfo(
|
||||||
|
filePath: file.path,
|
||||||
|
fileSize: await file.length(),
|
||||||
|
fileName: file.path.split('/').last,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_item_composer_widget.dart';
|
||||||
|
|
||||||
|
import '../../base/base_test_scenario.dart';
|
||||||
|
import '../../resources/test_images.dart';
|
||||||
|
import '../../robots/composer_robot.dart';
|
||||||
|
import '../../robots/thread_robot.dart';
|
||||||
|
|
||||||
|
class ComposerUploadAttachmentAndInlineImageScenario extends BaseTestScenario {
|
||||||
|
const ComposerUploadAttachmentAndInlineImageScenario(super.$);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> runTestLogic() async {
|
||||||
|
const pngName = 'composer-png';
|
||||||
|
final threadRobot = ThreadRobot($);
|
||||||
|
final composerRobot = ComposerRobot($);
|
||||||
|
|
||||||
|
await threadRobot.openComposer();
|
||||||
|
await _expectComposerViewVisible();
|
||||||
|
|
||||||
|
await composerRobot.grantContactPermission();
|
||||||
|
|
||||||
|
final png = await preparingPngWithName(pngName);
|
||||||
|
|
||||||
|
await composerRobot.addAttachment(png);
|
||||||
|
await composerRobot.addInline(png);
|
||||||
|
await $.pumpAndSettle();
|
||||||
|
|
||||||
|
_expectAttachment(pngName);
|
||||||
|
await _expectInline();
|
||||||
|
|
||||||
|
await composerRobot.addAttachment(png);
|
||||||
|
await composerRobot.addAttachment(png);
|
||||||
|
await $.pumpAndSettle();
|
||||||
|
|
||||||
|
_expectMultipleAttachments(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _expectInline() async {
|
||||||
|
final currentHtmlContent = await Get
|
||||||
|
.find<ComposerController>()
|
||||||
|
.getContentInEditor();
|
||||||
|
expect(
|
||||||
|
currentHtmlContent.contains(TestImages.base64),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _expectAttachment(String pngName) {
|
||||||
|
return expect(
|
||||||
|
$(AttachmentItemComposerWidget)
|
||||||
|
.which<AttachmentItemComposerWidget>(
|
||||||
|
(widget) => widget.fileName.contains(pngName)
|
||||||
|
),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _expectMultipleAttachments(int numberOfAttachments) {
|
||||||
|
return expect(
|
||||||
|
$(AttachmentItemComposerWidget),
|
||||||
|
findsNWidgets(numberOfAttachments),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _expectComposerViewVisible() => expectViewVisible($(ComposerView));
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import '../../base/test_base.dart';
|
||||||
|
import '../../scenarios/composer/upload_attachment_and_inline_image_scenario.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestBase().runPatrolTest(
|
||||||
|
description: 'Should see attachment and inline image '
|
||||||
|
'when upload success in composer',
|
||||||
|
scenarioBuilder: ($) => ComposerUploadAttachmentAndInlineImageScenario($),
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user