Skip to content

Commit

Permalink
JAMES-1752 Handle multipart mediatype when retrieving text/html body
Browse files Browse the repository at this point in the history
  • Loading branch information
aduprat committed Jun 10, 2016
1 parent af7b1c6 commit f973b28
Show file tree
Hide file tree
Showing 8 changed files with 581 additions and 104 deletions.
Expand Up @@ -26,7 +26,6 @@
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -56,6 +55,7 @@ public abstract class VacationIntegrationTest {
private static final String USER_2 = "matthieu@" + DOMAIN;
private static final String PASSWORD = "secret";
private static final String REASON = "Message explaining my wonderful vacations";
private static final String HTML_REASON = "<b>" + REASON + "</b>";
public static final String ORIGINAL_MESSAGE_TEXT_BODY = "Hello someone, and thank you for joining example.com!";

private ConditionFactory calmlyAwait;
Expand Down Expand Up @@ -137,7 +137,7 @@ public void jmapVacationShouldHaveSupportForHtmlMail() throws Exception {
calmlyAwait.atMost(10, TimeUnit.SECONDS)
.until(() -> isTextMessageReceived(user1AccessToken, getInboxId(user1AccessToken), ORIGINAL_MESSAGE_TEXT_BODY, USER_2, USER_1));
calmlyAwait.atMost(10, TimeUnit.SECONDS)
.until( () -> assertOneMessageWithNullTextBodyReceived(user2AccessToken, getInboxId(user2AccessToken), USER_1, USER_2));
.until( () -> assertOneMessageWithHtmlBodyReceived(user2AccessToken, getInboxId(user2AccessToken), HTML_REASON, USER_1, USER_2));
}

@Test
Expand Down Expand Up @@ -278,7 +278,7 @@ private void setHtmlVacationResponse(AccessToken user1AccessToken) {
" \"singleton\" : {" +
" \"id\": \"singleton\"," +
" \"isEnabled\": \"true\"," +
" \"htmlBody\": \"<b>" + REASON + "</b>\"" +
" \"htmlBody\": \"" + HTML_REASON + "\"" +
" }" +
" }" +
"}, \"#0\"" +
Expand Down Expand Up @@ -376,7 +376,7 @@ private void assertOneMessageReceived(AccessToken recipientToken, String mailbox
.body(SECOND_ARGUMENTS + ".list[0].to.email[0]", equalTo(expectedTo));
}

private boolean assertOneMessageWithNullTextBodyReceived(AccessToken recipientToken, String mailboxId, String expectedFrom, String expectedTo) {
private boolean assertOneMessageWithHtmlBodyReceived(AccessToken recipientToken, String mailboxId, String expectedHtmlBody, String expectedFrom, String expectedTo) {
try {
with()
.accept(ContentType.JSON)
Expand All @@ -385,7 +385,7 @@ private boolean assertOneMessageWithNullTextBodyReceived(AccessToken recipientTo
.body("[[\"getMessageList\", " +
"{" +
" \"fetchMessages\": true, " +
" \"fetchMessageProperties\": [\"textBody\", \"from\", \"to\", \"mailboxIds\"]," +
" \"fetchMessageProperties\": [\"htmlBody\", \"from\", \"to\", \"mailboxIds\"]," +
" \"filter\": {" +
" \"inMailboxes\":[\"" + mailboxId + "\"]" +
" }" +
Expand All @@ -395,7 +395,7 @@ private boolean assertOneMessageWithNullTextBodyReceived(AccessToken recipientTo
.statusCode(200)
.body(SECOND_NAME, equalTo("messages"))
.body(SECOND_ARGUMENTS + ".list", hasSize(1))
.body(SECOND_ARGUMENTS + ".list[0].textBody", nullValue())
.body(SECOND_ARGUMENTS + ".list[0].htmlBody", equalTo(expectedHtmlBody))
.body(SECOND_ARGUMENTS + ".list[0].from.email", equalTo(expectedFrom))
.body(SECOND_ARGUMENTS + ".list[0].to.email", hasSize(1))
.body(SECOND_ARGUMENTS + ".list[0].to.email[0]", equalTo(expectedTo));
Expand Down
Expand Up @@ -51,7 +51,8 @@
public abstract class GetMessagesMethodTest {
private static final String NAME = "[0][0]";
private static final String ARGUMENTS = "[0][1]";
private static final String ATTACHMENTS = ARGUMENTS + ".list[0].attachments";
private static final String FIRST_MESSAGE = ARGUMENTS + ".list[0]";
private static final String ATTACHMENTS = FIRST_MESSAGE + ".attachments";
private static final String FIRST_ATTACHMENT = ATTACHMENTS + "[0]";
private static final String SECOND_ATTACHMENT = ATTACHMENTS + "[1]";

Expand Down Expand Up @@ -182,15 +183,15 @@ public void getMessagesShouldReturnMessagesWhenAvailable() throws Exception {
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].id", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].threadId", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].subject", equalTo("my test subject"))
.body(ARGUMENTS + ".list[0].textBody", equalTo("testmail"))
.body(ARGUMENTS + ".list[0].isUnread", equalTo(true))
.body(ARGUMENTS + ".list[0].preview", equalTo("testmail"))
.body(ARGUMENTS + ".list[0].headers", equalTo(ImmutableMap.of("subject", "my test subject")))
.body(ARGUMENTS + ".list[0].date", equalTo("2014-10-30T14:12:00Z"))
.body(ARGUMENTS + ".list[0].hasAttachment", equalTo(false))
.body(FIRST_MESSAGE + ".id", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".threadId", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".subject", equalTo("my test subject"))
.body(FIRST_MESSAGE + ".textBody", equalTo("testmail"))
.body(FIRST_MESSAGE + ".isUnread", equalTo(true))
.body(FIRST_MESSAGE + ".preview", equalTo("testmail"))
.body(FIRST_MESSAGE + ".headers", equalTo(ImmutableMap.of("subject", "my test subject")))
.body(FIRST_MESSAGE + ".date", equalTo("2014-10-30T14:12:00Z"))
.body(FIRST_MESSAGE + ".hasAttachment", equalTo(false))
.body(ATTACHMENTS, empty());
}

Expand All @@ -215,14 +216,14 @@ public void getMessagesShouldReturnMessageWhenHtmlMessage() throws Exception {
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].id", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].threadId", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].subject", equalTo("my test subject"))
.body(ARGUMENTS + ".list[0].htmlBody", equalTo("This is a <b>HTML</b> mail"))
.body(ARGUMENTS + ".list[0].isUnread", equalTo(true))
.body(ARGUMENTS + ".list[0].preview", equalTo("This is a <b>HTML</b> mail"))
.body(ARGUMENTS + ".list[0].headers", equalTo(ImmutableMap.of("content-type", "text/html", "subject", "my test subject")))
.body(ARGUMENTS + ".list[0].date", equalTo("2014-10-30T14:12:00Z"));
.body(FIRST_MESSAGE + ".id", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".threadId", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".subject", equalTo("my test subject"))
.body(FIRST_MESSAGE + ".htmlBody", equalTo("This is a <b>HTML</b> mail"))
.body(FIRST_MESSAGE + ".isUnread", equalTo(true))
.body(FIRST_MESSAGE + ".preview", equalTo("This is a <b>HTML</b> mail"))
.body(FIRST_MESSAGE + ".headers", equalTo(ImmutableMap.of("content-type", "text/html", "subject", "my test subject")))
.body(FIRST_MESSAGE + ".date", equalTo("2014-10-30T14:12:00Z"));
}

@Test
Expand All @@ -246,13 +247,13 @@ public void getMessagesShouldReturnFilteredPropertiesMessagesWhenAsked() throws
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].id", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].subject", equalTo("my test subject"))
.body(ARGUMENTS + ".list[0].textBody", nullValue())
.body(ARGUMENTS + ".list[0].isUnread", nullValue())
.body(ARGUMENTS + ".list[0].preview", nullValue())
.body(ARGUMENTS + ".list[0].headers", nullValue())
.body(ARGUMENTS + ".list[0].date", nullValue());
.body(FIRST_MESSAGE + ".id", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".subject", equalTo("my test subject"))
.body(FIRST_MESSAGE + ".textBody", nullValue())
.body(FIRST_MESSAGE + ".isUnread", nullValue())
.body(FIRST_MESSAGE + ".preview", nullValue())
.body(FIRST_MESSAGE + ".headers", nullValue())
.body(FIRST_MESSAGE + ".date", nullValue());
}

@Test
Expand Down Expand Up @@ -281,13 +282,13 @@ public void getMessagesShouldReturnFilteredHeaderPropertyWhenAsked() throws Exce
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].id", equalTo(username + "|inbox|1"))
.body(ARGUMENTS + ".list[0].subject", nullValue())
.body(ARGUMENTS + ".list[0].textBody", nullValue())
.body(ARGUMENTS + ".list[0].isUnread", nullValue())
.body(ARGUMENTS + ".list[0].preview", nullValue())
.body(ARGUMENTS + ".list[0].headers", equalTo(ImmutableMap.of("from", "user@domain.tld", "header2", "Header2Content")))
.body(ARGUMENTS + ".list[0].date", nullValue());
.body(FIRST_MESSAGE + ".id", equalTo(username + "|inbox|1"))
.body(FIRST_MESSAGE + ".subject", nullValue())
.body(FIRST_MESSAGE + ".textBody", nullValue())
.body(FIRST_MESSAGE + ".isUnread", nullValue())
.body(FIRST_MESSAGE + ".preview", nullValue())
.body(FIRST_MESSAGE + ".headers", equalTo(ImmutableMap.of("from", "user@domain.tld", "header2", "Header2Content")))
.body(FIRST_MESSAGE + ".date", nullValue());
}

