Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set device tags on device create/details screens #366

Merged
merged 49 commits into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
dd8222a
Fix Namespace issue
audserraCGI Feb 25, 2022
7e1c542
Added DeviceTagService + Custom tags on CreateDevicePage
audserraCGI Feb 28, 2022
c28c7e9
Customised tag on DeviceDetailPage
audserraCGI Feb 28, 2022
4329597
List<DeviceTag> changed to List<string> in CreateDeviceDetails()
audserraCGI Feb 28, 2022
d376db0
Fix DeviceMapper Tests to work with new DeviceDetails model
audserraCGI Mar 1, 2022
10d2773
Fix DevicesControllerTests with new DeviceDetails model
audserraCGI Mar 1, 2022
33d5e00
Added DeviceTagService Test
audserraCGI Mar 1, 2022
e97a555
Added DEviceTagsSettingsController test
audserraCGI Mar 2, 2022
3272070
Fix Namespace issue
audserraCGI Feb 25, 2022
0f66cc2
Added DeviceTagService + Custom tags on CreateDevicePage
audserraCGI Feb 28, 2022
098261e
Customised tag on DeviceDetailPage
audserraCGI Feb 28, 2022
bd8a5ac
List<DeviceTag> changed to List<string> in CreateDeviceDetails()
audserraCGI Feb 28, 2022
965c99f
Fix DeviceMapper Tests to work with new DeviceDetails model
audserraCGI Mar 1, 2022
babb8e7
Fix DevicesControllerTests with new DeviceDetails model
audserraCGI Mar 1, 2022
9a9dd65
Added DeviceTagService Test
audserraCGI Mar 1, 2022
0c82b41
Added DEviceTagsSettingsController test
audserraCGI Mar 2, 2022
d7c1a5a
Merge
audserraCGI Mar 2, 2022
2af0f24
Fixed typo when merging
audserraCGI Mar 2, 2022
6029fcd
Fix code scanning errors
audserraCGI Mar 2, 2022
3652927
Small fix
audserraCGI Mar 2, 2022
ff2bacb
Added form validation on front side
audserraCGI Mar 3, 2022
a9cf802
Added form validation on Edit page
audserraCGI Mar 3, 2022
098d2ff
Fix comments
audserraCGI Mar 3, 2022
835112d
Fix #362 - Update API version + Better treat errors (#378)
kbeaugrand Mar 3, 2022
cafa2d8
Fix #308 - Remove useless pages in table queries (#379)
kbeaugrand Mar 4, 2022
ef74bcd
Fix tests and clear code
audserraCGI Mar 4, 2022
0c94d83
Fix change in pagination conflict
audserraCGI Mar 4, 2022
b65c6cb
Fix Namespace issue
audserraCGI Feb 25, 2022
3281094
Added DeviceTagService + Custom tags on CreateDevicePage
audserraCGI Feb 28, 2022
d422685
Customised tag on DeviceDetailPage
audserraCGI Feb 28, 2022
c7e1fe5
List<DeviceTag> changed to List<string> in CreateDeviceDetails()
audserraCGI Feb 28, 2022
bda4e48
Fix DeviceMapper Tests to work with new DeviceDetails model
audserraCGI Mar 1, 2022
8e3c21c
Fix DevicesControllerTests with new DeviceDetails model
audserraCGI Mar 1, 2022
dd692d6
Added DeviceTagService Test
audserraCGI Mar 1, 2022
0dd8271
Added DEviceTagsSettingsController test
audserraCGI Mar 2, 2022
61df518
Added DeviceTagService + Custom tags on CreateDevicePage
audserraCGI Feb 28, 2022
bd9f040
List<DeviceTag> changed to List<string> in CreateDeviceDetails()
audserraCGI Feb 28, 2022
20bb96c
Added DeviceTagService Test
audserraCGI Mar 1, 2022
2350095
Added DEviceTagsSettingsController test
audserraCGI Mar 2, 2022
7c36689
Fixed typo when merging
audserraCGI Mar 2, 2022
8ee567e
Fix code scanning errors
audserraCGI Mar 2, 2022
7eef934
Small fix
audserraCGI Mar 2, 2022
cd08aeb
Added form validation on front side
audserraCGI Mar 3, 2022
7a155b3
Added form validation on Edit page
audserraCGI Mar 3, 2022
24760c6
Fix comments
audserraCGI Mar 3, 2022
c6d59e4
Fix tests and clear code
audserraCGI Mar 4, 2022
173becd
Fix change in pagination conflict
audserraCGI Mar 4, 2022
dedd9c8
Merge branch '236_set_tag_on_devices' of github.com:CGI-FR/iot-hub-po…
audserraCGI Mar 4, 2022
61bd865
Update src/AzureIoTHub.Portal/Server/Controllers/v1.0/DeviceTagSettin…
audserraCGI Mar 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,52 @@ public void When_Model_NotExists_Get_Should_Return_404()
this.mockRepository.VerifyAll();
}

