package fr.sii.ogham.assertion;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import javax.mail.internet.MimeMessage;
import org.apache.commons.io.IOUtils;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.jsmpp.bean.SubmitSm;
import org.w3c.dom.Document;
import com.google.common.base.Charsets;
import com.icegreen.greenmail.junit.GreenMailRule;
import fr.sii.ogham.assertion.context.Context;
import fr.sii.ogham.assertion.email.EmailsAssert;
import fr.sii.ogham.assertion.email.ReceivedEmailsAssert;
import fr.sii.ogham.assertion.hamcrest.CustomReason;
import fr.sii.ogham.assertion.hamcrest.IdenticalHtmlMatcher;
import fr.sii.ogham.assertion.hamcrest.SimilarHtmlMatcher;
import fr.sii.ogham.assertion.sms.ReceivedSmsAssert;
import fr.sii.ogham.assertion.sms.SmsListAssert;
import fr.sii.ogham.helper.sms.rule.SmppServerRule;
/**
* Utility class that helps writing message assertions. For emails, you can
* write something like this:
*
* <pre>
* assertThat(greenMail).receivedMessages().count(is(1)).message(0).subject(is("Test")).from().address(hasItems("test.sender@sii.fr")).and().to().address(hasItems("recipient@sii.fr")).and().body()
* .contentAsString(is("body")).contentType(startsWith("text/plain")).and().alternative(nullValue()).attachments(hasSize(1)).attachment("04-Java-OOP-Basics.pdf")
* .content(is(resource("/attachment/04-Java-OOP-Basics.pdf"))).contentType(startsWith("application/pdf")).filename(is("04-Java-OOP-Basics.pdf")).disposition(is(ATTACHMENT_DISPOSITION));
* </pre>
*
* For sms, you can write something like this:
*
* <pre>
* assertThat(smppServer).receivedMessages().count(is(1)).message(0).content(is("sms content")).from().number(is(INTERNATIONAL_PHONE_NUMBER)).typeOfNumber(is(TypeOfNumber.INTERNATIONAL))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN)).and().to().number(is(NATIONAL_PHONE_NUMBER)).typeOfNumber(is(TypeOfNumber.UNKNOWN))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN));
* </pre>
*
*
*
* @author Aurélien Baudet
*
*/
public class OghamAssertions {
// @formatter:off
/**
* Helper method to write assertions on mails using fluent API.
* For example:
* <pre>
* assertThat(greenMail).receivedMessages()
* .count(is(1))
* .message(0)
* .subject(is("Test"))
* .from().address(hasItems("test.sender@sii.fr")).and()
* .to().address(hasItems("recipient@sii.fr")).and()
* .body()
* .contentAsString(is("body"))
* .contentType(startsWith("text/plain")).and()
* .alternative(nullValue())
* .attachments(hasSize(1))
* .attachment("04-Java-OOP-Basics.pdf")
* .content(is(resource("/attachment/04-Java-OOP-Basics.pdf")))
* .contentType(startsWith("application/pdf"))
* .filename(is("04-Java-OOP-Basics.pdf"))
* .disposition(is(ATTACHMENT_DISPOSITION));
* </pre>
*
* @param greenMail
* email server that stores received messages
* @return builder for fluent assertions on received messages
*/
// @formatter:on
public static ReceivedEmailsAssert assertThat(GreenMailRule greenMail) {
return new ReceivedEmailsAssert(Arrays.asList(greenMail.getReceivedMessages()));
}
// @formatter:off
/**
* Helper method to write assertions on mails using fluent API.
* For example:
* <pre>
* assertThat(greenMail.getReceivedMessages())
* .count(is(1))
* .message(0)
* .subject(is("Test"))
* .from().address(hasItems("test.sender@sii.fr")).and()
* .to().address(hasItems("recipient@sii.fr")).and()
* .body()
* .contentAsString(is("body"))
* .contentType(startsWith("text/plain")).and()
* .alternative(nullValue())
* .attachments(hasSize(1))
* .attachment("04-Java-OOP-Basics.pdf")
* .content(is(resource("/attachment/04-Java-OOP-Basics.pdf")))
* .contentType(startsWith("application/pdf"))
* .filename(is("04-Java-OOP-Basics.pdf"))
* .disposition(is(ATTACHMENT_DISPOSITION));
* </pre>
*
* @param receivedEmails
* list of messages received by the email server
* @return builder for fluent assertions on received messages
*/
// @formatter:on
public static EmailsAssert<Void> assertThat(MimeMessage[] receivedEmails) {
return new EmailsAssert<>(Arrays.asList(receivedEmails), null);
}
// @formatter:off
/**
* Helper method to write assertions on sms using fluent API.
* For example:
* <pre>
* assertThat(smppServer).receivedMessages()
* .count(is(1))
* .message(0)
* .content(is("sms content"))
* .from()
* .number(is(INTERNATIONAL_PHONE_NUMBER))
* .typeOfNumber(is(TypeOfNumber.INTERNATIONAL))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN)).and()
* .to()
* .number(is(NATIONAL_PHONE_NUMBER))
* .typeOfNumber(is(TypeOfNumber.UNKNOWN))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN));
* </pre>
*
* @param smsServer
* SMS server that stores received messages
* @return builder for fluent assertions on received messages
*/
// @formatter:on
public static ReceivedSmsAssert assertThat(SmppServerRule<SubmitSm> smsServer) {
return new ReceivedSmsAssert(smsServer.getReceivedMessages());
}
// @formatter:off
/**
* Helper method to write assertions on sms using fluent API.
* For example:
* <pre>
* assertThat(smppServer.getReceivedMessages())
* .count(is(1))
* .message(0)
* .content(is("sms content"))
* .from()
* .number(is(INTERNATIONAL_PHONE_NUMBER))
* .typeOfNumber(is(TypeOfNumber.INTERNATIONAL))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN)).and()
* .to()
* .number(is(NATIONAL_PHONE_NUMBER))
* .typeOfNumber(is(TypeOfNumber.UNKNOWN))
* .numberPlanIndicator(is(NumberingPlanIndicator.ISDN));
* </pre>
*
* @param receivedSms
* The list of messages received by the SMS server
* @return builder for fluent assertions on received messages
*/
// @formatter:on
public static SmsListAssert<Void> assertThat(List<SubmitSm> receivedSms) {
return new SmsListAssert<>(receivedSms, null);
}
/**
* Ogham helper for keeping context information when using fluent
* assertions.
*
* @param reasonTemplate
* the template for the reason
* @param context
* the evaluation context
* @param delegate
* the matcher to decorate
* @param <T>
* the type used for the matcher
* @return the matcher
*/
public static <T> Matcher<T> usingContext(String reasonTemplate, Context context, Matcher<T> delegate) {
return new CustomReason<>(context.evaluate(reasonTemplate), delegate);
}
/**
* Check if the HTML is similar to the expected. The HTML strings are parsed
* into {@link Document}s. Two documents are considered to be "similar" if
* they contain the same elements and attributes regardless of order.
*
* @param expectedHtml
* the expected HTML
* @return the matcher that will check if HTML is identical to expected HTML
*/
@Factory
public static Matcher<String> isSimilarHtml(String expectedHtml) {
return new SimilarHtmlMatcher(expectedHtml);
}
/**
* Check if the HTML is identical to the expected. The HTML strings are
* parsed into {@link Document}s. Two documents are considered to be
* "identical" if they contain the same elements and attributes in the same
* order.
*
* @param expectedHtml
* the expected HTML
* @return the matcher that will check if HTML is identical to expected HTML
*/
@Factory
public static Matcher<String> isIdenticalHtml(String expectedHtml) {
return new IdenticalHtmlMatcher(expectedHtml);
}
/**
* Utility method that loads a file content from the classpath. UTF-8
* charset is used.
*
* @param path
* the path to the classpath resource
* @return the content of the file
* @throws IOException
* when resource can't be read or doesn't exist
*/
public static String resourceAsString(String path) throws IOException {
return resourceAsString(path, Charsets.UTF_8);
}
/**
* Utility method that loads a file content from the classpath.
*
* @param path
* the path to the classpath resource
* @param charset
* the charset used for reading the file
* @return the content of the file
* @throws IOException
* when resource can't be read or doesn't exist
*/
public static String resourceAsString(String path, Charset charset) throws IOException {
return IOUtils.toString(resource(path), charset.name());
}
/**
* Utility method that loads a file content from the classpath.
*
* @param path
* the path to the classpath resource
* @return the content of the file as byte array
* @throws IOException
* when resource can't be read or doesn't exist
*/
public static byte[] resource(String path) throws IOException {
InputStream resource = OghamAssertions.class.getClassLoader().getResourceAsStream(path.startsWith("/") ? path.substring(1) : path);
if (resource == null) {
throw new FileNotFoundException("No resource found for path " + path);
}
return IOUtils.toByteArray(resource);
}
private OghamAssertions() {
super();
}
}