Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows multiple reply-to addresses #17321

Merged
merged 1 commit into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Mail {
private List<String> bcc = new ArrayList<>();
private List<String> cc = new ArrayList<>();
private String from;
private String replyTo;
private List<String> replyTo = new ArrayList<>();
private String bounceAddress;
private String subject;
private String text;
Expand Down Expand Up @@ -163,20 +163,52 @@ public Mail setFrom(String from) {
}

/**
* @return the reply-to address.
* @return the reply-to address. In the case of multiple addresses, the comma-separated list is returned, following
* the https://datatracker.ietf.org/doc/html/rfc5322#section-3.6.2 recommendation. If no reply-to address has been
* set, it returns {@code null}.
*/
public String getReplyTo() {
return replyTo;
if (replyTo == null || replyTo.isEmpty()) {
return null;
}
return String.join(",", replyTo);
}

/**
* Adds a reply-to address.
*
* @param replyTo the address to use as reply-to. Must be a valid email address.
* @return the current {@link Mail}
* @see #setReplyTo(String)
*/
public Mail addReplyTo(String replyTo) {
this.replyTo.add(replyTo);
return this;
}

/**
* Sets the reply-to address.
*
* @param replyTo the address to use as reply-to. Must be a valid email address.
* @return the current {@link Mail}
* @see #setReplyTo(String[])
*/
public Mail setReplyTo(String replyTo) {
this.replyTo = replyTo;
this.replyTo.clear();
this.replyTo.add(replyTo);
return this;
}

/**
* Sets the reply-to addresses.
*
* @param replyTo the addresses to use as reply-to. Must contain valid email addresses, must contain at least
* one address.
* @return the current {@link Mail}
*/
public Mail setReplyTo(String... replyTo) {
cescoffier marked this conversation as resolved.
Show resolved Hide resolved
this.replyTo.clear();
Collections.addAll(this.replyTo, replyTo);
return this;
}

Expand Down Expand Up @@ -436,7 +468,8 @@ public Mail addAttachment(String name, byte[] data, String contentType, String d
* @param disposition the disposition of the attachment
* @return the current {@link Mail}
*/
public Mail addAttachment(String name, Publisher<Byte> data, String contentType, String description, String disposition) {
public Mail addAttachment(String name, Publisher<Byte> data, String contentType, String description,
String disposition) {
this.attachments.add(new Attachment(name, data, contentType, description, disposition));
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ interface MailTemplateInstance {

MailTemplateInstance replyTo(String replyTo);

MailTemplateInstance replyTo(String... replyTo);

MailTemplateInstance bounceAddress(String bounceAddress);

MailTemplateInstance addInlineAttachment(String name, File file, String contentType, String contentId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public MailTemplateInstance replyTo(String replyTo) {
return this;
}

@Override
public MailTemplateInstance replyTo(String... replyTo) {
this.mail.setReplyTo(replyTo);
return this;
}

@Override
public MailTemplateInstance bounceAddress(String bounceAddress) {
this.mail.setBounceAddress(bounceAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ private Uni<MailMessage> toMailMessage(Mail mail) {
message.setHtml(mail.getHtml());
message.setHeaders(toMultimap(mail.getHeaders()));
if (mail.getReplyTo() != null) {
// getReplyTo produces the comma-separated list.
message.addHeader("Reply-To", mail.getReplyTo());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,32 @@ void testHeaders() {
assertThat(mail.getHeaders()).isEmpty();
}

@Test
void testMultipleReplyTo() {
Mail mail = new Mail().addTo(TO_ADDRESS).setSubject("test").setText(BEGINNING)
.setFrom("from@quarkus.io")
.setReplyTo("reply-to@quarkus.io", "another@quarkus.io")
.setBounceAddress("bounce@quarkus.io");
assertThat(mail.getTo()).containsExactly(TO_ADDRESS);
assertThat(mail.getSubject()).isEqualTo("test");
assertThat(mail.getText()).isEqualTo(BEGINNING);
assertThat(mail.getHtml()).isNull();
assertThat(mail.getFrom()).isEqualTo("from@quarkus.io");
assertThat(mail.getReplyTo()).isEqualTo("reply-to@quarkus.io,another@quarkus.io");
assertThat(mail.getBounceAddress()).isEqualTo("bounce@quarkus.io");

mail = new Mail().addTo(TO_ADDRESS).setSubject("test").setText(BEGINNING)
.setFrom("from@quarkus.io")
.addReplyTo("another@quarkus.io")
.addReplyTo("reply-to@quarkus.io")
.setBounceAddress("bounce@quarkus.io");
assertThat(mail.getTo()).containsExactly(TO_ADDRESS);
assertThat(mail.getSubject()).isEqualTo("test");
assertThat(mail.getText()).isEqualTo(BEGINNING);
assertThat(mail.getHtml()).isNull();
assertThat(mail.getFrom()).isEqualTo("from@quarkus.io");
assertThat(mail.getReplyTo()).isEqualTo("another@quarkus.io,reply-to@quarkus.io");
assertThat(mail.getBounceAddress()).isEqualTo("bounce@quarkus.io");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public Byte next() {

@Test
void testInlineAttachment() throws MessagingException, IOException {
String cid = UUID.randomUUID().toString() + "@acme";
String cid = UUID.randomUUID() + "@acme";
mailer.send(Mail.withHtml(TO, "Test", "testInlineAttachment")
.addInlineAttachment("inline.txt", "my inlined text".getBytes(StandardCharsets.UTF_8), TEXT_CONTENT_TYPE, cid))
.await().indefinitely();
Expand Down Expand Up @@ -210,6 +210,19 @@ void testReplyToHeaderIsSet() throws MessagingException {
assertThat(msg.getReplyTo()).containsExactly(InternetAddress.parse("reply-to@quarkus.io"));
}

@Test
void testMultipleReplyToHeaderIsSet() throws MessagingException {
mailer.send(Mail.withText(TO, "Test", "testHeaders")
.setReplyTo("reply-to@quarkus.io", "another@quarkus.io"))
.await().indefinitely();
assertThat(wiser.getMessages()).hasSize(1);
WiserMessage actual = wiser.getMessages().get(0);
MimeMessage msg = actual.getMimeMessage();
assertThat(msg.getHeader("Reply-To")).containsExactly("reply-to@quarkus.io,another@quarkus.io");
assertThat(msg.getReplyTo()).hasSize(2).contains(InternetAddress.parse("reply-to@quarkus.io"))
.contains(InternetAddress.parse("another@quarkus.io"));
}

private String getContent(WiserMessage msg) {
try {
Object content = msg.getMimeMessage().getContent();
Expand Down Expand Up @@ -279,24 +292,4 @@ private String getTextFromMimeMultipart(
return result.toString();
}

private List<String> getContentTypesFromMimeMultipart(
MimeMultipart mimeMultipart) throws MessagingException, IOException {
List<String> types = new ArrayList<>();
int count = mimeMultipart.getCount();
for (int i = 0; i < count; i++) {
BodyPart bodyPart = mimeMultipart.getBodyPart(i);
if (bodyPart.getContent() instanceof MimeMultipart) {
types.addAll(getContentTypesFromMimeMultipart((MimeMultipart) bodyPart.getContent()));
} else {
types.add(bodyPart.getContentType());
}
}
return types;
}

private List<String> getContentTypesFromMimeMultipart(
String content) throws MessagingException, IOException {
return Collections.singletonList(content);
}

}