// Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_041: [The function shall set the ‘to’ property on
  // the Message object using the created event path.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_042: [The function shall set the ‘messageId’
  // property on the Message object if the messageId is not null.]
  @Test
  public void createBinaryMessageSetsToPropertyAndMessageIDIfNotNull() {
    final String hostName = "test.host.name";
    final String deviceId = "test-deviceId";
    final String userName = "******";
    final String sasToken = "test-token";
    final byte[] msgBody = {0x61, 0x62, 0x63};
    final Object messageId = "123";
    final String expectedEndpoint = "/devices/test-deviceId/messages/events";

    new NonStrictExpectations() {
      {
        new Properties();
        result = mockProperties;
      }
    };

    AmqpsIotHubConnectionBaseHandler handler =
        new AmqpsIotHubConnectionBaseHandler(
            hostName, userName, sasToken, deviceId, mockIotHubConnection);
    Deencapsulation.setField(handler, "sender", mockSender);
    handler.createBinaryMessage(msgBody, null);
    handler.createBinaryMessage(msgBody, messageId);

    new Verifications() {
      {
        mockProperties.setTo(expectedEndpoint);
        times = 2;
        mockProperties.setMessageId(messageId);
        times = 1;
        mockMessage.setProperties(mockProperties);
        times = 2;
      }
    };
  }
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_046: [The function shall open the Sender (Proton)
  // link.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_047: [The function shall return a new
  // CompletableFuture for the sent message.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_048: [The function shall lock sending on the
  // AmqpsIotHubConnection.]
  @Test
  public void createBinaryMessageOpensSenderAndLocksSending(
      @Mocked final CompletableFuture<Integer> mockFuture) {
    final String hostName = "test.host.name";
    final String deviceId = "test-deviceId";
    final String userName = "******";
    final String sasToken = "test-token";
    final byte[] msgBody = {0x61, 0x62, 0x63};
    final Object messageId = "123";

    new NonStrictExpectations() {
      {
        new CompletableFuture<Integer>();
        result = mockFuture;
      }
    };

    AmqpsIotHubConnectionBaseHandler handler =
        new AmqpsIotHubConnectionBaseHandler(
            hostName, userName, sasToken, deviceId, mockIotHubConnection);
    Deencapsulation.setField(handler, "sender", mockSender);

    CompletableFuture<Integer> actualFuture = handler.createBinaryMessage(msgBody, messageId);

    assertEquals(CompletableFuture.class, actualFuture.getClass());

    new Verifications() {
      {
        Deencapsulation.invoke(mockIotHubConnection, "lockSending");
        mockSender.open();
      }
    };
  }
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_043: [The function shall create a Binary (Proton)
  // object from the content array.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_044: [The function shall create a data Section
  // (Proton) object from the Binary.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_045: [The function shall set the Message body to
  // the created data Section.]
  @Test
  public void createBinaryMessageSetsBodyFromContent() {
    final String hostName = "test.host.name";
    final String deviceId = "test-deviceId";
    final String userName = "******";
    final String sasToken = "test-token";
    final byte[] msgBody = {0x61, 0x62, 0x63};
    final Object messageId = "123";

    AmqpsIotHubConnectionBaseHandler handler =
        new AmqpsIotHubConnectionBaseHandler(
            hostName, userName, sasToken, deviceId, mockIotHubConnection);
    Deencapsulation.setField(handler, "sender", mockSender);

    handler.createBinaryMessage(msgBody, messageId);

    new Verifications() {
      {
        mockBinary = new Binary(msgBody);
        mockSection = new Data(mockBinary);
        Message m = Deencapsulation.getField(handler, "outgoingMessage");
        m.setBody(mockSection);
      }
    };
  }
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_017: [The event handler shall get the Sender
  // (Proton) object from the link.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_018: [The event handler shall encode the message
  // and copy the contents to the byte buffer.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_019: [The event handler shall set the delivery
  // tag on the Sender (Proton) object.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_020: [The event handler shall send the encoded
  // bytes.]
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_021: [The event handler shall advance the Sender
  // and complete the sent message CompletableFuture using the Delivery (Proton) object hash code.]
  @Test
  public void onLinkFlowFullTest(@Mocked final CompletableFuture<Integer> mockFuture) {
    final String hostName = "test.host.name";
    final String deviceId = "test-deviceId";
    final String userName = "******";
    final String sasToken = "test-token";
    final byte[] msgBody = {0x61, 0x62, 0x63};
    final int tag = 0;

    new NonStrictExpectations() {
      {
        mockMessage.encode(msgBody, 0, msgBody.length);
        result = 3;
        mockEvent.getLink();
        result = mockSender;
        mockSender.getCredit();
        result = 1;
        mockSender.getUnsettled();
        result = 0;
      }
    };

    AmqpsIotHubConnectionBaseHandler handler =
        new AmqpsIotHubConnectionBaseHandler(
            hostName, userName, sasToken, deviceId, mockIotHubConnection);

    Deencapsulation.setField(handler, "sender", mockSender);
    Deencapsulation.setField(handler, "currentSentMessageFuture", mockFuture);
    handler.createBinaryMessage(msgBody, null);
    handler.onLinkFlow(mockEvent);

    new Verifications() {
      {
        mockEvent.getLink();
        byte[] buffer = new byte[1024];
        int length = mockMessage.encode(buffer, 0, buffer.length);
        byte[] deliveryTag = String.valueOf(tag).getBytes();
        Delivery d = mockSender.delivery(deliveryTag);
        mockSender.send((byte[]) any, 0, length);

        mockSender.advance();
        mockFuture.complete(d.hashCode());
      }
    };
  }
  // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_040: [The function shall create a new Message
  // (Proton) object.]
  @Test
  public void createBinaryMessageCreatesNewProtonMessage() {
    final String hostName = "test.host.name";
    final String deviceId = "test-deviceId";
    final String userName = "******";
    final String sasToken = "test-token";
    final byte[] msgBody = {0x61, 0x62, 0x63};

    AmqpsIotHubConnectionBaseHandler handler =
        new AmqpsIotHubConnectionBaseHandler(
            hostName, userName, sasToken, deviceId, mockIotHubConnection);
    Deencapsulation.setField(handler, "sender", mockSender);
    handler.createBinaryMessage(msgBody, null);

    new Verifications() {
      {
        mockMessage = mockProton.message();
      }
    };
  }