Skip to content

Instantly share code, notes, and snippets.

@dorzepowski
Created February 9, 2022 07:16
Show Gist options
  • Save dorzepowski/b56086e4c7e04842b528079226c265fa to your computer and use it in GitHub Desktop.
Save dorzepowski/b56086e4c7e04842b528079226c265fa to your computer and use it in GitHub Desktop.
package pl.sl
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.function.ThrowingSupplier;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import javax.mail.Address;
import javax.mail.internet.MimeMessage;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.InstanceOfAssertFactories.STRING;
public class MockedJavaMailSender extends JavaMailSenderImpl {
private List<MimeMessage> messages = List.of();
@Override
protected void doSend(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
messages = List.of(mimeMessages);
}
public MailMessagesAssertions assertThat() {
return MailMessagesAssertions.assertThat(messages);
}
public static class MailMessagesAssertions extends AbstractAssert<MailMessagesAssertions, List<MimeMessage>> {
private MailMessagesAssertions(List<MimeMessage> actual) {
super(actual, MailMessagesAssertions.class);
}
public static MailMessagesAssertions assertThat(List<MimeMessage> actual) {
return new MailMessagesAssertions(actual);
}
public MailMessagesAssertions exactlyOneEmailWasSend() {
isNotNull();
if (actual.size() < 1) {
failWithMessage("Expect that email was send but there wasn't any");
} else if (actual.size() > 1) {
failWithMessage("Expect that exactly one email was send but was %s", actual.size());
}
return this;
}
public SingleMailMessageAssertions firstMail() {
return SingleMailMessageAssertions.assertThat(actual.stream().findFirst().orElse(null));
}
static public class SingleMailMessageAssertions extends AbstractAssert<SingleMailMessageAssertions, MimeMessage> {
public static SingleMailMessageAssertions assertThat(MimeMessage actual) {
return new SingleMailMessageAssertions(actual);
}
private SingleMailMessageAssertions(MimeMessage mimeMessage) {
super(mimeMessage, SingleMailMessageAssertions.class);
}
public SingleMailMessageAssertions isFrom(String expectedFrom) {
var fromAddresses = tryTo(actual::getFrom);
if (fromAddresses.length > 1) {
failWithMessage("Expected email was send only from one address but has multiple (%s) addresses", fromAddresses.length);
} else if (fromAddresses.length < 1) {
failWithMessage("Expected email to have any 'from' address but found none");
}
var fromEmail = Arrays.stream(fromAddresses).findFirst().map(Address::toString);
Assertions.assertThat(fromEmail).get().as("Email 'from' address").isEqualTo(expectedFrom);
return this;
}
public SingleMailMessageAssertions isTo(String expectedTo) {
var recipientAddresses = tryTo(actual::getAllRecipients);
if (recipientAddresses.length > 1) {
failWithMessage("Expected email was send only to one address but has multiple (%s) addresses", recipientAddresses.length);
} else if (recipientAddresses.length < 1) {
failWithMessage("Expected email to have any 'to' address but found none");
}
var fromEmail = Arrays.stream(recipientAddresses).findFirst().map(Address::toString);
Assertions.assertThat(fromEmail).get().as("Email 'to' address").isEqualTo(expectedTo);
return this;
}
public SingleMailMessageAssertions hasSubject(String expectedSubject) {
var emailSubject = tryTo(actual::getSubject);
Assertions.assertThat(emailSubject).as("Email subject").isEqualTo(expectedSubject);
return this;
}
public SingleMailMessageAssertions hasHtmlMessage() {
var contentType = tryTo(() -> actual.getDataHandler().getContentType());
var expectedContentType = "text/html";
if (!contentType.contains(expectedContentType)) {
failWithActualExpectedAndMessage(
contentType,
expectedContentType,
"Expected email to have <%s> content type but was <%s>",
expectedContentType,
contentType);
}
return this;
}
public SingleMailMessageAssertions hasMessageContaining(String part) {
var content = tryTo(actual::getContent);
Assertions.assertThat(content)
.isInstanceOf(String.class)
.asInstanceOf(STRING)
.as("Mail message")
.contains(part);
return this;
}
private <T> T tryTo(ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Throwable e) {
throw new AssertionError(e);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment