TF-3369 Fix cid image without disposition (#3373)
This commit is contained in:
@@ -24,8 +24,11 @@ Brief the logic flows to make it easier to track changes during `attachment` dis
|
|||||||
2. Inline attachments: Displayed within the email body
|
2. Inline attachments: Displayed within the email body
|
||||||
|
|
||||||
- Display is only allowed when the following conditions are met:
|
- Display is only allowed when the following conditions are met:
|
||||||
- `cid is not NULL` AND `disposition = 'inline'`
|
- `cid is not NULL` AND `disposition = 'inline' || disposition = NULL`
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
|
|
||||||
- Any changes to attachment display while reading emails should be updated in this ADR.
|
- Any changes to attachment display while reading emails should be updated in this ADR.
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [rfc2392](https://datatracker.ietf.org/doc/html/rfc2392)
|
||||||
@@ -19,4 +19,15 @@ class ThreadRobot extends CoreRobot {
|
|||||||
Future<void> tapOnSearchField() async {
|
Future<void> tapOnSearchField() async {
|
||||||
await $(ThreadView).$(SearchBarView).tap();
|
await $(ThreadView).$(SearchBarView).tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> openMailbox(String mailboxName) async {
|
||||||
|
await $(#mobile_mailbox_menu_button).tap();
|
||||||
|
await $.scrollUntilVisible(finder: $(mailboxName));
|
||||||
|
await $(mailboxName).tap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> openEmailWithSubject(String subject) async {
|
||||||
|
await $.scrollUntilVisible(finder: $(subject));
|
||||||
|
await $(subject).tap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:core/presentation/views/html_viewer/html_content_viewer_widget.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||||
|
|
||||||
|
import '../base/base_scenario.dart';
|
||||||
|
import '../robots/search_robot.dart';
|
||||||
|
import '../robots/thread_robot.dart';
|
||||||
|
import 'login_with_basic_auth_scenario.dart';
|
||||||
|
|
||||||
|
class NoDispositionInlineScenario extends BaseScenario {
|
||||||
|
NoDispositionInlineScenario(
|
||||||
|
super.$, {
|
||||||
|
required this.loginWithBasicAuthScenario,
|
||||||
|
});
|
||||||
|
|
||||||
|
final LoginWithBasicAuthScenario loginWithBasicAuthScenario;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> execute() async {
|
||||||
|
final threadRobot = ThreadRobot($);
|
||||||
|
final searchRobot = SearchRobot($);
|
||||||
|
|
||||||
|
await loginWithBasicAuthScenario.execute();
|
||||||
|
|
||||||
|
await threadRobot.openSearchView();
|
||||||
|
await searchRobot.enterQueryString('Greeting Card');
|
||||||
|
await $.pumpAndTrySettle();
|
||||||
|
await threadRobot.openEmailWithSubject('Greeting');
|
||||||
|
await $.pumpAndTrySettle();
|
||||||
|
_expectEmailViewWithBase64Image(_base64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _expectEmailViewWithBase64Image(String base64) {
|
||||||
|
expect(
|
||||||
|
$(EmailView)
|
||||||
|
.$(HtmlContentViewer)
|
||||||
|
.which<HtmlContentViewer>((view) => view.contentHtml.contains(base64)),
|
||||||
|
findsOneWidget,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _base64 = '''/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAEAsMDgwKEA4NDhIREBM''';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import '../../base/test_base.dart';
|
||||||
|
import '../../scenarios/login_with_basic_auth_scenario.dart';
|
||||||
|
import '../../scenarios/no_disposition_inline_scenario.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestBase().runPatrolTest(
|
||||||
|
description: 'Should see base64 inline image when attachment has no disposition but has cid',
|
||||||
|
test: ($) async {
|
||||||
|
final loginWithBasicAuthScenario = LoginWithBasicAuthScenario($,
|
||||||
|
username: const String.fromEnvironment('USERNAME'),
|
||||||
|
hostUrl: const String.fromEnvironment('BASIC_AUTH_URL'),
|
||||||
|
email: const String.fromEnvironment('BASIC_AUTH_EMAIL'),
|
||||||
|
password: const String.fromEnvironment('PASSWORD'),
|
||||||
|
);
|
||||||
|
|
||||||
|
final noDispositionInlineScenario = NoDispositionInlineScenario($,
|
||||||
|
loginWithBasicAuthScenario: loginWithBasicAuthScenario,
|
||||||
|
);
|
||||||
|
|
||||||
|
await noDispositionInlineScenario.execute();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -39,6 +39,8 @@ class Attachment with EquatableMixin {
|
|||||||
|
|
||||||
bool isDispositionInlined() => disposition == ContentDisposition.inline;
|
bool isDispositionInlined() => disposition == ContentDisposition.inline;
|
||||||
|
|
||||||
|
bool isDispositionUndefined() => disposition == null;
|
||||||
|
|
||||||
bool isApplicationRTFInlined() => type?.mimeType == applicationRTFType && isDispositionInlined();
|
bool isApplicationRTFInlined() => type?.mimeType == applicationRTFType && isDispositionInlined();
|
||||||
|
|
||||||
String getDownloadUrl(String baseDownloadUrl, AccountId accountId) {
|
String getDownloadUrl(String baseDownloadUrl, AccountId accountId) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ extension ListAttachmentExtension on List<Attachment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Attachment> get listAttachmentsDisplayedInContent =>
|
List<Attachment> get listAttachmentsDisplayedInContent =>
|
||||||
where((attachment) => attachment.hasCid() && attachment.isDispositionInlined())
|
where((attachment) => attachment.hasCid() && (attachment.isDispositionInlined() || attachment.isDispositionUndefined()))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Map<String, String> toMapCidImageDownloadUrl({
|
Map<String, String> toMapCidImageDownloadUrl({
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Define users and folders
|
# Define users and folders
|
||||||
users=("alice" "bob" "brian" "charlotte" "david" "emma")
|
users=("alice" "bob" "brian" "charlotte" "david" "emma")
|
||||||
bobFolders=("Search Emails" "Forward Emails")
|
bobFolders=("Search Emails" "Forward Emails" "Disposition")
|
||||||
|
|
||||||
# Add users
|
# Add users
|
||||||
for user in "${users[@]}"; do
|
for user in "${users[@]}"; do
|
||||||
@@ -26,3 +26,8 @@ done
|
|||||||
# Import emails into 'Forward Emails' folder for user Bob
|
# Import emails into 'Forward Emails' folder for user Bob
|
||||||
echo "Importing 0.eml into 'Forward Emails' folder for user bob"
|
echo "Importing 0.eml into 'Forward Emails' folder for user bob"
|
||||||
james-cli ImportEml \#private "bob@example.com" "Forward Emails" "/root/conf/integration_test/eml/forward_email/0.eml"
|
james-cli ImportEml \#private "bob@example.com" "Forward Emails" "/root/conf/integration_test/eml/forward_email/0.eml"
|
||||||
|
|
||||||
|
# For test email with no-disposition inline image
|
||||||
|
# Import email into 'Disposition' folder for user Bob
|
||||||
|
echo "Importing no_disposition_inline.eml into 'Disposition' folder for user bob"
|
||||||
|
james-cli ImportEml \#private "bob@example.com" "Disposition" "/root/conf/integration_test/eml/no_disposition_inline/no_disposition_inline.eml"
|
||||||
Reference in New Issue
Block a user