From a0ba412bc8cc5e3350cd201c61ec9890fb09e539 Mon Sep 17 00:00:00 2001 From: Eric Fleming Date: Sat, 20 Jun 2020 21:35:05 -0400 Subject: [PATCH] Adding additional unit tests (#406) * Creating new test class for RemoveEmptyItems * Adding tests for AddItemToBasket in BasketService * Removing unused GetBasketItemCountAsync * Adding tests for BasketWithItemsSpecification * Adding CustomerORdersWithItemsSpecification tests * Adding CatalogFilterPaginatedSpecifciation tests * Adding CatalogItemsSpecification tests --- .../Entities/OrderAggregate/Order.cs | 2 +- .../Entities/OrderAggregate/OrderItem.cs | 1 - .../Interfaces/IBasketService.cs | 1 - src/ApplicationCore/Services/BasketService.cs | 16 ----- .../BasketWithItemsSpecification.cs | 1 + .../Entities/BasketTests/BasketAddItem.cs | 10 --- .../BasketTests/BasketRemoveEmptyItems.cs | 22 +++++++ .../BasketServiceTests/AddItemToBasket.cs | 48 ++++++++++++++ .../BasketWithItemsSpecification.cs | 33 ++++++++-- .../CatalogFilterPaginatedSpecification.cs | 48 ++++++++++++++ ...ilter.cs => CatalogFilterSpecification.cs} | 7 +- .../CatalogItemsSpecification.cs | 55 ++++++++++++++++ .../CustomerOrdersWithItemsSpecification.cs | 66 +++++++++++++++++++ 13 files changed, 272 insertions(+), 38 deletions(-) create mode 100644 tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketRemoveEmptyItems.cs create mode 100644 tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs create mode 100644 tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs rename tests/UnitTests/ApplicationCore/Specifications/{CatalogFilterSpecificationFilter.cs => CatalogFilterSpecification.cs} (83%) create mode 100644 tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs create mode 100644 tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs diff --git a/src/ApplicationCore/Entities/OrderAggregate/Order.cs b/src/ApplicationCore/Entities/OrderAggregate/Order.cs index f05f073..c869041 100644 --- a/src/ApplicationCore/Entities/OrderAggregate/Order.cs +++ b/src/ApplicationCore/Entities/OrderAggregate/Order.cs @@ -22,8 +22,8 @@ namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate ShipToAddress = shipToAddress; _orderItems = items; } - public string BuyerId { get; private set; } + public string BuyerId { get; private set; } public DateTimeOffset OrderDate { get; private set; } = DateTimeOffset.Now; public Address ShipToAddress { get; private set; } diff --git a/src/ApplicationCore/Entities/OrderAggregate/OrderItem.cs b/src/ApplicationCore/Entities/OrderAggregate/OrderItem.cs index 4c60432..b115df8 100644 --- a/src/ApplicationCore/Entities/OrderAggregate/OrderItem.cs +++ b/src/ApplicationCore/Entities/OrderAggregate/OrderItem.cs @@ -1,6 +1,5 @@ namespace Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate { - public class OrderItem : BaseEntity { public CatalogItemOrdered ItemOrdered { get; private set; } diff --git a/src/ApplicationCore/Interfaces/IBasketService.cs b/src/ApplicationCore/Interfaces/IBasketService.cs index 9b7b2b1..38412be 100644 --- a/src/ApplicationCore/Interfaces/IBasketService.cs +++ b/src/ApplicationCore/Interfaces/IBasketService.cs @@ -5,7 +5,6 @@ namespace Microsoft.eShopWeb.ApplicationCore.Interfaces { public interface IBasketService { - Task GetBasketItemCountAsync(string userName); Task TransferBasketAsync(string anonymousId, string userName); Task AddItemToBasket(int basketId, int catalogItemId, decimal price, int quantity = 1); Task SetQuantities(int basketId, Dictionary quantities); diff --git a/src/ApplicationCore/Services/BasketService.cs b/src/ApplicationCore/Services/BasketService.cs index 8d5d62a..a4dcc51 100644 --- a/src/ApplicationCore/Services/BasketService.cs +++ b/src/ApplicationCore/Services/BasketService.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.eShopWeb.ApplicationCore.Specifications; -using System.Linq; using Ardalis.GuardClauses; using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; @@ -37,21 +36,6 @@ namespace Microsoft.eShopWeb.ApplicationCore.Services await _basketRepository.DeleteAsync(basket); } - public async Task GetBasketItemCountAsync(string userName) - { - Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basketSpec = new BasketWithItemsSpecification(userName); - var basket = (await _basketRepository.FirstOrDefaultAsync(basketSpec)); - if (basket == null) - { - _logger.LogInformation($"No basket found for {userName}"); - return 0; - } - int count = basket.Items.Sum(i => i.Quantity); - _logger.LogInformation($"Basket for {userName} has {count} items."); - return count; - } - public async Task SetQuantities(int basketId, Dictionary quantities) { Guard.Against.Null(quantities, nameof(quantities)); diff --git a/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs b/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs index f7bc0d4..68eeb31 100644 --- a/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs +++ b/src/ApplicationCore/Specifications/BasketWithItemsSpecification.cs @@ -9,6 +9,7 @@ namespace Microsoft.eShopWeb.ApplicationCore.Specifications { AddInclude(b => b.Items); } + public BasketWithItemsSpecification(string buyerId) : base(b => b.BuyerId == buyerId) { AddInclude(b => b.Items); diff --git a/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketAddItem.cs b/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketAddItem.cs index 4b7aaff..cf7cc98 100644 --- a/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketAddItem.cs +++ b/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketAddItem.cs @@ -56,16 +56,6 @@ namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests Assert.Equal(1, firstItem.Quantity); } - [Fact] - public void RemoveEmptyItems() - { - var basket = new Basket(_buyerId); - basket.AddItem(_testCatalogItemId, _testUnitPrice, 0); - basket.RemoveEmptyItems(); - - Assert.Equal(0, basket.Items.Count); - } - [Fact] public void CantAddItemWithNegativeQuantity() { diff --git a/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketRemoveEmptyItems.cs b/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketRemoveEmptyItems.cs new file mode 100644 index 0000000..0ce6320 --- /dev/null +++ b/tests/UnitTests/ApplicationCore/Entities/BasketTests/BasketRemoveEmptyItems.cs @@ -0,0 +1,22 @@ +using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; +using Xunit; + +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests +{ + public class BasketRemoveEmptyItems + { + private readonly int _testCatalogItemId = 123; + private readonly decimal _testUnitPrice = 1.23m; + private readonly string _buyerId = "Test buyerId"; + + [Fact] + public void RemovesEmptyBasketItems() + { + var basket = new Basket(_buyerId); + basket.AddItem(_testCatalogItemId, _testUnitPrice, 0); + basket.RemoveEmptyItems(); + + Assert.Equal(0, basket.Items.Count); + } + } +} diff --git a/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs new file mode 100644 index 0000000..f0921c0 --- /dev/null +++ b/tests/UnitTests/ApplicationCore/Services/BasketServiceTests/AddItemToBasket.cs @@ -0,0 +1,48 @@ +using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; +using Microsoft.eShopWeb.ApplicationCore.Interfaces; +using Microsoft.eShopWeb.ApplicationCore.Services; +using Moq; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests +{ + public class AddItemToBasket + { + private readonly string _buyerId = "Test buyerId"; + private readonly Mock> _mockBasketRepo; + + public AddItemToBasket() + { + _mockBasketRepo = new Mock>(); + } + + [Fact] + public async Task InvokesBasketRepositoryGetByIdAsyncOnce() + { + var basket = new Basket(_buyerId); + basket.AddItem(1, It.IsAny(), It.IsAny()); + _mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny())).ReturnsAsync(basket); + + var basketService = new BasketService(_mockBasketRepo.Object, null); + + await basketService.AddItemToBasket(basket.Id, 1, 1.50m); + + _mockBasketRepo.Verify(x => x.GetByIdAsync(It.IsAny()), Times.Once); + } + + [Fact] + public async Task InvokesBasketRepositoryUpdateAsyncOnce() + { + var basket = new Basket(_buyerId); + basket.AddItem(1, It.IsAny(), It.IsAny()); + _mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny())).ReturnsAsync(basket); + + var basketService = new BasketService(_mockBasketRepo.Object, null); + + await basketService.AddItemToBasket(basket.Id, 1, 1.50m); + + _mockBasketRepo.Verify(x => x.UpdateAsync(basket), Times.Once); + } + } +} diff --git a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs index 8657abc..401fce1 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/BasketWithItemsSpecification.cs @@ -13,7 +13,7 @@ namespace Microsoft.eShopWeb.UnitTests private readonly string _buyerId = "Test buyerId"; [Fact] - public void MatchesBasketWithGivenId() + public void MatchesBasketWithGivenBasketId() { var spec = new BasketWithItemsSpecification(_testBasketId); @@ -23,14 +23,37 @@ namespace Microsoft.eShopWeb.UnitTests Assert.NotNull(result); Assert.Equal(_testBasketId, result.Id); - } [Fact] - public void MatchesNoBasketsIfIdNotPresent() + public void MatchesNoBasketsIfBasketIdNotPresent() { - int badId = -1; - var spec = new BasketWithItemsSpecification(badId); + int badBasketId = -1; + var spec = new BasketWithItemsSpecification(badBasketId); + + Assert.False(GetTestBasketCollection() + .AsQueryable() + .Any(spec.Criterias.FirstOrDefault())); + } + + [Fact] + public void MatchesBasketWithGivenBuyerId() + { + var spec = new BasketWithItemsSpecification(_buyerId); + + var result = GetTestBasketCollection() + .AsQueryable() + .FirstOrDefault(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.Equal(_buyerId, result.BuyerId); + } + + [Fact] + public void MatchesNoBasketsIfBuyerIdNotPresent() + { + string badBuyerId = "badBuyerId"; + var spec = new BasketWithItemsSpecification(badBuyerId); Assert.False(GetTestBasketCollection() .AsQueryable() diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs new file mode 100644 index 0000000..6f0d66a --- /dev/null +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs @@ -0,0 +1,48 @@ +using Microsoft.eShopWeb.ApplicationCore.Entities; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications +{ + public class CatalogFilterPaginatedSpecification + { + [Fact] + public void ReturnsAllCatalogItems() + { + var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, null, null); + + var result = GetTestCollection() + .AsQueryable() + .Where(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.Equal(4, result.ToList().Count); + } + + [Fact] + public void Returns2CatalogItemsWithSameBrandAndTypeId() + { + var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, 1, 1); + + var result = GetTestCollection() + .AsQueryable() + .Where(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.Equal(2, result.ToList().Count); + } + + private List GetTestCollection() + { + var catalogItemList = new List(); + + catalogItemList.Add(new CatalogItem(1, 1, "Item 1", "Item 1", 1.00m, "TestUri1")); + catalogItemList.Add(new CatalogItem(1, 1, "Item 1.5", "Item 1.5", 1.50m, "TestUri1")); + catalogItemList.Add(new CatalogItem(2, 2, "Item 2", "Item 2", 2.00m, "TestUri2")); + catalogItemList.Add(new CatalogItem(3, 3, "Item 3", "Item 3", 3.00m, "TestUri3")); + + return catalogItemList; + } + } +} diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecificationFilter.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs similarity index 83% rename from tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecificationFilter.cs rename to tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs index 0ceb480..681e78b 100644 --- a/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecificationFilter.cs +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogFilterSpecification.cs @@ -1,12 +1,11 @@ -using Microsoft.eShopWeb.ApplicationCore.Specifications; -using Microsoft.eShopWeb.ApplicationCore.Entities; +using Microsoft.eShopWeb.ApplicationCore.Entities; using System.Collections.Generic; using System.Linq; using Xunit; namespace Microsoft.eShopWeb.UnitTests { - public class CatalogFilterSpecificationFilter + public class CatalogFilterSpecification { [Theory] [InlineData(null, null, 5)] @@ -18,7 +17,7 @@ namespace Microsoft.eShopWeb.UnitTests [InlineData(2, 3, 0)] public void MatchesExpectedNumberOfItems(int? brandId, int? typeId, int expectedCount) { - var spec = new CatalogFilterSpecification(brandId, typeId); + var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterSpecification(brandId, typeId); var result = GetTestItemCollection() .AsQueryable() diff --git a/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs new file mode 100644 index 0000000..2f9f11d --- /dev/null +++ b/tests/UnitTests/ApplicationCore/Specifications/CatalogItemsSpecification.cs @@ -0,0 +1,55 @@ +using Microsoft.eShopWeb.ApplicationCore.Entities; +using Moq; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications +{ + public class CatalogItemsSpecification + { + [Fact] + public void MatchesSpecificCatalogItem() + { + var catalogItemIds = new int[] { 1 }; + var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds); + + var result = GetTestCollection() + .AsQueryable() + .Where(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.Single(result.ToList()); + } + + [Fact] + public void MatchesAllCatalogItems() + { + var catalogItemIds = new int[] { 1, 3 }; + var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds); + + var result = GetTestCollection() + .AsQueryable() + .Where(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.Equal(2, result.ToList().Count); + } + + private List GetTestCollection() + { + var catalogItems = new List(); + + var mockCatalogItem1 = new Mock(1, 1, "Item 1 description", "Item 1", 1.5m, "Item1Uri"); + mockCatalogItem1.SetupGet(x => x.Id).Returns(1); + + var mockCatalogItem3 = new Mock(3, 3, "Item 3 description", "Item 3", 3.5m, "Item3Uri"); + mockCatalogItem3.SetupGet(x => x.Id).Returns(3); + + catalogItems.Add(mockCatalogItem1.Object); + catalogItems.Add(mockCatalogItem3.Object); + + return catalogItems; + } + } +} diff --git a/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs b/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs new file mode 100644 index 0000000..32ffe9e --- /dev/null +++ b/tests/UnitTests/ApplicationCore/Specifications/CustomerOrdersWithItemsSpecification.cs @@ -0,0 +1,66 @@ +using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications +{ + public class CustomerOrdersWithItemsSpecification + { + private readonly string _buyerId = "TestBuyerId"; + private Address _shipToAddress = new Address("Street", "City", "OH", "US", "11111"); + + [Fact] + public void ReturnsOrderWithOrderedItem() + { + var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId); + + var result = GetTestCollection() + .AsQueryable() + .FirstOrDefault(spec.Criterias.FirstOrDefault()); + + Assert.NotNull(result); + Assert.NotNull(result.OrderItems); + Assert.Equal(1, result.OrderItems.Count); + Assert.NotNull(result.OrderItems.FirstOrDefault().ItemOrdered); + } + + [Fact] + public void ReturnsAllOrderWithAllOrderedItem() + { + var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId); + + var result = GetTestCollection() + .AsQueryable() + .Where(spec.Criterias.FirstOrDefault()) + .ToList(); + + Assert.NotNull(result); + Assert.Equal(2, result.Count); + Assert.Equal(1, result[0].OrderItems.Count); + 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); + } + + public List GetTestCollection() + { + var ordersList = new List(); + + ordersList.Add(new Order(_buyerId, _shipToAddress, + new List + { + new OrderItem(new CatalogItemOrdered(1, "Product1", "testurl"), 10.50m, 1) + })); + ordersList.Add(new Order(_buyerId, _shipToAddress, + new List + { + new OrderItem(new CatalogItemOrdered(2, "Product2", "testurl"), 15.50m, 2), + new OrderItem(new CatalogItemOrdered(2, "Product3", "testurl"), 20.50m, 1) + })); + + return ordersList; + } + } +}