@Test
Expand Down Expand Up @@ -334,8 +335,8 @@ public void getMessagesShouldReturnMandatoryPropertiesMessagesWhenNotAsked() thr
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].id", equalTo("username@domain.tld|mailbox|1"))
.body(ARGUMENTS + ".list[0].subject", equalTo("my test subject"));
.body(FIRST_MESSAGE + ".id", equalTo("username@domain.tld|mailbox|1"))
.body(FIRST_MESSAGE + ".subject", equalTo("my test subject"));
}

@Test
Expand All @@ -359,7 +360,7 @@ public void getMessagesShouldReturnAttachmentsWhenSome() throws Exception {
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(ARGUMENTS + ".list[0].hasAttachment", equalTo(true))
.body(FIRST_MESSAGE + ".hasAttachment", equalTo(true))
.body(ATTACHMENTS, hasSize(2))
.body(FIRST_ATTACHMENT + ".blobId", equalTo("223a76c0e8c1b1762487d8e0598bd88497d73ef2"))
.body(FIRST_ATTACHMENT + ".type", equalTo("image/jpeg"))
Expand All @@ -368,4 +369,82 @@ public void getMessagesShouldReturnAttachmentsWhenSome() throws Exception {
.body(SECOND_ATTACHMENT + ".type", equalTo("image/jpeg"))
.body(SECOND_ATTACHMENT + ".size", equalTo(597));
}

@Test
public void getMessagesShouldReturnHTMLBodyWhenSomeAttachmentsAndHTMLmail() throws Exception {
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "inbox");

ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "inbox"),
ClassLoader.getSystemResourceAsStream("twoAttachments.eml"), Date.from(dateTime.toInstant()), false, new Flags());