[Test]
public void Get_Should_Return_Device_Model_Commands()
{
// Arrange
var deviceModel = SetupMockDeviceModel();
var deviceModelId = deviceModel.RowKey;
var deviceModelCommandsController = this.CreateDeviceModelCommandsController();
var mockResponse = this.mockRepository.Create<Response>();

this.mockCommandsTableClient.Setup(c => c.Query<TableEntity>(
It.Is<string>(x => x == $"PartitionKey eq '{ deviceModelId }'"),
It.IsAny<int?>(),
It.IsAny<IEnumerable<string>>(),
It.IsAny<CancellationToken>()))
.Returns(Pageable<TableEntity>.FromPages(new[]
{
Page<TableEntity>.FromValues(new[]
{
new TableEntity(deviceModelId, Guid.NewGuid().ToString())
}, null, mockResponse.Object)
}));

this.mockTableClientFactory.Setup(c => c.GetDeviceCommands())
.Returns(mockCommandsTableClient.Object);

this.mockDeviceModelCommandMapper.Setup(c => c.GetDeviceModelCommand(
It.Is<TableEntity>(x => x.PartitionKey == deviceModelId)))
.Returns(new DeviceModelCommand { });

// Act
var response = deviceModelCommandsController.Get(deviceModelId);

// Assert
Assert.IsNotNull(response);
Assert.IsAssignableFrom<OkObjectResult>(response.Result);

var okResult = (OkObjectResult)response.Result;

Assert.IsNotNull(okResult);
Assert.IsAssignableFrom<DeviceModelCommand[]>(okResult.Value);

var result = (DeviceModelCommand[])okResult.Value;
Assert.IsNotNull(result);
Assert.AreEqual(1, result.Length);
}

private TableEntity SetupMockDeviceModel()
{
var mockResponse = this.mockRepository.Create<Response<TableEntity>>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Azure;
using Azure.Data.Tables;
using AzureIoTHub.Portal.Server.Controllers.v10;
using AzureIoTHub.Portal.Server.Controllers.V10;
using AzureIoTHub.Portal.Server.Factories;
using AzureIoTHub.Portal.Server.Mappers;
using AzureIoTHub.Portal.Shared.Models.v10.Device;
using AzureIoTHub.Portal.Server.Services;
using AzureIoTHub.Portal.Shared.Models.V10.Device;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
Expand All @@ -23,29 +24,32 @@ public class DeviceTagSettingsControllerTest
{
private MockRepository mockRepository;

private Mock<IDeviceTagMapper> mockDeviceTagMapper;
private Mock<ITableClientFactory> mockTableClientFactory;
private Mock<TableClient> mockDeviceTagTableClient;
//private Mock<IDeviceTagMapper> mockDeviceTagMapper;
//private Mock<ITableClientFactory> mockTableClientFactory;
//private Mock<TableClient> mockDeviceTagTableClient;
private Mock<IDeviceTagService> mockDeviceTagService;
private Mock<ILogger<DeviceTagSettingsController>> mockLogger;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);

this.mockDeviceTagMapper = this.mockRepository.Create<IDeviceTagMapper>();
this.mockTableClientFactory = this.mockRepository.Create<ITableClientFactory>();
this.mockDeviceTagTableClient = this.mockRepository.Create<TableClient>();
//this.mockDeviceTagMapper = this.mockRepository.Create<IDeviceTagMapper>();
//this.mockTableClientFactory = this.mockRepository.Create<ITableClientFactory>();
//this.mockDeviceTagTableClient = this.mockRepository.Create<TableClient>();
this.mockDeviceTagService = this.mockRepository.Create<IDeviceTagService>();
this.mockLogger = this.mockRepository.Create<ILogger<DeviceTagSettingsController>>();
}

