Skip to content

Commit

Permalink
Fix loading device model properties on a device #1249
Browse files Browse the repository at this point in the history
  • Loading branch information
hocinehacherouf committed Sep 16, 2022
1 parent 68ce3a6 commit 23f68ce
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,31 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Services
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Azure;
using Azure.Data.Tables;
using AzureIoTHub.Portal.Domain;
using AzureIoTHub.Portal.Domain.Entities;
using AzureIoTHub.Portal.Domain.Exceptions;
using AzureIoTHub.Portal.Domain.Repositories;
using AzureIoTHub.Portal.Server.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;

[TestFixture]
public class DeviceModelPropertiesServiceTests
{
private MockRepository mockRepository;
private Mock<ITableClientFactory> mockTableClientFactory;
private Mock<TableClient> mockDeviceTemplatesTableClient;
private Mock<IDeviceModelPropertiesRepository> mockDeviceModelPropertiesRepository;
private Mock<IDeviceModelRepository> mockDeviceModelRepository;
private Mock<IUnitOfWork> mockUnitOfWork;
private Mock<ILogger<DeviceModelPropertiesService>> mockLogger;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);
this.mockTableClientFactory = this.mockRepository.Create<ITableClientFactory>();
this.mockDeviceTemplatesTableClient = this.mockRepository.Create<TableClient>();
this.mockDeviceModelPropertiesRepository = this.mockRepository.Create<IDeviceModelPropertiesRepository>();
this.mockDeviceModelRepository = this.mockRepository.Create<IDeviceModelRepository>();
this.mockUnitOfWork = this.mockRepository.Create<IUnitOfWork>();
this.mockLogger = this.mockRepository.Create<ILogger<DeviceModelPropertiesService>>();
}

[Test]
Expand All @@ -49,18 +40,18 @@ public async Task GetPropertiesStateUnderTestExpectedBehavior()
var instance = CreateDeviceModelPropertiesService();
var entity = SetupMockEntity();

_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.GetModelProperties(entity.RowKey))
_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.GetModelProperties(entity.Id))
.ReturnsAsync(new[]
{
new DeviceModelProperty
{
Id = Guid.NewGuid().ToString(),
ModelId = entity.RowKey
ModelId = entity.Id
}
});

// Act
var result = await instance.GetModelProperties(entity.RowKey);
var result = await instance.GetModelProperties(entity.Id);

// Assert
Assert.NotNull(result);
Expand All @@ -80,6 +71,17 @@ public void WhenDeviceModelNotExistsGetPropertiesShouldReturnHttp404()
_ = Assert.ThrowsAsync<ResourceNotFoundException>(async () => await instance.GetModelProperties(Guid.NewGuid().ToString()));
}

[Test]
public void SavePropertiesForModelShouldThrowResourceNotFoundExceptionWhenDeviceModelNotExists()
{
// Arrange
var instance = CreateDeviceModelPropertiesService();
SetupNotFoundEntity();

// Act
_ = Assert.ThrowsAsync<ResourceNotFoundException>(async () => await instance.SavePropertiesForModel(Guid.NewGuid().ToString(), new List<DeviceModelProperty>()));
}

[Test]
public async Task SetPropertiesStateUnderTestExpectedBehavior()
{
Expand All @@ -96,14 +98,14 @@ public async Task SetPropertiesStateUnderTestExpectedBehavior()
}
};

_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.SavePropertiesForModel(entity.RowKey, It.IsAny<IEnumerable<DeviceModelProperty>>()))
_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.SavePropertiesForModel(entity.Id, It.IsAny<IEnumerable<DeviceModelProperty>>()))
.Returns(Task.CompletedTask);

_ = this.mockUnitOfWork.Setup(c => c.SaveAsync())
.Returns(Task.CompletedTask);

// Act
await instance.SavePropertiesForModel(entity.RowKey, properties);
await instance.SavePropertiesForModel(entity.Id, properties);

// Assert
this.mockRepository.VerifyAll();
Expand All @@ -117,76 +119,42 @@ public void WhenExceptionOccuresSavePropertiesForModelShouldThrowInternalServerE

var entity = SetupMockEntity();

_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.SavePropertiesForModel(entity.RowKey, It.IsAny<IEnumerable<DeviceModelProperty>>()))
_ = this.mockDeviceModelPropertiesRepository.Setup(c => c.SavePropertiesForModel(entity.Id, It.IsAny<IEnumerable<DeviceModelProperty>>()))
.Returns(Task.CompletedTask);

_ = this.mockUnitOfWork.Setup(c => c.SaveAsync())
.Throws<DbUpdateException>();

// Act
_ = Assert.ThrowsAsync<InternalServerErrorException>(async () => await instance.SavePropertiesForModel(entity.RowKey, Array.Empty<DeviceModelProperty>()));
_ = Assert.ThrowsAsync<InternalServerErrorException>(async () => await instance.SavePropertiesForModel(entity.Id, Array.Empty<DeviceModelProperty>()));
}

