Tidy up and refactoring
This commit is contained in:
parent
532499dbf4
commit
e622a1b641
1 changed files with 66 additions and 120 deletions
|
@ -21,12 +21,14 @@
|
||||||
|
|
||||||
package net.kemitix.wiser.assertions;
|
package net.kemitix.wiser.assertions;
|
||||||
|
|
||||||
|
import net.kemitix.mon.maybe.Maybe;
|
||||||
import org.subethamail.wiser.Wiser;
|
import org.subethamail.wiser.Wiser;
|
||||||
import org.subethamail.wiser.WiserMessage;
|
import org.subethamail.wiser.WiserMessage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -71,8 +73,10 @@ import javax.mail.internet.MimeMultipart;
|
||||||
@SuppressWarnings("methodcount")
|
@SuppressWarnings("methodcount")
|
||||||
public final class WiserAssertions {
|
public final class WiserAssertions {
|
||||||
|
|
||||||
private static final String ERROR_MESSAGE_SUBJECT
|
private static final String ERROR_MESSAGE_SUBJECT = "No message with subject [{0}] found!";
|
||||||
= "No message with subject [{0}] found!";
|
private static final String ERROR_MESSAGE_CONTENT_CONTAINS = "No message with content containing [{0}] found!";
|
||||||
|
private static final String ERROR_MESSAGE_CONTENT = "No message with content [{0}] found!";
|
||||||
|
private static final String ERROR_MESSAGE_TO = "No message to [{0}] found!";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The messages received by Wiser.
|
* The messages received by Wiser.
|
||||||
|
@ -109,26 +113,15 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions from(final String sender) {
|
public WiserAssertions from(final String sender) {
|
||||||
findFirstOrElseThrow(m -> m.getEnvelopeSender().equals(sender),
|
messageMatches(m -> m.getEnvelopeSender().equals(sender))
|
||||||
assertionError("No message from [{0}] found!", sender));
|
.orElseThrow(assertionError("No message from [{0}] found!", sender));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Optional<WiserMessage> messageMatches(final Predicate<WiserMessage> predicate) {
|
||||||
* Checks that at least on message matches the predicate or the supplied
|
|
||||||
* exception will be thrown.
|
|
||||||
*
|
|
||||||
* @param predicate the condition a message must match
|
|
||||||
* @param exceptionSupplier the supplier of the exception
|
|
||||||
* @return the first WiserMessage
|
|
||||||
*/
|
|
||||||
private WiserMessage findFirstOrElseThrow(
|
|
||||||
final Predicate<WiserMessage> predicate,
|
|
||||||
final Supplier<AssertionError> exceptionSupplier) {
|
|
||||||
return messages.stream()
|
return messages.stream()
|
||||||
.filter(predicate)
|
.filter(predicate)
|
||||||
.findFirst()
|
.findAny();
|
||||||
.orElseThrow(exceptionSupplier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,10 +135,8 @@ public final class WiserAssertions {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings(
|
@SuppressWarnings(
|
||||||
{"ThrowableInstanceNotThrown", "ThrowableInstanceNeverThrown"})
|
{"ThrowableInstanceNotThrown", "ThrowableInstanceNeverThrown"})
|
||||||
private static Supplier<AssertionError> assertionError(
|
private static Supplier<AssertionError> assertionError(final String errorMessage, final Object... args) {
|
||||||
final String errorMessage, final Object... args) {
|
return () -> new AssertionError(MessageFormat.format(errorMessage, args));
|
||||||
return () -> new AssertionError(
|
|
||||||
MessageFormat.format(errorMessage, args));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,8 +148,8 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions to(final String recipient) {
|
public WiserAssertions to(final String recipient) {
|
||||||
findFirstOrElseThrow(m -> m.getEnvelopeReceiver().equals(recipient),
|
messageMatches(m -> m.getEnvelopeReceiver().equals(recipient))
|
||||||
assertionError("No message to [{0}] found!", recipient));
|
.orElseThrow(assertionError(ERROR_MESSAGE_TO, recipient));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,44 +162,19 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions withSubject(final String subject) {
|
public WiserAssertions withSubject(final String subject) {
|
||||||
Predicate<WiserMessage> predicate = m -> subject.equals(
|
messageMatches(m -> subject(m).equals(subject))
|
||||||
unchecked(getMimeMessage(m)::getSubject));
|
.orElseThrow(assertionError(ERROR_MESSAGE_SUBJECT, subject));
|
||||||
findFirstOrElseThrow(predicate,
|
|
||||||
assertionError(ERROR_MESSAGE_SUBJECT, subject));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String subject(final WiserMessage wiserMessage) {
|
||||||
* Convert any checked Exceptions into unchecked Exceptions.
|
|
||||||
*
|
|
||||||
* @param <T> the item type to be returned after suppressing any
|
|
||||||
* checked exceptions
|
|
||||||
* @param supplier the source of the return value that could cause a checked
|
|
||||||
* exception
|
|
||||||
*
|
|
||||||
* @return the product of the supplier
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("illegalcatch")
|
|
||||||
public static <T> T unchecked(final ThrowingSupplier<T> supplier) {
|
|
||||||
try {
|
try {
|
||||||
return supplier.get();
|
return wiserMessage.getMimeMessage().getSubject();
|
||||||
} catch (Throwable e) {
|
} catch (MessagingException e) {
|
||||||
throw new WiserAssertionException(e);
|
throw new IllegalArgumentException("Invalid email message", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the mime message within the {@link WiserMessage} converting any
|
|
||||||
* {@link MessagingException}s into {@link RuntimeException}s.
|
|
||||||
*
|
|
||||||
* @param wiserMessage the message
|
|
||||||
*
|
|
||||||
* @return the mime message
|
|
||||||
*/
|
|
||||||
private MimeMessage getMimeMessage(final WiserMessage wiserMessage) {
|
|
||||||
return unchecked(wiserMessage::getMimeMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that there was at least one email received that has a subject that
|
* Checks that there was at least one email received that has a subject that
|
||||||
* contains the search text.
|
* contains the search text.
|
||||||
|
@ -218,10 +184,8 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions withSubjectContains(final String subject) {
|
public WiserAssertions withSubjectContains(final String subject) {
|
||||||
Predicate<WiserMessage> predicate = m -> unchecked(
|
messageMatches(m -> subject(m).contains(subject))
|
||||||
getMimeMessage(m)::getSubject).contains(subject);
|
.orElseThrow(assertionError(ERROR_MESSAGE_SUBJECT, subject));
|
||||||
findFirstOrElseThrow(predicate,
|
|
||||||
assertionError(ERROR_MESSAGE_SUBJECT, subject));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,14 +198,51 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions withContent(final String content) {
|
public WiserAssertions withContent(final String content) {
|
||||||
findFirstOrElseThrow(m -> {
|
messageMatches(m -> messageBody(m).trim().equals(content.trim()))
|
||||||
ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
|
.orElseThrow(assertionError(ERROR_MESSAGE_CONTENT, content));
|
||||||
m).trim();
|
|
||||||
return content.equals(unchecked(contentAsString));
|
|
||||||
}, assertionError("No message with content [{0}] found!", content));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String messageBody(final WiserMessage m) {
|
||||||
|
try {
|
||||||
|
return messageBody(m.getMimeMessage().getContent());
|
||||||
|
} catch (IOException | MessagingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String messageBody(final Object content) {
|
||||||
|
return contentAsString(content)
|
||||||
|
.or(() -> contentAsMimeMessage(content))
|
||||||
|
.or(() -> contentAsMultiPartMime(content))
|
||||||
|
.orElseThrow(() -> new RuntimeException("Unexpected MimeMessage content"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Maybe<String> contentAsString(final Object content) {
|
||||||
|
if (content instanceof String) {
|
||||||
|
return Maybe.just((String) content);
|
||||||
|
}
|
||||||
|
return Maybe.nothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Maybe<String> contentAsMimeMessage(final Object content) {
|
||||||
|
if (content instanceof MimeMessage) {
|
||||||
|
return Maybe.just(content.toString());
|
||||||
|
}
|
||||||
|
return Maybe.nothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Maybe<String> contentAsMultiPartMime(final Object content) {
|
||||||
|
if (content instanceof MimeMultipart) {
|
||||||
|
try {
|
||||||
|
return Maybe.just(getMimeMultipartAsString((MimeMultipart) content));
|
||||||
|
} catch (MessagingException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Maybe.nothing();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that there was at least one email received that contains the search
|
* Check that there was at least one email received that contains the search
|
||||||
* text.
|
* text.
|
||||||
|
@ -251,48 +252,11 @@ public final class WiserAssertions {
|
||||||
* @return the {@code WiserAssertions} instance
|
* @return the {@code WiserAssertions} instance
|
||||||
*/
|
*/
|
||||||
public WiserAssertions withContentContains(final String content) {
|
public WiserAssertions withContentContains(final String content) {
|
||||||
StringBuilder messageContent = new StringBuilder();
|
messageMatches((WiserMessage m) -> messageBody(m).trim().contains(content))
|
||||||
findFirstOrElseThrow((WiserMessage m) -> {
|
.orElseThrow(assertionError(ERROR_MESSAGE_CONTENT_CONTAINS, content));
|
||||||
ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
|
|
||||||
m).trim();
|
|
||||||
messageContent.append(unchecked(contentAsString));
|
|
||||||
return unchecked(contentAsString).contains(content);
|
|
||||||
}, assertionError(
|
|
||||||
"No message with content containing [{0}] found! Was {1}",
|
|
||||||
content, messageContent));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the body of the message.
|
|
||||||
*
|
|
||||||
* @param message the message
|
|
||||||
*
|
|
||||||
* @return the body of the message
|
|
||||||
*
|
|
||||||
* @throws IOException if error extracting the mime message
|
|
||||||
* @throws MessagingException if the message type is not known
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("npathcomplexity")
|
|
||||||
private String getMimeMessageBody(final WiserMessage message)
|
|
||||||
throws IOException, MessagingException {
|
|
||||||
final Object content = getMimeMessage(message).getContent();
|
|
||||||
String result = null;
|
|
||||||
if (content instanceof String) {
|
|
||||||
result = (String) content;
|
|
||||||
}
|
|
||||||
if (content instanceof MimeMessage) {
|
|
||||||
result = content.toString();
|
|
||||||
}
|
|
||||||
if (content instanceof MimeMultipart) {
|
|
||||||
result = getMimeMultipartAsString((MimeMultipart) content);
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
throw new MimeMessageException("Unexpected MimeMessage content");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a {@link MimeMultipart} into a {@link String} stripping out the
|
* Converts a {@link MimeMultipart} into a {@link String} stripping out the
|
||||||
* mime part boundary and headers..
|
* mime part boundary and headers..
|
||||||
|
@ -318,22 +282,4 @@ public final class WiserAssertions {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for providing a value that could thrown an exception when
|
|
||||||
* sought.
|
|
||||||
*
|
|
||||||
* @param <T> the type of value to be supplied
|
|
||||||
*/
|
|
||||||
public interface ThrowingSupplier<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value.
|
|
||||||
*
|
|
||||||
* @return the value
|
|
||||||
*
|
|
||||||
* @throws Throwable on error
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("illegalthrows")
|
|
||||||
T get() throws Throwable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue