You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ad...@apache.org on 2017/01/31 15:10:27 UTC
[2/5] james-project git commit: JAMES-1916 Extract html from inner
multipart when text/plain in main multipart
JAMES-1916 Extract html from inner multipart when text/plain in main multipart
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5fd8641a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5fd8641a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5fd8641a
Branch: refs/heads/master
Commit: 5fd8641a99434ecba4215d098f903e6ffe680722
Parents: 8e95555
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Fri Jan 27 15:33:09 2017 +0100
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Fri Jan 27 15:33:09 2017 +0100
----------------------------------------------------------------------
.../cucumber/GetMessagesMethodStepdefs.java | 5 +
.../test/resources/cucumber/GetMessages.feature | 10 +-
.../textInMainMultipartHtmlInInnerMultipart.eml | 43 +++++++++
.../jmap/model/MessageContentExtractor.java | 17 +++-
.../jmap/model/MessageContentExtractorTest.java | 97 ++++++++++++++++++++
5 files changed, 170 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd8641a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
index e6c4c4c..450ffb1 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
@@ -191,6 +191,11 @@ public class GetMessagesMethodStepdefs {
appendMessage(messageName, "eml/embeddedMultipartWithInlineTextAttachment.eml");
}
+ @Given("^the user has a message \"([^\"]*)\" in \"([^\"]*)\" mailbox with text in main multipart and html in inner multipart$")
+ public void appendMessageWithTextInMainMultipartAndHtmlInInnerMultipart(String messageName, String mailbox) throws Throwable {
+ appendMessage(messageName, "eml/textInMainMultipartHtmlInInnerMultipart.eml");
+ }
+
private void appendMessage(String messageName, String emlFileName) throws Exception {
ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
MessageId id = mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.lastConnectedUser,
http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd8641a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
index 9cbd0c1..0cd93d1 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
@@ -230,4 +230,12 @@ Feature: GetMessages method
Then no error is returned
And the list should contain 1 message
And the textBody of the message is "/blabla/\n*bloblo*\n"
- And the htmlBody of the message is "<i>blabla</i>\n<b>bloblo</b>\n"
\ No newline at end of file
+ And the htmlBody of the message is "<i>blabla</i>\n<b>bloblo</b>\n"
+
+ Scenario: Retrieving message should find html body when text in main multipart and html in inner multipart
+ Given the user has a message "m1" in "inbox" mailbox with text in main multipart and html in inner multipart
+ When the user ask for messages "m1"
+ Then no error is returned
+ And the list should contain 1 message
+ And the textBody of the message is "/blabla/\r\n*bloblo*\r\n"
+ And the htmlBody of the message is "<i>blabla</i>\r\n<b>bloblo</b>\r\n"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd8641a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/textInMainMultipartHtmlInInnerMultipart.eml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/textInMainMultipartHtmlInInnerMultipart.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/textInMainMultipartHtmlInInnerMultipart.eml
new file mode 100644
index 0000000..6e42d91
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/textInMainMultipartHtmlInInnerMultipart.eml
@@ -0,0 +1,43 @@
+To: David DOLCIMASCOLO <da...@linagora.com>
+From: David DOLCIMASCOLO <da...@linagora.com>
+Subject: Inline twice
+Message-ID: <03...@linagora.com>
+Date: Tue, 3 Jan 2017 17:59:01 +0100
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
+ Thunderbird/45.5.1
+Content-Type: multipart/alternative;
+ boundary="------------41916E9CB699BB85B7A39ABF"
+
+This is a multi-part message in MIME format.
+--------------41916E9CB699BB85B7A39ABF
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+
+/blabla/
+*bloblo*
+
+--------------41916E9CB699BB85B7A39ABF
+Content-Type: multipart/related;
+ boundary="------------7562AB559B6C67B3BE780AA2"
+
+
+--------------7562AB559B6C67B3BE780AA2
+Content-Type: text/html; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+<i>blabla</i>
+<b>bloblo</b>
+
+--------------7562AB559B6C67B3BE780AA2
+Content-Type: image/png;
+ name="=?UTF-8?Q?S=c3=a9lection=5f014.png?="
+Content-Transfer-Encoding: base64
+Content-ID: <pa...@linagora.com>
+Content-Disposition: inline;
+ filename*=utf-8''%53%C3%A9%6C%65%63%74%69%6F%6E%5F%30%31%34%2E%70%6E%67
+
+iVBORw0KGgoAAAANSUhEUgAAAUcAAAJCCAIAAADcDpISAAAAA3NCSVQICAjb4U/gAAAAEHRF
+ASEB8/ejg6KNLS31fZ+u8hQAPj/AXiuIAuF4TyOAAAAAElFTkSuQmCC
+--------------7562AB559B6C67B3BE780AA2--
+
+--------------41916E9CB699BB85B7A39ABF--
http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd8641a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
index 721e641..b5baf53 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageContentExtractor.java
@@ -92,7 +92,12 @@ public class MessageContentExtractor {
private MessageContent retrieveHtmlAndPlainTextContent(Multipart multipart) throws IOException {
Optional<String> textBody = getFirstMatchingTextBody(multipart, "text/plain");
Optional<String> htmlBody = getFirstMatchingTextBody(multipart, "text/html");
- return new MessageContent(textBody, htmlBody);
+ MessageContent directChildTextBodies = new MessageContent(textBody, htmlBody);
+ if (!directChildTextBodies.isComplete()) {
+ MessageContent fromInnerMultipart = parseFirstFoundMultipart(multipart);
+ return directChildTextBodies.merge(fromInnerMultipart);
+ }
+ return directChildTextBodies;
}
private MessageContent retrieveFirstReadablePart(Multipart multipart) throws IOException {
@@ -180,6 +185,16 @@ public class MessageContentExtractor {
return equals(empty());
}
+ public boolean isComplete() {
+ return textBody.isPresent() && htmlBody.isPresent();
+ }
+
+ public MessageContent merge(MessageContent fromInnerMultipart) {
+ return new MessageContent(
+ textBody.map(Optional::of).orElse(fromInnerMultipart.getTextBody()),
+ htmlBody.map(Optional::of).orElse(fromInnerMultipart.getHtmlBody()));
+ }
+
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof MessageContent)) {
http://git-wip-us.apache.org/repos/asf/james-project/blob/5fd8641a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
index 0a05e5d..84f78c4 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MessageContentExtractorTest.java
@@ -21,6 +21,7 @@ package org.apache.james.jmap.model;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
+import java.util.Optional;
import javax.mail.internet.MimeMessage;
@@ -45,6 +46,8 @@ public class MessageContentExtractorTest {
private static final String BINARY_CONTENT = "binary";
private static final String TEXT_CONTENT = "text content";
private static final String HTML_CONTENT = "<b>html</b> content";
+ private static final String TEXT_CONTENT2 = "other text content";
+ private static final String HTML_CONTENT2 = "other <b>html</b> content";
private static final String ATTACHMENT_CONTENT = "attachment content";
private static final String ANY_VALUE = "anyValue";
private static final Field CONTENT_ID_FIELD = new Field() {
@@ -70,6 +73,7 @@ public class MessageContentExtractorTest {
private BodyPart textPart;
private BodyPart textAttachment;
private BodyPart inlineText;
+ private BodyPart inlineImage;
@Before
public void setup() throws IOException {
@@ -84,6 +88,10 @@ public class MessageContentExtractorTest {
.setBody(ATTACHMENT_CONTENT, "plain", Charsets.UTF_8)
.setContentDisposition("inline")
.build();
+ inlineImage = BodyPartBuilder.create()
+ .setBody(new byte[0], "image/png")
+ .setContentDisposition("inline")
+ .build();
}
@Test
@@ -368,4 +376,93 @@ public class MessageContentExtractorTest {
assertThat(actual.getTextBody()).contains(TEXT_CONTENT);
assertThat(actual.getHtmlBody()).contains(HTML_CONTENT);
}
+
+ @Test
+ public void extractShouldRetrieveTextBodyAndHtmlBodyWhenTextBodyInMainMultipartAndHtmlBodyInInnerMultipart() throws IOException {
+ BodyPart multipartRelated = BodyPartBuilder.create()
+ .setBody(MultipartBuilder.create("related")
+ .addBodyPart(htmlPart)
+ .addBodyPart(inlineImage)
+ .build())
+ .build();
+
+ Multipart multipartAlternative = MultipartBuilder.create("alternative")
+ .addBodyPart(textPart)
+ .addBodyPart(multipartRelated)
+ .build();
+
+ Message message = MessageBuilder.create()
+ .setBody(multipartAlternative)
+ .build();
+
+ MessageContent actual = testee.extract(message);
+ assertThat(actual.getTextBody()).contains(TEXT_CONTENT);
+ assertThat(actual.getHtmlBody()).contains(HTML_CONTENT);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnEmptyWhenAllEmpty() {
+ MessageContent messageContent1 = MessageContent.empty();
+ MessageContent messageContent2 = MessageContent.empty();
+ MessageContent expected = MessageContent.empty();
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnFirstWhenSecondEmpty() {
+ MessageContent messageContent1 = new MessageContent(Optional.of(TEXT_CONTENT), Optional.of(HTML_CONTENT));
+ MessageContent messageContent2 = MessageContent.empty();
+ MessageContent expected = messageContent1;
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnSecondWhenFirstEmpty() {
+ MessageContent messageContent1 = MessageContent.empty();
+ MessageContent messageContent2 = new MessageContent(Optional.of(TEXT_CONTENT), Optional.of(HTML_CONTENT));
+ MessageContent expected = messageContent2;
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnMixWhenFirstTextOnlyAndSecondHtmlOnly() {
+ MessageContent messageContent1 = MessageContent.ofTextOnly(TEXT_CONTENT);
+ MessageContent messageContent2 = MessageContent.ofHtmlOnly(HTML_CONTENT);
+ MessageContent expected = new MessageContent(Optional.of(TEXT_CONTENT), Optional.of(HTML_CONTENT));
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnMixWhenFirstHtmlOnlyAndSecondTextOnly() {
+ MessageContent messageContent1 = MessageContent.ofHtmlOnly(HTML_CONTENT);
+ MessageContent messageContent2 = MessageContent.ofTextOnly(TEXT_CONTENT);
+ MessageContent expected = new MessageContent(Optional.of(TEXT_CONTENT), Optional.of(HTML_CONTENT));
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void mergeMessageContentShouldReturnFirstWhenTwiceAreComplete() {
+ MessageContent messageContent1 = new MessageContent(Optional.of(TEXT_CONTENT), Optional.of(HTML_CONTENT));
+ MessageContent messageContent2 = new MessageContent(Optional.of(TEXT_CONTENT2), Optional.of(HTML_CONTENT2));
+ MessageContent expected = messageContent1;
+
+ MessageContent actual = messageContent1.merge(messageContent2);
+
+ assertThat(actual).isEqualTo(expected);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org