private DeviceTagSettingsController CreateDeviceTagSettingsController()
{
return new DeviceTagSettingsController(
this.mockLogger.Object,
this.mockDeviceTagMapper.Object,
this.mockTableClientFactory.Object
);
//this.mockDeviceTagMapper.Object,
//this.mockTableClientFactory.Object,
this.mockDeviceTagService.Object
);
}

[Test]
Expand All @@ -62,54 +66,16 @@ public async Task Post_Should_Create_New_Entity()
Searchable = true
};

var mockResponse = this.mockRepository.Create<Response>();

this.mockDeviceTagMapper.Setup(c => c.UpdateTableEntity(
It.Is<TableEntity>(x => x.RowKey == tag.Name && x.PartitionKey == DeviceTagSettingsController.DefaultPartitionKey),
It.Is<DeviceTag>(x => x == tag)));

this.mockDeviceTagTableClient.Setup(c => c.AddEntityAsync(
It.Is<TableEntity>(x => x.PartitionKey == DeviceTagSettingsController.DefaultPartitionKey && x.RowKey == tag.Name),
It.IsAny<CancellationToken>()))
.ReturnsAsync(mockResponse.Object);

this.mockDeviceTagTableClient.Setup(c => c.Query<TableEntity>(
It.Is<string>(x => true),
It.IsAny<int?>(),
It.IsAny<IEnumerable<string>>(),
It.IsAny<CancellationToken>()))
.Returns(Pageable<TableEntity>.FromPages(new[] {
Page<TableEntity>.FromValues(new[]
{
new TableEntity(DeviceTagSettingsController.DefaultPartitionKey,tag.Name)
}, null, mockResponse.Object)
}));

