Skip to content

Commit

Permalink
JAMES-1794 Generate correct multipart/alternative when htmlBody and t…
Browse files Browse the repository at this point in the history
…extBody
  • Loading branch information
Raphael Ouazana committed Jul 8, 2016
1 parent 0be33d7 commit c5714ed
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 15 deletions.
Expand Up @@ -72,6 +72,7 @@ public class MIMEMessageConverter {
private static final String PLAIN_TEXT_MEDIA_TYPE = MediaType.PLAIN_TEXT_UTF_8.withoutParameters().toString();
private static final String HTML_MEDIA_TYPE = MediaType.HTML_UTF_8.withoutParameters().toString();
private static final NameValuePair UTF_8_CHARSET = new NameValuePair("charset", Charsets.UTF_8.name());
private static final String ALTERNATIVE_SUB_TYPE = "alternative";
private static final String MIXED_SUB_TYPE = "mixed";
private static final String FIELD_PARAMETERS_SEPARATOR = ";";

Expand Down Expand Up @@ -100,7 +101,7 @@ public byte[] convert(ValueWithId.CreationMessageEntry creationMessageEntry, Imm

MessageBuilder messageBuilder = MessageBuilder.create();
if (isMultipart(creationMessageEntry.getValue(), messageAttachments)) {
messageBuilder.setBody(createMultipartBody(creationMessageEntry.getValue(), messageAttachments));
messageBuilder.setBody(createMultipart(creationMessageEntry.getValue(), messageAttachments));
} else {
messageBuilder.setBody(createTextBody(creationMessageEntry.getValue()));
}
Expand Down Expand Up @@ -149,7 +150,11 @@ private Consumer<String> addInReplyToHeader(Consumer<Field> headerAppender) {

private boolean isMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
return (newMessage.getTextBody().isPresent() && newMessage.getHtmlBody().isPresent())
|| !messageAttachments.isEmpty();
|| hasAttachment(messageAttachments);
}

private boolean hasAttachment(ImmutableList<MessageAttachment> messageAttachments) {
return !messageAttachments.isEmpty();
}

private TextBody createTextBody(CreationMessage newMessage) {
Expand All @@ -159,23 +164,45 @@ private TextBody createTextBody(CreationMessage newMessage) {
return bodyFactory.textBody(body, Charsets.UTF_8);
}

private Multipart createMultipartBody(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
try {
MultipartBuilder builder = MultipartBuilder.create(MIXED_SUB_TYPE);
addText(builder, newMessage.getTextBody());
addHtml(builder, newMessage.getHtmlBody());

Consumer<MessageAttachment> addAttachment = addAttachment(builder);
messageAttachments.stream()
.forEach(addAttachment);

return builder.build();
if (hasAttachment(messageAttachments)) {
MultipartBuilder builder = MultipartBuilder.create(MIXED_SUB_TYPE);
addBody(newMessage, builder);

Consumer<MessageAttachment> addAttachment = addAttachment(builder);
messageAttachments.stream()
.forEach(addAttachment);

return builder.build();
} else {
return createMultipartAlternativeBody(newMessage);
}
} catch (IOException e) {
LOGGER.error("Error while creating textBody \n"+ newMessage.getTextBody().get() +"\n or htmlBody \n" + newMessage.getHtmlBody().get(), e);
throw Throwables.propagate(e);
}
}

private void addBody(CreationMessage newMessage, MultipartBuilder builder) throws IOException {
if (newMessage.getHtmlBody().isPresent() && newMessage.getTextBody().isPresent()) {
Multipart body = createMultipartAlternativeBody(newMessage);
builder.addBodyPart(BodyPartBuilder.create().setBody(body).build());
}
else {
addText(builder, newMessage.getTextBody());
addHtml(builder, newMessage.getHtmlBody());
}
}

private Multipart createMultipartAlternativeBody(CreationMessage newMessage) throws IOException {
MultipartBuilder bodyBuilder = MultipartBuilder.create(ALTERNATIVE_SUB_TYPE);
addText(bodyBuilder, newMessage.getTextBody());
addHtml(bodyBuilder, newMessage.getHtmlBody());
Multipart body = bodyBuilder.build();
return body;
}

private void addText(MultipartBuilder builder, Optional<String> textBody) throws IOException {
if (textBody.isPresent()) {
builder.addBodyPart(BodyPartBuilder.create()
Expand Down
Expand Up @@ -200,6 +200,7 @@ public void convertToMimeShouldGenerateMultipartWhenHtmlBodyAndTextBodyProvided(
// Then
assertThat(result.getBody()).isInstanceOf(Multipart.class);
assertThat(result.isMultipart()).isTrue();
assertThat(result.getMimeType()).isEqualTo("multipart/alternative");
Multipart typedResult = (Multipart)result.getBody();
assertThat(typedResult.getBodyParts()).hasSize(2);
}
Expand All @@ -218,7 +219,7 @@ public void convertShouldGenerateExpectedMultipartWhenHtmlAndTextBodyProvided()
.build();

String expectedHeaders = "MIME-Version: 1.0\r\n" +
"Content-Type: multipart/mixed;\r\n" +
"Content-Type: multipart/alternative;\r\n" +
" boundary=\"-=Part.1.";
String expectedPart1 = "Content-Type: text/plain; charset=UTF-8\r\n" +
"\r\n" +
Expand Down Expand Up @@ -337,7 +338,7 @@ public void convertToMimeShouldAddAttachmentWhenOne() {
String expectedCID = "<cid>";
String expectedMimeType = "image/png";
String text = "123456";
TextBody expectedBody = new BasicBodyFactory().textBody(text, Charsets.UTF_8);
TextBody expectedBody = new BasicBodyFactory().textBody(text.getBytes(), Charsets.UTF_8);
MessageAttachment attachment = MessageAttachment.builder()
.attachment(org.apache.james.mailbox.store.mail.model.Attachment.builder()
.attachmentId(AttachmentId.from("blodId"))
Expand All @@ -358,7 +359,62 @@ public void convertToMimeShouldAddAttachmentWhenOne() {
Multipart typedResult = (Multipart)result.getBody();
assertThat(typedResult.getBodyParts()).hasSize(2);
Entity attachmentPart = typedResult.getBodyParts().get(1);
assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expectedBody);
assertThat(attachmentPart.getBody()).isEqualToComparingOnlyGivenFields(expectedBody, "content");
assertThat(attachmentPart.getDispositionType()).isEqualTo("inline");
assertThat(attachmentPart.getMimeType()).isEqualTo(expectedMimeType);
assertThat(attachmentPart.getHeader().getField("Content-ID").getBody()).isEqualTo(expectedCID);
}

@Test
public void convertToMimeShouldAddAttachmentAndMultipartAlternativeWhenOneAttachementAndTextAndHtmlBody() {
// Given
MIMEMessageConverter sut = new MIMEMessageConverter();

CreationMessage testMessage = CreationMessage.builder()
.mailboxIds(ImmutableList.of("dead-bada55"))
.subject("subject")
.from(DraftEmailer.builder().name("sender").build())
.textBody("Hello all!")
.htmlBody("Hello <b>all<b>!")
.build();
TextBody expectedTextBody = new BasicBodyFactory().textBody("Hello all!".getBytes(), Charsets.UTF_8);
TextBody expectedHtmlBody = new BasicBodyFactory().textBody("Hello <b>all<b>!".getBytes(), Charsets.UTF_8);

String expectedCID = "<cid>";
String expectedMimeType = "image/png";
String text = "123456";
TextBody expectedAttachmentBody = new BasicBodyFactory().textBody(text.getBytes(), Charsets.UTF_8);
MessageAttachment attachment = MessageAttachment.builder()
.attachment(org.apache.james.mailbox.store.mail.model.Attachment.builder()
.attachmentId(AttachmentId.from("blodId"))
.bytes(text.getBytes())
.type(expectedMimeType)
.build())
.cid(expectedCID)
.isInline(true)
.build();

// When
Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));

// Then
assertThat(result.getBody()).isInstanceOf(Multipart.class);
assertThat(result.isMultipart()).isTrue();
Multipart typedResult = (Multipart)result.getBody();
assertThat(typedResult.getBodyParts()).hasSize(2);
Entity mainBodyPart = typedResult.getBodyParts().get(0);
assertThat(mainBodyPart.getBody()).isInstanceOf(Multipart.class);
assertThat(mainBodyPart.isMultipart()).isTrue();
assertThat(mainBodyPart.getMimeType()).isEqualTo("multipart/alternative");
assertThat(((Multipart)mainBodyPart.getBody()).getBodyParts()).hasSize(2);
Entity textPart = ((Multipart)mainBodyPart.getBody()).getBodyParts().get(0);
Entity htmlPart = ((Multipart)mainBodyPart.getBody()).getBodyParts().get(1);
assertThat(textPart.getBody()).isEqualToComparingOnlyGivenFields(expectedTextBody, "content");
assertThat(htmlPart.getBody()).isEqualToComparingOnlyGivenFields(expectedHtmlBody, "content");

Entity attachmentPart = typedResult.getBodyParts().get(1);
assertThat(attachmentPart.getBody()).isEqualToComparingOnlyGivenFields(expectedAttachmentBody, "content");
assertThat(attachmentPart.getDispositionType()).isEqualTo("inline");
assertThat(attachmentPart.getMimeType()).isEqualTo(expectedMimeType);
assertThat(attachmentPart.getHeader().getField("Content-ID").getBody()).isEqualTo(expectedCID);
Expand Down

0 comments on commit c5714ed

Please sign in to comment.