Refactor to introduce nullable types and reduce compiler warnings (#801)
* Introduce nullable types to Core, Infrastructure and PublicApi projects * Refactor unit tests * Fixed failing tests * Introduce Parameter object for CatalogItem update method * Refactor CataloItemDetails param object * Refactor following PR comments
This commit is contained in:
committed by
GitHub
parent
aa6305eab1
commit
a72dd775ee
@@ -1,6 +1,4 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopWeb.FunctionalTests.Web;
|
||||
using Microsoft.eShopWeb.FunctionalTests.Web;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class GetByIdWithItemsAsync
|
||||
|
||||
//Act
|
||||
var spec = new OrderWithItemsByIdSpec(secondOrderId);
|
||||
var orderFromRepo = await _orderRepository.GetBySpecAsync(spec);
|
||||
var orderFromRepo = await _orderRepository.FirstOrDefaultAsync(spec);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(secondOrderId, orderFromRepo.Id);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.CatalogItemTests;
|
||||
|
||||
public class UpdateDetails
|
||||
{
|
||||
private CatalogItem _testItem;
|
||||
private int _validTypeId = 1;
|
||||
private int _validBrandId = 2;
|
||||
private string _validDescription = "test description";
|
||||
private string _validName = "test name";
|
||||
private decimal _validPrice = 1.23m;
|
||||
private string _validUri = "/123";
|
||||
|
||||
public UpdateDetails()
|
||||
{
|
||||
_testItem = new CatalogItem(_validTypeId, _validBrandId, _validDescription, _validName, _validPrice, _validUri);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsArgumentExceptionGivenEmptyName()
|
||||
{
|
||||
string newValue = "";
|
||||
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(newValue, _validDescription, _validPrice));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsArgumentExceptionGivenEmptyDescription()
|
||||
{
|
||||
string newValue = "";
|
||||
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, newValue, _validPrice));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsArgumentNullExceptionGivenNullName()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(null, _validDescription, _validPrice));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsArgumentNullExceptionGivenNullDescription()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(_validName, null, _validPrice));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(-1.23)]
|
||||
public void ThrowsArgumentExceptionGivenNonPositivePrice(decimal newPrice)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, _validDescription, newPrice));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions;
|
||||
|
||||
@@ -9,12 +6,22 @@ public class TestParent : IEquatable<TestParent>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; }
|
||||
|
||||
public IEnumerable<TestChild> Children { get; set; }
|
||||
public IEnumerable<TestChild>? Children { get; set; }
|
||||
|
||||
public bool Equals([AllowNull] TestParent other) =>
|
||||
other?.Id == Id && other?.Name == Name &&
|
||||
(other?.Children is null && Children is null ||
|
||||
(other?.Children?.Zip(Children)?.All(t => t.First?.Equals(t.Second) ?? false) ?? false));
|
||||
public bool Equals([AllowNull] TestParent other)
|
||||
{
|
||||
if (other?.Id == Id && other?.Name == Name)
|
||||
{
|
||||
if (Children is null)
|
||||
{
|
||||
return other?.Children is null;
|
||||
}
|
||||
|
||||
return other?.Children?.Zip(Children).All(t => t.First?.Equals(t.Second) ?? false) ?? false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,19 +12,20 @@ public class AddItemToBasket
|
||||
{
|
||||
private readonly string _buyerId = "Test buyerId";
|
||||
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
|
||||
private readonly Mock<IAppLogger<BasketService>> _mockLogger = new();
|
||||
|
||||
[Fact]
|
||||
public async Task InvokesBasketRepositoryGetBySpecAsyncOnce()
|
||||
{
|
||||
var basket = new Basket(_buyerId);
|
||||
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
|
||||
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
|
||||
_mockBasketRepo.Setup(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
|
||||
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
|
||||
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
|
||||
|
||||
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
|
||||
_mockBasketRepo.Verify(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -32,9 +33,9 @@ public class AddItemToBasket
|
||||
{
|
||||
var basket = new Basket(_buyerId);
|
||||
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
|
||||
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
|
||||
_mockBasketRepo.Setup(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
|
||||
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
|
||||
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ public class DeleteBasket
|
||||
{
|
||||
private readonly string _buyerId = "Test buyerId";
|
||||
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
|
||||
private readonly Mock<IAppLogger<BasketService>> _mockLogger = new();
|
||||
|
||||
[Fact]
|
||||
public async Task ShouldInvokeBasketRepositoryDeleteAsyncOnce()
|
||||
@@ -20,7 +21,7 @@ public class DeleteBasket
|
||||
basket.AddItem(2, It.IsAny<decimal>(), It.IsAny<int>());
|
||||
_mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny<int>(), default))
|
||||
.ReturnsAsync(basket);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
|
||||
await basketService.DeleteBasketAsync(It.IsAny<int>());
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Exceptions;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Services;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests;
|
||||
|
||||
public class SetQuantities
|
||||
{
|
||||
private readonly int _invalidId = -1;
|
||||
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsGivenInvalidBasketId()
|
||||
{
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
|
||||
await Assert.ThrowsAsync<BasketNotFoundException>(async () =>
|
||||
await basketService.SetQuantities(_invalidId, new System.Collections.Generic.Dictionary<string, int>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsGivenNullQuantities()
|
||||
{
|
||||
var basketService = new BasketService(null, null);
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
|
||||
await basketService.SetQuantities(123, null));
|
||||
}
|
||||
}
|
||||
@@ -16,34 +16,19 @@ public class TransferBasket
|
||||
private readonly string _nonexistentUserBasketBuyerId = "newuser@microsoft.com";
|
||||
private readonly string _existentUserBasketBuyerId = "testuser@microsoft.com";
|
||||
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsGivenNullAnonymousId()
|
||||
{
|
||||
var basketService = new BasketService(null, null);
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync(null, "steve"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ThrowsGivenNullUserId()
|
||||
{
|
||||
var basketService = new BasketService(null, null);
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync("abcdefg", null));
|
||||
}
|
||||
private readonly Mock<IAppLogger<BasketService>> _mockLogger = new();
|
||||
|
||||
[Fact]
|
||||
public async Task InvokesBasketRepositoryFirstOrDefaultAsyncOnceIfAnonymousBasketNotExists()
|
||||
{
|
||||
var anonymousBasket = null as Basket;
|
||||
var userBasket = new Basket(_existentUserBasketBuyerId);
|
||||
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
_mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
.ReturnsAsync(anonymousBasket)
|
||||
.ReturnsAsync(userBasket);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
|
||||
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
|
||||
_mockBasketRepo.Verify(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -55,10 +40,10 @@ public class TransferBasket
|
||||
var userBasket = new Basket(_existentUserBasketBuyerId);
|
||||
userBasket.AddItem(1, 10, 4);
|
||||
userBasket.AddItem(2, 99, 3);
|
||||
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
_mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
.ReturnsAsync(anonymousBasket)
|
||||
.ReturnsAsync(userBasket);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
|
||||
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
|
||||
Assert.Equal(3, userBasket.Items.Count);
|
||||
@@ -72,10 +57,10 @@ public class TransferBasket
|
||||
{
|
||||
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
|
||||
var userBasket = new Basket(_existentUserBasketBuyerId);
|
||||
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
_mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
.ReturnsAsync(anonymousBasket)
|
||||
.ReturnsAsync(userBasket);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
|
||||
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
|
||||
_mockBasketRepo.Verify(x => x.DeleteAsync(anonymousBasket, default), Times.Once);
|
||||
@@ -86,10 +71,10 @@ public class TransferBasket
|
||||
{
|
||||
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
|
||||
var userBasket = null as Basket;
|
||||
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
_mockBasketRepo.SetupSequence(x => x.FirstOrDefaultAsync(It.IsAny<BasketWithItemsSpecification>(), default))
|
||||
.ReturnsAsync(anonymousBasket)
|
||||
.ReturnsAsync(userBasket);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, null);
|
||||
var basketService = new BasketService(_mockBasketRepo.Object, _mockLogger.Object);
|
||||
await basketService.TransferBasketAsync(_existentAnonymousBasketBuyerId, _nonexistentUserBasketBuyerId);
|
||||
_mockBasketRepo.Verify(x => x.AddAsync(It.Is<Basket>(x => x.BuyerId == _nonexistentUserBasketBuyerId), default), Times.Once);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
|
||||
@@ -12,9 +10,7 @@ public class CatalogFilterPaginatedSpecification
|
||||
{
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, null, null);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestCollection());
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(4, result.ToList().Count);
|
||||
@@ -25,9 +21,7 @@ public class CatalogFilterPaginatedSpecification
|
||||
{
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, 1, 1);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestCollection()).ToList();
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(2, result.ToList().Count);
|
||||
|
||||
@@ -19,9 +19,7 @@ public class CatalogFilterSpecification
|
||||
{
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterSpecification(brandId, typeId);
|
||||
|
||||
var result = GetTestItemCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestItemCollection()).ToList();
|
||||
|
||||
Assert.Equal(expectedCount, result.Count());
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ public class CatalogItemsSpecification
|
||||
var catalogItemIds = new int[] { 1 };
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestCollection()).ToList();
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Single(result.ToList());
|
||||
@@ -28,9 +26,7 @@ public class CatalogItemsSpecification
|
||||
var catalogItemIds = new int[] { 1, 3 };
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestCollection()).ToList();
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(2, result.ToList().Count);
|
||||
|
||||
@@ -15,14 +15,12 @@ public class CustomerOrdersWithItemsSpecification
|
||||
{
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.FirstOrDefault(spec.WhereExpressions.FirstOrDefault().Filter);
|
||||
var result = spec.Evaluate(GetTestCollection()).FirstOrDefault();
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.NotNull(result.OrderItems);
|
||||
Assert.Equal(1, result.OrderItems.Count);
|
||||
Assert.NotNull(result.OrderItems.FirstOrDefault().ItemOrdered);
|
||||
Assert.NotNull(result.OrderItems.FirstOrDefault()?.ItemOrdered);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -30,15 +28,12 @@ public class CustomerOrdersWithItemsSpecification
|
||||
{
|
||||
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
|
||||
|
||||
var result = GetTestCollection()
|
||||
.AsQueryable()
|
||||
.Where(spec.WhereExpressions.FirstOrDefault().Filter)
|
||||
.ToList();
|
||||
var result = spec.Evaluate(GetTestCollection()).ToList();
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(2, result.Count);
|
||||
Assert.Equal(1, result[0].OrderItems.Count);
|
||||
Assert.NotNull(result[0].OrderItems.FirstOrDefault().ItemOrdered);
|
||||
Assert.NotNull(result[0].OrderItems.FirstOrDefault()?.ItemOrdered);
|
||||
Assert.Equal(2, result[1].OrderItems.Count);
|
||||
Assert.NotNull(result[1].OrderItems.ToList()[0].ItemOrdered);
|
||||
Assert.NotNull(result[1].OrderItems.ToList()[1].ItemOrdered);
|
||||
|
||||
@@ -22,7 +22,7 @@ public class GetOrderDetails
|
||||
Order order = new Order("buyerId", address, new List<OrderItem> { item });
|
||||
|
||||
_mockOrderRepository = new Mock<IReadRepository<Order>>();
|
||||
_mockOrderRepository.Setup(x => x.GetBySpecAsync(It.IsAny<OrderWithItemsByIdSpec>(), default))
|
||||
_mockOrderRepository.Setup(x => x.FirstOrDefaultAsync(It.IsAny<OrderWithItemsByIdSpec>(), default))
|
||||
.ReturnsAsync(order);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user