given()
.accept(ContentType.JSON)
.contentType(ContentType.JSON)
.header("Authorization", accessToken.serialize())
.body("[[\"getMessages\", {\"ids\": [\"" + username + "|inbox|1\"]}, \"#0\"]]")
.when()
.post("/jmap")
.then()
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(FIRST_MESSAGE + ".hasAttachment", equalTo(true))
.body(ATTACHMENTS, hasSize(2))
.body(FIRST_MESSAGE + ".preview", equalTo("<b>html</b>\n"))
.body(FIRST_MESSAGE + ".textBody", nullValue())
.body(FIRST_MESSAGE + ".htmlBody", equalTo("<b>html</b>\n"));
}

@Test
public void getMessagesShouldReturnTextBodyWhenSomeAttachmentsAndTextmail() throws Exception {
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "inbox");

ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "inbox"),
ClassLoader.getSystemResourceAsStream("twoAttachmentsTextPlain.eml"), Date.from(dateTime.toInstant()), false, new Flags());

given()
.accept(ContentType.JSON)
.contentType(ContentType.JSON)
.header("Authorization", accessToken.serialize())
.body("[[\"getMessages\", {\"ids\": [\"" + username + "|inbox|1\"]}, \"#0\"]]")
.when()
.post("/jmap")
.then()
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(FIRST_MESSAGE + ".hasAttachment", equalTo(true))
.body(ATTACHMENTS, hasSize(2))
.body(FIRST_MESSAGE + ".preview", equalTo("html\n"))
.body(FIRST_MESSAGE + ".textBody", equalTo("html\n"))
.body(FIRST_MESSAGE + ".htmlBody", nullValue());
}

