FluentShortMessageMessageAssert.java

  1. package fr.sii.ogham.testing.assertion.sms;

  2. import static fr.sii.ogham.testing.assertion.util.AssertionHelper.assertThat;
  3. import static fr.sii.ogham.testing.assertion.util.AssertionHelper.usingContext;
  4. import static java.util.Collections.unmodifiableList;
  5. import static org.apache.commons.lang3.ArrayUtils.toObject;

  6. import java.util.Arrays;
  7. import java.util.List;

  8. import org.hamcrest.Matcher;

  9. import fr.sii.ogham.testing.assertion.util.AssertionRegistry;
  10. import fr.sii.ogham.testing.sms.simulator.bean.SubmitSm;
  11. import fr.sii.ogham.testing.util.HasParent;

  12. /**
  13.  * Make assertions on {@code short_message} field.
  14.  *
  15.  * @author AurĂ©lien Baudet
  16.  *
  17.  * @param <P>
  18.  *            Parent type
  19.  * @param <S>
  20.  *            Sent SubmitSm type
  21.  */
  22. public class FluentShortMessageMessageAssert<P, S extends SubmitSm> extends HasParent<P> {
  23.     private final List<ShortMessageWithContext<S>> actual;
  24.     private final AssertionRegistry registry;

  25.     /**
  26.      * Initializes with the list of short messages and the parent.
  27.      *
  28.      * @param actual
  29.      *            the list of short messages (whit extra context for error
  30.      *            reporting)
  31.      * @param parent
  32.      *            the parent (used by {@link #and()})
  33.      * @param registry
  34.      *            used to register assertions
  35.      */
  36.     public FluentShortMessageMessageAssert(List<ShortMessageWithContext<S>> actual, P parent, AssertionRegistry registry) {
  37.         super(parent);
  38.         this.actual = unmodifiableList(actual);
  39.         this.registry = registry;
  40.     }

  41.     /**
  42.      * Make assertions on the header byte array of short message field of the
  43.      * message(s) using fluent API. The header byte array may be null. This is
  44.      * the default behavior. However, if the original message is split into
  45.      * several segments, each segment has a header that contains information to
  46.      * indicate how the message was split (number of segments, reference number,
  47.      * current segment number, ...).
  48.      *
  49.      * <pre>
  50.      * .receivedMessages()
  51.      *   .message(0)
  52.      *     .rawRequest()
  53.      *       .shortMessage()
  54.      *         .header(array(equalTo(0x01), equalTo(0x02)))
  55.      * </pre>
  56.      *
  57.      * Will check if the header byte array of the first message is exactly
  58.      * [0x01, 0x02].
  59.      *
  60.      * <pre>
  61.      * .receivedMessages()
  62.      *   .every()
  63.      *     .rawRequest()
  64.      *       .shortMessage()
  65.      *         .header(array(equalTo(0x01), equalTo(0x02)))
  66.      * </pre>
  67.      *
  68.      * Will check if the header byte array of every message is exactly [0x01,
  69.      * 0x02].
  70.      *
  71.      * @param matcher
  72.      *            the assertion to apply on the header
  73.      * @return the fluent API for chaining assertions on received message(s)
  74.      */
  75.     public FluentShortMessageMessageAssert<P, S> header(Matcher<? super Byte[]> matcher) {
  76.         String message = "header of ${name} of message ${messageIndex}";
  77.         for (ShortMessageWithContext<S> shortMessageWithContext : actual) {
  78.             S msg = shortMessageWithContext.getRequest();
  79.             registry.register(() -> assertThat(toObject(getHeader(msg)), usingContext(message, shortMessageWithContext, matcher)));
  80.         }
  81.         return this;
  82.     }

  83.     /**
  84.      * Make assertions on the payload byte array of short message field of the
  85.      * message(s) using fluent API. The payload is the part without the header
  86.      * (see {@link #header(Matcher)}). It contains the message (as byte array)
  87.      * displayed to the end-user.
  88.      *
  89.      * <pre>
  90.      * .receivedMessages()
  91.      *   .message(0)
  92.      *     .rawRequest()
  93.      *       .shortMessage()
  94.      *         .payload(arrayWithSize(160))
  95.      * </pre>
  96.      *
  97.      * Will check if the payload byte array of the first message has exactly 160
  98.      * bytes.
  99.      *
  100.      * <pre>
  101.      * .receivedMessages()
  102.      *   .every()
  103.      *     .rawRequest()
  104.      *       .shortMessage()
  105.      *         .payload(arrayWithSize(160))
  106.      * </pre>
  107.      *
  108.      * Will check if the payload byte array of the first message has exactly 160
  109.      * bytes.
  110.      *
  111.      * @param matcher
  112.      *            the assertion to apply on the payload
  113.      * @return the fluent API for chaining assertions on received message(s)
  114.      */
  115.     public FluentShortMessageMessageAssert<P, S> payload(Matcher<? super Byte[]> matcher) {
  116.         String message = "payload of ${name} of message ${messageIndex}";
  117.         for (ShortMessageWithContext<S> shortMessageWithContext : actual) {
  118.             S msg = shortMessageWithContext.getRequest();
  119.             registry.register(() -> assertThat(toObject(getPayload(msg)), usingContext(message, shortMessageWithContext, matcher)));
  120.         }
  121.         return this;
  122.     }

  123.     @SuppressWarnings("squid:S1168")
  124.     private byte[] getHeader(S msg) {
  125.         byte[] shortMessage = msg.getShortMessage();
  126.         if (msg.isUdhi()) {
  127.             return Arrays.copyOfRange(shortMessage, 0, headerLength(shortMessage));
  128.         }
  129.         return null;
  130.     }

  131.     private static int headerLength(byte[] shortMessage) {
  132.         return shortMessage[0] + 1;
  133.     }

  134.     private byte[] getPayload(S msg) {
  135.         byte[] shortMessage = msg.getShortMessage();
  136.         if (msg.isUdhi()) {
  137.             return Arrays.copyOfRange(shortMessage, headerLength(shortMessage), shortMessage.length);
  138.         }
  139.         return shortMessage;
  140.     }
  141. }