using LCU.API.Internal.Operations.IncentiveApi.Services; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using Moq; using NUnit.Framework; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.API.Internal.Operations.IncentiveApi.Exceptions; namespace Application.UnitTests.Services { public class CommissionServiceTest { private CommissionService _service; private Mock _mockCommissionRepository; private Mock _mockUnitOfWork; [SetUp] public void Setup() { _mockCommissionRepository = new Mock(); _mockUnitOfWork = new Mock(); _service = new CommissionService(_mockCommissionRepository.Object, _mockUnitOfWork.Object); } [Test] public async Task GetCommissionsAsync_ReturnsCommissionsFromRepo() { var commissions = new List { new Commission { Id = 1, Product = Product.ATMCard, RatePerProduct = 5, Role = Role.Teller }, new Commission { Id = 2, Product = Product.CheckCard, RatePerProduct = 10, Role = Role.ABM } }.AsReadOnly(); _mockCommissionRepository.Setup(repo => repo.GetCommissionsAsync()).ReturnsAsync(commissions); var result = await _service.GetCommissionsAsync(); Assert.NotNull(result); Assert.AreEqual(2, result.Count); Assert.AreEqual(commissions[0].Id, result.ElementAt(0).Id); Assert.AreEqual(commissions[0].Product, result.ElementAt(0).Product); Assert.AreEqual(commissions[0].RatePerProduct, result.ElementAt(0).RatePerProduct); Assert.AreEqual(commissions[0].Role, result.ElementAt(0).Role); Assert.AreEqual(commissions[1].Id, result.ElementAt(1).Id); Assert.AreEqual(commissions[1].Product, result.ElementAt(1).Product); Assert.AreEqual(commissions[1].RatePerProduct, result.ElementAt(1).RatePerProduct); Assert.AreEqual(commissions[1].Role, result.ElementAt(1).Role); } [Test] public async Task SaveCommissionsAsync_NewCommission_CallRepoWithCommissionToSave() { var actualUpdates = new List(); var newCommission = new Commission { Id = 0, Product = Product.ATMCard, RatePerProduct = 5, Role = Role.Teller }; var commissionsToUpdate = new List { newCommission }; _mockCommissionRepository.Setup(repo => repo.FindExistingCommission(newCommission.Role, newCommission.Product)) .ReturnsAsync((Commission)null); _mockCommissionRepository.Setup(repo => repo.SaveCommission(newCommission)); await _service.SaveCommissionsAsync(commissionsToUpdate); _mockCommissionRepository.Verify(repo => repo.FindExistingCommission(newCommission.Role, newCommission.Product), Times.Once); _mockCommissionRepository.Verify(repo => repo.SaveCommission(newCommission), Times.Once); _mockUnitOfWork.Verify(context => context.CompleteAsync(), Times.Once); } [Test] public void SaveCommissionsAsync_NewCommissionMatchInRepo_ThrowsCommissionExistsException() { var newCommission = new Commission { Id = 0, Product = Product.CheckCard, RatePerProduct = 10, Role = Role.ABM }; var commissions = new List { newCommission }; var existingInRepo = new Commission { Id = 1, Product = Product.CheckCard, RatePerProduct = 15, Role = Role.ABM }; _mockCommissionRepository.Setup(repo => repo.FindExistingCommission(newCommission.Role, newCommission.Product)) .ReturnsAsync(existingInRepo); var ex = Assert.ThrowsAsync(async () => { await _service.SaveCommissionsAsync(commissions); }); Assert.AreEqual("Commission already exists for Role=ABM, Product=CheckCard", ex.Message); _mockCommissionRepository.Verify(repo => repo.FindExistingCommission(newCommission.Role, newCommission.Product), Times.Once); _mockCommissionRepository.Verify(repo => repo.SaveCommission(It.IsAny()), Times.Never); _mockUnitOfWork.Verify(context => context.CompleteAsync(), Times.Never); _mockCommissionRepository.VerifyNoOtherCalls(); } [Test] public async Task SaveCommissionsAsync_UpdateCommission_SetsRate() { var updates = new Commission { Id = 1, Product = Product.CheckCard, RatePerProduct = 20, Role = Role.ABM }; var commissions = new List { updates }; var commissionToUpdate = new Commission { Id = 1, Product = Product.CheckCard, RatePerProduct = 15, Role = Role.ABM }; Assert.AreEqual(15, commissionToUpdate.RatePerProduct); _mockCommissionRepository.Setup(repo => repo.FindExistingCommission(updates.Id)) .ReturnsAsync(commissionToUpdate); await _service.SaveCommissionsAsync(commissions); Assert.AreEqual(20, commissionToUpdate.RatePerProduct); _mockCommissionRepository.Verify(repo => repo.FindExistingCommission(updates.Id), Times.Once); _mockUnitOfWork.Verify(context => context.CompleteAsync(), Times.Once); _mockCommissionRepository.VerifyNoOtherCalls(); } } }