this.mockDeviceTagTableClient.Setup(c => c.DeleteEntityAsync(
It.Is<string>(x => true),
It.IsAny<string>(),
It.IsAny<ETag>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(mockResponse.Object);

this.mockTableClientFactory.Setup(c => c.GetDeviceTagSettings())
.Returns(mockDeviceTagTableClient.Object);
this.mockDeviceTagService.Setup(c => c.UpdateTags(It.IsAny<List<DeviceTag>>()))
.Returns(Task.CompletedTask);

// Act
var result = await deviceTagSettingsController.Post(new List<DeviceTag>(new[] { tag }));

// Assert
Assert.IsNotNull(result);
Assert.IsAssignableFrom<OkResult>(result);

this.mockTableClientFactory.Verify(c => c.GetDeviceTagSettings());

this.mockDeviceTagMapper.VerifyAll();

this.mockDeviceTagTableClient.Verify(c => c.AddEntityAsync(
It.Is<TableEntity>(x => x.RowKey == tag.Name && x.PartitionKey == DeviceTagSettingsController.DefaultPartitionKey),
It.IsAny<CancellationToken>()), Times.Once());

this.mockDeviceTagService.VerifyAll();
this.mockRepository.VerifyAll();
}

Expand All @@ -118,30 +84,8 @@ public void Get_Should_Return_A_List()
{
// Arrange
var deviceTagSettingsController = this.CreateDeviceTagSettingsController();
var returnedIndex = 10;

var mockTable = this.mockRepository.Create<TableClient>();
var mockTableResponse = this.mockRepository.Create<Pageable<TableEntity>>();
var mockEnumerator = this.mockRepository.Create<IEnumerator<TableEntity>>();
mockEnumerator.Setup(x => x.Dispose()).Callback(() => { });
mockEnumerator.Setup(x => x.MoveNext()).Returns(() =>
{
return returnedIndex-- > 0;
});

mockEnumerator.Setup(x => x.Current)
.Returns(new TableEntity(DeviceTagSettingsController.DefaultPartitionKey, "test"));

mockTableResponse.Setup(x => x.GetEnumerator()).Returns(mockEnumerator.Object);

mockDeviceTagTableClient.Setup(c => c.Query<TableEntity>(It.IsAny<string>(), It.IsAny<int?>(), It.IsAny<IEnumerable<string>>(), It.IsAny<CancellationToken>()))
.Returns(mockTableResponse.Object);

mockTableClientFactory.Setup(c => c.GetDeviceTagSettings())
.Returns(mockDeviceTagTableClient.Object);

mockDeviceTagMapper.Setup(c => c.GetDeviceTag(It.IsAny<TableEntity>()))
.Returns((TableEntity entity) => new DeviceTag());
mockDeviceTagService.Setup(x => x.GetAllTags()).Returns(new DeviceTag[10].ToList());

// Act
var response = deviceTagSettingsController.Get();
Expand All @@ -157,6 +101,7 @@ public void Get_Should_Return_A_List()
var result = okResponse.Value as IEnumerable<DeviceTag>;
Assert.AreEqual(10, result.Count());

this.mockDeviceTagService.VerifyAll();
this.mockRepository.VerifyAll();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class DevicesControllerTests
private Mock<IDeviceProvisioningServiceManager> mockProvisioningServiceManager;
private Mock<ILogger<DevicesController>> mockLogger;
private Mock<IDeviceService> mockDeviceService;
private Mock<IDeviceTagService> mockDeviceTagService;
private Mock<IDeviceTwinMapper<DeviceListItem, DeviceDetails>> mockDeviceTwinMapper;
private Mock<ITableClientFactory> mockTableClientFactory;

Expand All @@ -41,6 +42,7 @@ public void SetUp()
this.mockProvisioningServiceManager = this.mockRepository.Create<IDeviceProvisioningServiceManager>();
this.mockLogger = this.mockRepository.Create<ILogger<DevicesController>>();
this.mockDeviceService = this.mockRepository.Create<IDeviceService>();
this.mockDeviceTagService = this.mockRepository.Create<IDeviceTagService>();
this.mockDeviceTwinMapper = this.mockRepository.Create<IDeviceTwinMapper<DeviceListItem, DeviceDetails>>();
this.mockTableClientFactory = this.mockRepository.Create<ITableClientFactory>();
}
Expand All @@ -50,6 +52,7 @@ private DevicesController CreateDevicesController()
return new DevicesController(
this.mockLogger.Object,
this.mockDeviceService.Object,
this.mockDeviceTagService.Object,
this.mockProvisioningServiceManager.Object,
this.mockDeviceTwinMapper.Object,
this.mockTableClientFactory.Object);
Expand Down Expand Up @@ -98,12 +101,15 @@ public async Task GetItem_StateUnderTest_ExpectedBehavior()
this.mockDeviceService.Setup(c => c.GetDeviceTwin(It.Is<string>(x => x == deviceID)))
.Returns<string>(x => Task.FromResult(new Twin(x)));

this.mockDeviceTwinMapper.Setup(c => c.CreateDeviceDetails(It.IsAny<Twin>()))
.Returns<Twin>(x => new DeviceDetails
this.mockDeviceTwinMapper.Setup(c => c.CreateDeviceDetails(It.IsAny<Twin>(), It.IsAny<IEnumerable<string>>()))
.Returns<Twin, IEnumerable<string>>((x, y) => new DeviceDetails
{
DeviceID = x.DeviceId
});

this.mockDeviceTagService.Setup(c => c.GetAllTagsNames())
.Returns(new List<string>());

// Act
var result = await devicesController.Get(deviceID);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public async Task GetEnrollmentCredentials_Should_Return_Enrollment_Credentials(
Assert.IsAssignableFrom<OkObjectResult>(response.Result);

var okObjectResult = (OkObjectResult)response.Result;
Assert.IsNotNull(okObjectResult);
Assert.IsNotNull(okObjectResult);
Assert.AreEqual(mockRegistrationCredentials, okObjectResult.Value);

this.mockRepository.VerifyAll();
Expand Down Expand Up @@ -344,12 +344,14 @@ public async Task DeleteDeviceAsync_StateUnderTest_ExpectedBehavior()
this.mockDeviceService.Setup(c => c.DeleteDevice(It.Is<string>(x => x == deviceId)))
.Returns(Task.CompletedTask);

#nullable enable
this.mockLogger.Setup(c => c.Log(
It.Is<LogLevel>(x => x == LogLevel.Information),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()));
#nullable disable

// Act
var result = await edgeDevicesController.DeleteDeviceAsync(deviceId);
Expand All @@ -374,12 +376,14 @@ public async Task ExecuteMethod_Should_Execute_C2D_Method(string methodName, str

string deviceId = Guid.NewGuid().ToString();

#nullable enable
this.mockLogger.Setup(c => c.Log(
It.Is<LogLevel>(x => x == LogLevel.Information),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()));
#nullable disable

this.mockDeviceService.Setup(c => c.ExecuteC2DMethod(
It.Is<string>(x => x == deviceId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class LoRaWANDevicesControllerTests
private Mock<IDeviceProvisioningServiceManager> mockProvisioningServiceManager;
private Mock<ILogger<LoRaWANDevicesController>> mockLogger;
private Mock<IDeviceService> mockDeviceService;
private Mock<IDeviceTagService> mockDeviceTagService;
private Mock<IDeviceTwinMapper<DeviceListItem, LoRaDeviceDetails>> mockDeviceTwinMapper;
private Mock<ITableClientFactory> mockTableClientFactory;
private Mock<ILoraDeviceMethodManager> mockLoraDeviceMethodManager;
Expand All @@ -46,10 +47,11 @@ public void SetUp()
this.mockProvisioningServiceManager = this.mockRepository.Create<IDeviceProvisioningServiceManager>();
this.mockLogger = this.mockRepository.Create<ILogger<LoRaWANDevicesController>>();
this.mockDeviceService = this.mockRepository.Create<IDeviceService>();
this.mockDeviceTagService = this.mockRepository.Create<IDeviceTagService>();
this.mockDeviceTwinMapper = this.mockRepository.Create<IDeviceTwinMapper<DeviceListItem, LoRaDeviceDetails>>();
this.mockTableClientFactory = this.mockRepository.Create<ITableClientFactory>();
this.mockLoraDeviceMethodManager = this.mockRepository.Create<ILoraDeviceMethodManager>();
this.mockDeviceModelCommandMapper = this.mockRepository.Create<IDeviceModelCommandMapper>();
this.mockDeviceModelCommandMapper = this.mockRepository.Create<IDeviceModelCommandMapper>();
this.mockCommandsTableClient = this.mockRepository.Create<TableClient>();

}
Expand All @@ -59,6 +61,7 @@ private LoRaWANDevicesController CreateLoRaWANDevicesController()
return new LoRaWANDevicesController(
this.mockLogger.Object,
this.mockDeviceService.Object,
this.mockDeviceTagService.Object,
this.mockDeviceTwinMapper.Object,
this.mockTableClientFactory.Object,
this.mockLoraDeviceMethodManager.Object,
Expand Down Expand Up @@ -105,12 +108,14 @@ public async Task ExecuteCommand_StateUnderTest_ExpectedBehavior()
It.Is<DeviceModelCommand>(x => x.Name == commandId)))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));

#nullable enable
this.mockLogger.Setup(c => c.Log(
It.Is<LogLevel>(x => x == LogLevel.Information),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()));
It.IsAny<Func<It.IsAnyType, Exception?, string>>()));
#nullable disable

// Act
var result = await loRaWANDevicesController.ExecuteCommand(deviceId, commandId);
Expand Down Expand Up @@ -161,12 +166,14 @@ public async Task ExecuteCommand_Failed_Should_Return_Http400()
It.Is<DeviceModelCommand>(x => x.Name == commandId)))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.InternalServerError));

