public void AddRemoveItemDoesNotFireTimeoutEvent()
        {
            MqttProtocolInformation.Settings.NetworkTimeout = 4; // 4 seconds
            var store = new MessageStore();
            var are = new AutoResetEvent(false);
            var eventData = "Test data";
            string connectionKey = "123";
            var msg = new MqttPublishMessageBuilder
            {
                MessageId = 42,
                QualityOfService = QualityOfService.AtLeastOnce,
                TopicName = "a/b/c"
            };

            store.MessageTimeout += (sender, args) =>
            {
                Assert.Fail("MessageTimeout event fired but should not have.");
                are.Set();
            };

            store.Add(msg.GetMessage(), eventData, connectionKey);
            Thread.Sleep(1000);
            store.Remove(MessageType.PubAck, 42, connectionKey);
            if (!are.WaitOne(MqttProtocolInformation.Settings.NetworkTimeout*2))
            {
                Assert.AreEqual(0, store.Count);
            }
        }
        public void AddItemWithoutRemovingItFiresTimeoutEvent()
        {
            MqttProtocolInformation.Settings.NetworkTimeout = 4; // 4 seconds
            var store = new MessageStore();
            var are = new AutoResetEvent(false);
            var eventData = "Test data";
            string connectionKey = "123";
            var msgBldr = new MqttPublishMessageBuilder
            {
                MessageId = 42,
                QualityOfService = QualityOfService.AtLeastOnce,
                TopicName = "a/b/c"
            };
            var msg = msgBldr.GetMessage();

            store.MessageTimeout += (sender, args) =>
            {
                Assert.AreEqual(msg, args.FailedMessage);
                Assert.AreEqual(eventData, args.EventData);
                are.Set();
            };

            store.Add(msg, eventData, connectionKey);
            if (!are.WaitOne(MqttProtocolInformation.Settings.NetworkTimeout*2*1000))
            {
                Assert.Fail("Timeout event did not fire.");
            }
        }
        public void CanReadMessageId()
        {
            string topic = "Tests/MqttPublishMessage/Test1";
            int id = 42;
            var msgBuilder = new MqttPublishMessageBuilder()
            {
                TopicName = topic,
                MessageId = id,
                QualityOfService = QualityOfService.AtLeastOnce

            };

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            Assert.AreEqual(id, msg.MessageId);
        }
        public void RemoveItemReturnsEventData()
        {
            MqttProtocolInformation.Settings.NetworkTimeout = 4; // 4 seconds
            var store = new MessageStore();
            var eventData = "Test data";
            string connectionKey = "123";
            var msg = new MqttPublishMessageBuilder
            {
                MessageId = 42,
                QualityOfService = QualityOfService.AtLeastOnce,
                TopicName = "a/b/c"
            };

            store.Add(msg.GetMessage(), eventData, connectionKey);
            Thread.Sleep(1000);
            object testData = store.Remove(MessageType.PubAck, 42, connectionKey);
            Assert.AreSame(eventData, testData);
        }
        public void CanReadProtocolHeader()
        {
            string topic = "Tests/MqttPublishMessage/Test1";
            var msgBuilder = new MqttPublishMessageBuilder()
            {
                Duplicate = true,
                QualityOfService = QualityOfService.ExactlyOnce,
                Retain = true,
                TopicName = topic
            };

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            Assert.AreEqual(msgBuilder.Duplicate, msg.Duplicate);
            Assert.AreEqual(msgBuilder.QualityOfService, msg.QualityOfService);
            Assert.AreEqual(msgBuilder.Retain, msg.Retain);
            Assert.AreEqual(msgBuilder.TopicName, msg.TopicName);
        }
        public void TopicNameValidationCatchesUnsetTopicName()
        {
            var msgBuilder = new MqttPublishMessageBuilder()
            {
                MessageId = 42
            };

            try
            {
                var msg = msgBuilder.GetMessage() as MqttPublishMessage;
            }
            catch (ArgumentException)
            {
                return;
            }
            catch (Exception)
            {
                Assert.Fail("Incorrect exception type thrown.");
            }

            Assert.Fail("No exception thrown for invalid TopicName");
        }
        public void CanCreateFromMessageBuilder()
        {
            string topic = "Tests/MqttPublishMessage/Test1";
            var msgBuilder = new MqttPublishMessageBuilder()
            {
                QualityOfService = QualityOfService.AtMostOnce,
                TopicName = topic
            };

            Assert.AreEqual(MessageType.Publish, msgBuilder.MessageType);
            Assert.AreEqual(QualityOfService.AtMostOnce, msgBuilder.QualityOfService);
            Assert.AreEqual(0, msgBuilder.Payload.Length);

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            Assert.IsNotNull(msg);
            Assert.AreEqual(MessageType.Publish, msg.MessageType);
            Assert.AreEqual(false, msg.Duplicate);
            Assert.AreEqual(QualityOfService.AtMostOnce, msg.QualityOfService);
            Assert.AreEqual(false, msg.Retain);
            Assert.AreEqual(topic, msg.TopicName);
            Assert.AreEqual(0, msg.Payload.Length);
        }
        public void PublishAsync(string topic, byte[] payload, QualityOfService qos, int messageId, bool retain)
        {
            var msgBuilder = new MqttPublishMessageBuilder
            {
                MessageId = messageId,
                TopicName = topic,
                QualityOfService = qos,
                Retain = retain,
                Payload = payload
            };

            SendMessageAsync(msgBuilder);
        }
        public void ReceivePublishQosLevel2CallsMessageReceived()
        {
            var are = new AutoResetEvent(false);
            var moqSocket = new MoqSocket();
            var client = new MqttClientProtocol(new LogCompositor(), moqSocket);
            var topic = "a/b/c";
            var id = 42;
            var bldr = new MqttPublishMessageBuilder
            {
                MessageId = id,
                QualityOfService = QualityOfService.ExactlyOnce,
                TopicName = topic
            };

            client.PublishReceived += (sender, args) =>
            {
                var pubMsg = args.Message as MqttPublishMessage;
                Assert.IsNotNull(pubMsg);
                Assert.AreEqual(topic, pubMsg.TopicName);
                Assert.AreEqual(2, moqSocket.SentMessages.Count);
                Assert.AreEqual(id, pubMsg.MessageId);
                Assert.IsTrue(moqSocket.SentMessages.Contains(MessageType.PubRec));
                Assert.IsTrue(moqSocket.SentMessages.Contains(MessageType.PubComp));
                are.Set();
            };

            moqSocket.ReceiveMessage(bldr);

            if (!are.WaitOne(5000))
            {
                Assert.Fail("PublishReceived event not fired for received Publish (Qos=ExactlyOnce).");
            }
        }
        public void PublishQosLevel2CallsSendMessageCompleteEventWithEventData()
        {
            var are = new AutoResetEvent(false);
            var eventData = "Test data";
            var moqSocket = new MoqSocket();
            var client = new MqttClientProtocol(new LogCompositor(), moqSocket);
            var bldr = new MqttPublishMessageBuilder
            {
                MessageId = 42,
                QualityOfService = QualityOfService.ExactlyOnce,
                TopicName = "a/b/c"
            };

            client.SendMessageComplete += (sender, args) =>
            {
                var msg = args.Message as IMqttIdMessage;
                Assert.IsNotNull(msg);
                Assert.AreEqual(bldr.MessageId, msg.MessageId);
                Assert.AreSame(eventData, args.EventData);
                Assert.IsTrue(moqSocket.SentMessages.Contains(MessageType.Publish));
                Assert.IsFalse(moqSocket.SentMessages.Contains(MessageType.PubRec));
                Assert.IsTrue(moqSocket.SentMessages.Contains(MessageType.PubRel));
                Assert.IsFalse(moqSocket.SentMessages.Contains(MessageType.PubComp));
                are.Set();
            };

            client.SendMessageAsync(bldr, eventData, null);

            if (!are.WaitOne(5000))
            {
                Assert.Fail("SendMessageComplete event not fired for Publish (Qos=ExactlyOnce).");
            }
        }
        public IAsyncAction PublishAsync(
            string topic,
            [ReadOnlyArray]
            byte[] payload,
            QualityOfService qos,
            int messageId,
            bool retain
            )
        {
            var msgBuilder = new MqttPublishMessageBuilder
            {
                QualityOfService = qos,
                MessageId = messageId,
                Retain = retain,
                TopicName = topic,
                Payload = payload
            };

            return SendMessageAsync(msgBuilder);
        }
        public void MessageIdValidationCatchesOutOfRangeMessageId()
        {
            string topic = "Tests/MqttPublishMessage/Test1";
            var msgBuilder = new MqttPublishMessageBuilder()
            {
                TopicName = topic
            };

            try
            {
                msgBuilder.MessageId = 0x1FFFF;
            }
            catch (ArgumentException)
            {
                return;
            }
            catch (Exception)
            {
                Assert.Fail("Incorrect exception type thrown.");
            }

            Assert.Fail("No exception thrown for out of range MessageID");
        }
        public void CanReadInt16Payload()
        {
            int i = 23321;
            int pos = 0;
            var payloadBytes = new byte[2];
            Frame.EncodeInt16(i, payloadBytes, ref pos);

            var msgBuilder = new MqttPublishMessageBuilder()
            {
                TopicName = "Tests/MqttPublishMessage/Test1",
                MessageId = 42,
                Payload = payloadBytes
            };

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            int result = msg.Int16Payload;
            Assert.AreEqual(i, result);
        }
        public void CanReadStringPayload()
        {
            string str = "This is a test.";
            byte[] payload = Encoding.UTF8.GetBytes(str);

            var msgBuilder = new MqttPublishMessageBuilder()
            {
                TopicName = "Tests/MqttPublishMessage/Test1",
                MessageId = 42,
                Payload = payload
            };

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            string result = msg.StringPayload;
            Assert.AreEqual(str, result);
        }
        public void CanReadBinaryPayload()
        {
            string topic = "Tests/MqttPublishMessage/Test1";
            int id = 42;
            byte[] payload = new[] { (byte)0x0, (byte)0x1, (byte)0x2, (byte)0x3, (byte)0x4, (byte)0x5 };

            var msgBuilder = new MqttPublishMessageBuilder()
            {
                TopicName = topic,
                MessageId = id,
                Payload = payload
            };

            var msg = msgBuilder.GetMessage() as MqttPublishMessage;

            Assert.AreEqual(payload.Length, msg.Payload.Length);
            Assert.AreEqual(payload[0], msg.Payload[0]);
            Assert.AreEqual(payload[payload.Length - 1], msg.Payload[payload.Length-1]);
        }