diff --git a/src/IoTHub.Portal.Infrastructure/Services/LoRaWanManagementService.cs b/src/IoTHub.Portal.Infrastructure/Services/LoRaWanManagementService.cs index e2199400d..dd4e7efce 100644 --- a/src/IoTHub.Portal.Infrastructure/Services/LoRaWanManagementService.cs +++ b/src/IoTHub.Portal.Infrastructure/Services/LoRaWanManagementService.cs @@ -38,9 +38,17 @@ public async Task ExecuteLoRaDeviceMessage(string deviceId, ArgumentNullException.ThrowIfNull(deviceId, nameof(deviceId)); ArgumentNullException.ThrowIfNull(commandDto, nameof(commandDto)); + // Convert the hex frame to a byte array + var hexFrame = Enumerable.Range(0, commandDto.Frame.Length / 2) + .Select(x => Convert.ToByte(commandDto.Frame.Substring(x * 2, 2), 16)) + .ToArray(); + + // Convert the byte array to a base64 string + var rawPayload = Convert.ToBase64String(hexFrame); + var body = new LoRaCloudToDeviceMessage { - RawPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(commandDto.Frame)), + RawPayload = rawPayload, Fport = commandDto.Port, Confirmed = commandDto.Confirmed }; diff --git a/src/IoTHub.Portal.Tests.Unit/Infrastructure/Services/LoRaWanManagementServiceTests.cs b/src/IoTHub.Portal.Tests.Unit/Infrastructure/Services/LoRaWanManagementServiceTests.cs index dc63aaa19..b90a0318a 100644 --- a/src/IoTHub.Portal.Tests.Unit/Infrastructure/Services/LoRaWanManagementServiceTests.cs +++ b/src/IoTHub.Portal.Tests.Unit/Infrastructure/Services/LoRaWanManagementServiceTests.cs @@ -18,6 +18,8 @@ namespace IoTHub.Portal.Tests.Unit.Infrastructure.Services using NUnit.Framework; using RichardSzalay.MockHttp; using UnitTests.Bases; + using System.Linq; + using Fare; [TestFixture] public class LoRaWanManagementServiceTests : BackendUnitTest @@ -63,14 +65,60 @@ public async Task ExecuteLoRaDeviceMessageMustBeSuccessfullWhenParametersAreProv { // Arrange var deviceId = Fixture.Create(); + + string regex = "[0-9A-F]{8,15}"; + + Xeger xeger = new Xeger(regex, new Random(0)); // Note zero in Random constructor + + var command = new DeviceModelCommandDto + { + Frame = xeger.Generate(), + Confirmed = Fixture.Create(), + Port = Fixture.Create() + }; + + var expectedRawPayload = Convert.ToBase64String(Enumerable.Range(0, command.Frame.Length / 2).Select(x => Convert.ToByte(command.Frame.Substring(x * 2, 2), 16)).ToArray()); + + _ = MockHttpClient.When(HttpMethod.Post, $"/api/cloudtodevicemessage/{deviceId}") + .With(m => + { + _ = m.Content.Should().BeAssignableTo(); + var body = (JsonContent) m.Content; + var loRaCloudToDeviceMessage = (LoRaCloudToDeviceMessage)body?.Value; + _ = loRaCloudToDeviceMessage?.Should().NotBeNull(); + _ = loRaCloudToDeviceMessage?.Fport.Should().Be(command.Port); + _ = loRaCloudToDeviceMessage?.Confirmed.Should().Be(command.Confirmed); + _ = loRaCloudToDeviceMessage?.RawPayload.Should().Be(expectedRawPayload); + return true; + }) + .Respond(HttpStatusCode.Created); + + // Act + var result = await this.loRaWanManagementService.ExecuteLoRaDeviceMessage(deviceId, command); + + // Assert + _ = result.Should().NotBeNull(); + _ = result.IsSuccessStatusCode.Should().BeTrue(); + MockHttpClient.VerifyNoOutstandingRequest(); + MockHttpClient.VerifyNoOutstandingExpectation(); + } + + [Test] + public async Task ExecuteLoRaDeviceMessageMustBeSuccessfullWhenParametersAndCommandAreProvided() + { + // Arrange + var deviceId = Fixture.Create(); + + var commandHex = "0113007801680100640064"; + var command = new DeviceModelCommandDto { - Frame = Fixture.Create(), + Frame = commandHex, Confirmed = Fixture.Create(), Port = Fixture.Create() }; - var expectedRawPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(command.Frame)); + var expectedRawPayload = "ARMAeAFoAQBkAGQ="; _ = MockHttpClient.When(HttpMethod.Post, $"/api/cloudtodevicemessage/{deviceId}") .With(m =>