[Test]
public void WhenExceptionOccuresDuringCheckingModelExistanceShouldThrowInternalServerErrorException()
private DeviceModel SetupMockEntity()
{
// Arrange
var instance = CreateDeviceModelPropertiesService();

_ = this.mockTableClientFactory.Setup(c => c.GetDeviceTemplates())
.Returns(this.mockDeviceTemplatesTableClient.Object);

_ = this.mockDeviceTemplatesTableClient.Setup(c => c.GetEntityAsync<TableEntity>(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IEnumerable<string>>(), It.IsAny<CancellationToken>()))
.Throws(new RequestFailedException("failed"));

_ = this.mockLogger.Setup(c => c.Log(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception?>(), It.IsAny<Func<It.IsAnyType, Exception?, string>>()));

// Act
_ = Assert.ThrowsAsync<InternalServerErrorException>(async () => await instance.GetModelProperties(Guid.NewGuid().ToString()));
_ = Assert.ThrowsAsync<InternalServerErrorException>(async () => await instance.SavePropertiesForModel(Guid.NewGuid().ToString(), Array.Empty<DeviceModelProperty>()));

this.mockRepository.VerifyAll();
}

private TableEntity SetupMockEntity()
{
var mockResponse = this.mockRepository.Create<Response<TableEntity>>();
var modelId = Guid.NewGuid().ToString();
var entity = new TableEntity("0", modelId);

_ = this.mockDeviceTemplatesTableClient.Setup(c => c.GetEntityAsync<TableEntity>(
It.Is<string>(p => p == "0"),
It.Is<string>(k => k == modelId),
It.IsAny<IEnumerable<string>>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(mockResponse.Object);
var deviceModelEntity = new DeviceModel
{
Id = modelId
};

_ = this.mockTableClientFactory.Setup(c => c.GetDeviceTemplates())
.Returns(this.mockDeviceTemplatesTableClient.Object);
_ = this.mockDeviceModelRepository.Setup(repository => repository.GetByIdAsync(modelId))
.ReturnsAsync(deviceModelEntity);

return entity;
return deviceModelEntity;
}

private void SetupNotFoundEntity()
{
_ = this.mockDeviceTemplatesTableClient.Setup(c => c.GetEntityAsync<TableEntity>(
It.Is<string>(p => p == "0"),
It.IsAny<string>(),
It.IsAny<IEnumerable<string>>(),
It.IsAny<CancellationToken>()))
.Throws(new RequestFailedException(StatusCodes.Status404NotFound, "Not Found"));

_ = this.mockTableClientFactory.Setup(c => c.GetDeviceTemplates())
.Returns(this.mockDeviceTemplatesTableClient.Object);
_ = this.mockDeviceModelRepository.Setup(repository => repository.GetByIdAsync(It.IsAny<string>()))
.ReturnsAsync((DeviceModel)null);
}

private DeviceModelPropertiesService CreateDeviceModelPropertiesService()
{
return new DeviceModelPropertiesService(
this.mockLogger.Object,
this.mockUnitOfWork.Object,
this.mockTableClientFactory.Object,
this.mockDeviceModelPropertiesRepository.Object);
this.mockDeviceModelPropertiesRepository.Object,
this.mockDeviceModelRepository.Object);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ namespace AzureIoTHub.Portal.Server.Services
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure;
using Azure.Data.Tables;
using AzureIoTHub.Portal.Domain;
using Domain;
using AzureIoTHub.Portal.Domain.Entities;
using AzureIoTHub.Portal.Domain.Exceptions;
using AzureIoTHub.Portal.Domain.Repositories;
using Microsoft.AspNetCore.Http;
using Domain.Exceptions;
using Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

public class DeviceModelPropertiesService : IDeviceModelPropertiesService
{
Expand All @@ -22,28 +18,18 @@ public class DeviceModelPropertiesService : IDeviceModelPropertiesService
/// </summary>
private readonly IUnitOfWork unitOfWork;

/// <summary>
/// The table client factory.
/// </summary>
private readonly ITableClientFactory tableClientFactory;

/// <summary>
/// The device model properties repository.
/// </summary>
private readonly IDeviceModelPropertiesRepository deviceModelPropertiesRepository;

/// <summary>
/// The logger.
/// </summary>
private readonly ILogger log;
private readonly IDeviceModelRepository deviceModelRepository;

public DeviceModelPropertiesService(
ILogger<DeviceModelPropertiesService> log, IUnitOfWork unitOfWork, ITableClientFactory tableClientFactory, IDeviceModelPropertiesRepository deviceModelPropertiesRepository)
public DeviceModelPropertiesService(IUnitOfWork unitOfWork, IDeviceModelPropertiesRepository deviceModelPropertiesRepository, IDeviceModelRepository deviceModelRepository)
{
this.log = log;
this.unitOfWork = unitOfWork;
this.tableClientFactory = tableClientFactory;
this.deviceModelPropertiesRepository = deviceModelPropertiesRepository;
this.deviceModelRepository = deviceModelRepository;
}

public async Task<IEnumerable<DeviceModelProperty>> GetModelProperties(string modelId)
Expand All @@ -69,27 +55,13 @@ public async Task SavePropertiesForModel(string modelId, IEnumerable<DeviceModel
}
}

private async Task<bool> AssertModelExists(string id)
private async Task<bool> AssertModelExists(string deviceModelId)
{
try
{
_ = await this.tableClientFactory
.GetDeviceTemplates()
.GetEntityAsync<TableEntity>("0", id);

return true;
}
catch (RequestFailedException e)
{
if (e.Status == StatusCodes.Status404NotFound)
{
throw new ResourceNotFoundException($"The model {id} doesn't exist.");
}

this.log.LogError(e.Message, e);
var deviceModelEntity = await this.deviceModelRepository.GetByIdAsync(deviceModelId);

throw new InternalServerErrorException($"Unable to check if device model with id {id} exist", e);
}
return deviceModelEntity == null
? throw new ResourceNotFoundException($"The device model {deviceModelId} doesn't exist")
: true;
}
}
}

0 comments on commit 23f68ce

Please sign in to comment.