@Test
public void getMessagesShouldReturnBothHTMLAndTextBodyWhenOneAttachmentAndBothHTMLAndTextmail() throws Exception {
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "inbox");

ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "inbox"),
ClassLoader.getSystemResourceAsStream("htmlAndTextMultipartWithOneAttachment.eml"), Date.from(dateTime.toInstant()), false, new Flags());

given()
.accept(ContentType.JSON)
.contentType(ContentType.JSON)
.header("Authorization", accessToken.serialize())
.body("[[\"getMessages\", {\"ids\": [\"" + username + "|inbox|1\"]}, \"#0\"]]")
.when()
.post("/jmap")
.then()
.statusCode(200)
.body(NAME, equalTo("messages"))
.body(ARGUMENTS + ".list", hasSize(1))
.body(FIRST_MESSAGE + ".hasAttachment", equalTo(true))
.body(ATTACHMENTS, hasSize(1))
.body(FIRST_MESSAGE + ".preview", equalTo("<i>blabla</i>\n<b>bloblo</b>\n"))
.body(FIRST_MESSAGE + ".textBody", equalTo("/blabla/\n*bloblo*\n"))
.body(FIRST_MESSAGE + ".htmlBody", equalTo("<i>blabla</i>\n<b>bloblo</b>\n"));
}
}
@@ -0,0 +1,64 @@
Return-Path: <user0@open-paas.org>
MIME-Version: 1.0
Delivered-To: user0@open-paas.org
Received: from 172.18.0.1 (EHLO [172.18.0.1]) ([172.18.0.1])
by open-paas.org (JAMES SMTP Server ) with ESMTP ID -674616268
for <user0@open-paas.org>;
Tue, 07 Jun 2016 14:23:37 +0000 (UTC)
To: user0@open-paas.org
From: user0 <user0@open-paas.org>
Subject: BOTH
Message-ID: <1cc7f114-dbc4-42c2-99bd-f1100db6d0c1@open-paas.org>
Date: Tue, 7 Jun 2016 16:23:37 +0200
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
Thunderbird/45.1.1
Content-Type: multipart/mixed;
boundary="------------7AF1D14DE1DFA16229726B54"

This is a multi-part message in MIME format.
--------------7AF1D14DE1DFA16229726B54
Content-Type: multipart/alternative;
boundary="------------172F9470CFA3BF3417835D92"
--------------172F9470CFA3BF3417835D92
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
/blabla/
*bloblo*
--------------172F9470CFA3BF3417835D92
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<i>blabla</i>
<b>bloblo</b>

--------------172F9470CFA3BF3417835D92--

--------------7AF1D14DE1DFA16229726B54
Content-Type: image/jpeg;
name="4037_014.jpg"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="4037_014.jpg"
/9j/4X2cRXhpZgAASUkqAAgAAAANAA8BAgAKAAAAqgAAABABAgAJAAAAtAAAABIBAwABAAAA
AQAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAADEBAgAKAAAAzgAAADIB
AgAUAAAA2AAAABMCAwABAAAAAgAAAGmHBAABAAAAfAIAAKXEBwDQAAAA7AAAANLGBwBAAAAA
vAEAANPGBwCAAAAA/AEAAEwqAABQYW5hc29uaWMARE1DLUZaNDUAALQAAAABAAAAtAAAAAEA
AABWZXIuMS4wICAAMjAxNDowMjoyNSAxMDozMjowOQBQcmludElNADAyNTAAAA4AAQAWABYA
AgAAAAAAAwBkAAAABwAAAAAACAAAAAAACQAAAAAACgAAAAAACwCsAAAADAAAAAAADQAAAAAA
DgDEAAAAAAEFAAAAAQEBAAAAEAGAAAAACREAABAnAAALDwAAECcAAJcFAAAQJwAAsAgAABAn
AAABHAAAECcAAF4CAAAQJwAAiwAAABAnAADLAwAAECcAAOUbAAAQJwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--------------7AF1D14DE1DFA16229726B54--

0 comments on commit f973b28

Please sign in to comment.