#nullable enable
this.mockLogger.Setup(c => c.Log(
It.Is<LogLevel>(x => x == LogLevel.Error),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()));
#nullable disable

// Act
var result = await loRaWANDevicesController.ExecuteCommand(deviceId, commandId);
Expand Down Expand Up @@ -221,15 +228,18 @@ public async Task GetItem_StateUnderTest_ExpectedBehavior()
this.mockDeviceService.Setup(c => c.GetDeviceTwin(It.Is<string>(x => x == deviceID)))
.Returns<string>(x => Task.FromResult(new Twin(x)));

this.mockDeviceTwinMapper.Setup(c => c.CreateDeviceDetails(It.IsAny<Twin>()))
.Returns<Twin>(x => new LoRaDeviceDetails
this.mockDeviceTwinMapper.Setup(c => c.CreateDeviceDetails(It.IsAny<Twin>(), It.IsAny<IEnumerable<string>>()))
.Returns<Twin, IEnumerable<string>>((x, y) => new LoRaDeviceDetails
{
DeviceID = x.DeviceId,
AppEUI = Guid.NewGuid().ToString(),
AppKey = Guid.NewGuid().ToString(),
SensorDecoder = Guid.NewGuid().ToString(),
});

this.mockDeviceTagService.Setup(c => c.GetAllTagsNames())
.Returns(new List<string>());

// Act
var result = await devicesController.Get(deviceID);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Azure.Data.Tables;
using AzureIoTHub.Portal.Server.Mappers;
using AzureIoTHub.Portal.Shared.Models.v10.Device;
using AzureIoTHub.Portal.Shared.Models.V10.Device;
using Moq;
using NUnit.Framework;
using System;
Expand Down
Loading