public void When_Value_Is_NAN_Json_Should_Be_Quoted(object value, string expectedJson)
        {
            var target = new DecodePayloadResult(value);
            var json   = JsonConvert.SerializeObject(target);

            Assert.Equal(expectedJson, json);
        }
        public void When_Value_Is_Numeric_Json_Should_Not_Be_Quoted(object value, string expectedJson)
        {
            var target = new DecodePayloadResult(value);
            var json   = JsonConvert.SerializeObject(target);

            Assert.Equal(expectedJson, json);

            var parsed = JsonConvert.DeserializeObject <DecodePayloadResult>(json);

            Assert.IsType(value.GetType(), parsed.Value);
        }
        public async Task Unconfirmed_Cloud_To_Device_From_Decoder_Should_Call_ClassC_Message_Sender()
        {
            const uint PayloadFcnt           = 10;
            const uint InitialDeviceFcntUp   = 9;
            const uint InitialDeviceFcntDown = 20;

            var simulatedDevice = new SimulatedDevice(
                TestDeviceInfo.CreateABPDevice(1, gatewayID: this.ServerConfiguration.GatewayID),
                frmCntUp: InitialDeviceFcntUp,
                frmCntDown: InitialDeviceFcntDown);

            var loraDevice = this.CreateLoRaDevice(simulatedDevice);

            this.LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .ReturnsAsync(true);

            this.LoRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>()))
            .ReturnsAsync((Message)null);

            var decoderResult = new DecodePayloadResult("1")
            {
                CloudToDeviceMessage = new ReceivedLoRaCloudToDeviceMessage()
                {
                    Fport     = 1,
                    MessageId = "123",
                    Payload   = "12",
                    DevEUI    = "0000000000000002",
                },
            };

            var payloadDecoder = new Mock <ILoRaPayloadDecoder>(MockBehavior.Strict);

            payloadDecoder.Setup(x => x.DecodeMessageAsync(simulatedDevice.DevEUI, It.IsNotNull <byte[]>(), 1, It.IsAny <string>()))
            .ReturnsAsync(decoderResult);
            this.PayloadDecoder.SetDecoder(payloadDecoder.Object);

            var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, this.NewNonEmptyCache(loraDevice), this.LoRaDeviceApi.Object, this.LoRaDeviceFactory);

            var c2dMessageSent      = new SemaphoreSlim(0);
            var classCMessageSender = new Mock <IClassCDeviceMessageSender>(MockBehavior.Strict);

            classCMessageSender.Setup(x => x.SendAsync(It.IsNotNull <IReceivedLoRaCloudToDeviceMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(true)
            .Callback <IReceivedLoRaCloudToDeviceMessage, CancellationToken>((m, _) =>
            {
                Assert.False(m.Confirmed);
                Assert.Equal("0000000000000002", m.DevEUI);
                c2dMessageSent.Release();
            });
            this.RequestHandlerImplementation.SetClassCMessageSender(classCMessageSender.Object);

            // Send to message processor
            var messageProcessor = new MessageDispatcher(
                this.ServerConfiguration,
                deviceRegistry,
                this.FrameCounterUpdateStrategyProvider);

            var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", fcnt: PayloadFcnt);
            var rxpk    = payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0];
            var request = this.CreateWaitableRequest(rxpk);

            messageProcessor.DispatchRequest(request);
            Assert.True(await request.WaitCompleteAsync());

            // Expectations
            // 1. Message was sent to IoT Hub
            this.LoRaDeviceClient.VerifyAll();
            this.LoRaDeviceApi.VerifyAll();

            // 2. No downstream message for the current device is sent
            Assert.Null(request.ResponseDownlink);
            Assert.True(request.ProcessingSucceeded);

            // 4. Frame counter up was updated
            Assert.Equal(PayloadFcnt, loraDevice.FCntUp);

            // 5. Frame counter down is unchanged
            Assert.Equal(InitialDeviceFcntDown, loraDevice.FCntDown);

            // 6. Frame count has pending changes
            Assert.True(loraDevice.HasFrameCountChanges);

            // Ensure the message was sent
            Assert.True(await c2dMessageSent.WaitAsync(10 * 1000));

            payloadDecoder.VerifyAll();
            classCMessageSender.VerifyAll();
        }