using Moq; using NUnit.Framework; using System; using System.Collections.Generic; using System.Linq; using CandyHouseBase.DataModels; using CandyHouseBase.Exceptions; using CandyHouseBase.Extensions; using CandyHouseBase.Implementations; using CandyHouseBase.Interfaces.BusinessLogicsContracts; using CandyHouseBase.Interfaces.StoragesContracts; using Microsoft.Extensions.Logging; namespace CandyHouseTests.BusinessLogicsContractsTests { [TestFixture] internal class IngredientBusinessLogicContractTests { private IngredientBusinessLogicContract _ingredientBusinessLogicContract; private Mock _ingredientStorageContact; [OneTimeSetUp] public void OneTimeSetUp() { _ingredientStorageContact = new Mock(); _ingredientBusinessLogicContract = new IngredientBusinessLogicContract( _ingredientStorageContact.Object, new Mock().Object ); } [SetUp] public void SetUp() { _ingredientStorageContact.Reset(); } [Test] public void GetAllIngredients_ReturnsListOfRecords_Test() { // Arrange var ingredients = new List { new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100), new IngredientDataModel(Guid.NewGuid().ToString(), "Flour", "kg", 200), new IngredientDataModel(Guid.NewGuid().ToString(), "Cocoa", "kg", 50) }; _ingredientStorageContact.Setup(x => x.GetList()).Returns(ingredients); // Act var list = _ingredientBusinessLogicContract.GetAllIngredients(); // Assert Assert.That(list, Is.Not.Null); Assert.That(list, Is.EquivalentTo(ingredients)); Assert.That(list.All(i => Guid.TryParse(i.Id, out _) && !i.Name.IsEmpty() && !i.Unit.IsEmpty() && i.Cost >= 0), Is.True); } [Test] public void GetAllIngredients_ReturnsEmptyList_Test() { // Arrange _ingredientStorageContact.Setup(x => x.GetList()).Returns(new List()); // Act var list = _ingredientBusinessLogicContract.GetAllIngredients(); // Assert Assert.That(list, Is.Not.Null); Assert.That(list, Has.Count.EqualTo(0)); _ingredientStorageContact.Verify(x => x.GetList(), Times.Once); } [Test] public void GetAllIngredients_ReturnsNull_ThrowException_Test() { // Arrange _ingredientStorageContact.Setup(x => x.GetList()).Returns((List)null); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetAllIngredients(), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetList(), Times.Once); } [Test] public void GetAllIngredients_StorageThrowError_ThrowException_Test() { // Arrange _ingredientStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException())); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetAllIngredients(), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetList(), Times.Once); } [Test] public void GetIngredientByData_ReturnsIngredientById_Test() { // Arrange var id = Guid.NewGuid().ToString(); var ingredient = new IngredientDataModel(id, "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns(ingredient); // Act var element = _ingredientBusinessLogicContract.GetIngredientByData(id); // Assert Assert.That(element, Is.Not.Null); Assert.That(element.Id, Is.EqualTo(id)); Assert.That(Guid.TryParse(element.Id, out _), Is.True); Assert.That(!element.Name.IsEmpty()); Assert.That(!element.Unit.IsEmpty()); Assert.That(element.Cost >= 0); _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); } [Test] public void GetIngredientByData_ReturnsIngredientByName_Test() { // Arrange var name = "Sugar"; var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), name, "kg", 100); _ingredientStorageContact.Setup(x => x.GetElementByName(name)).Returns(ingredient); // Act var element = _ingredientBusinessLogicContract.GetIngredientByData(name); // Assert Assert.That(element, Is.Not.Null); Assert.That(element.Name, Is.EqualTo(name)); Assert.That(Guid.TryParse(element.Id, out _), Is.True); Assert.That(!element.Unit.IsEmpty()); Assert.That(element.Cost >= 0); _ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny()), Times.Once); } [Test] public void GetIngredientByData_EmptyData_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(null), Throws.TypeOf()); Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(string.Empty), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); _ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny()), Times.Never); } [Test] public void GetIngredientByData_NotFoundById_ThrowException_Test() { // Arrange var id = Guid.NewGuid().ToString(); // Valid Guid _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(id), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once); } [Test] public void GetIngredientByData_NotFoundByName_ThrowException_Test() { // Arrange var name = "Nonexistent"; _ingredientStorageContact.Setup(x => x.GetElementByName(name)).Returns((IngredientDataModel)null); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(name), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementByName(name), Times.Once); } [Test] public void GetIngredientByData_StorageThrowError_ThrowException_Test() { // Arrange _ingredientStorageContact.Setup(x => x.GetElementById(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); _ingredientStorageContact.Setup(x => x.GetElementByName(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(Guid.NewGuid().ToString()), Throws.TypeOf()); Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData("Sugar"), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); _ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny()), Times.Once); } [Test] public void InsertIngredient_CorrectRecord_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.AddElement(ingredient)).Verifiable(); // Act _ingredientBusinessLogicContract.InsertIngredient(ingredient); // Assert _ingredientStorageContact.Verify(x => x.AddElement(ingredient), Times.Once); } [Test] public void InsertIngredient_RecordWithExistsData_ThrowException_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.AddElement(ingredient)) .Throws(new ElementExistsException("ID", ingredient.Id)); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(ingredient), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.AddElement(ingredient), Times.Once); } [Test] public void InsertIngredient_NullRecord_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(null), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); } [Test] public void InsertIngredient_InvalidRecord_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(new IngredientDataModel("", "", "", -1)), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); } [Test] public void InsertIngredient_StorageThrowError_ThrowException_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.AddElement(ingredient)) .Throws(new StorageException(new InvalidOperationException())); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(ingredient), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.AddElement(ingredient), Times.Once); } [Test] public void UpdateIngredient_CorrectRecord_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)).Verifiable(); // Act _ingredientBusinessLogicContract.UpdateIngredient(ingredient); // Assert _ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once); } [Test] public void UpdateIngredient_RecordNotFound_ThrowException_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)) .Throws(new ElementNotFoundException(ingredient.Id)); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(ingredient), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once); } [Test] public void UpdateIngredient_NullRecord_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(null), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); } [Test] public void UpdateIngredient_InvalidRecord_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(new IngredientDataModel("", "", "", -1)), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); } [Test] public void UpdateIngredient_StorageThrowError_ThrowException_Test() { // Arrange var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); _ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)) .Throws(new StorageException(new InvalidOperationException())); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(ingredient), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once); } [Test] public void DeleteIngredient_CorrectId_Test() { // Arrange var id = Guid.NewGuid().ToString(); var ingredient = new IngredientDataModel(id, "Sugar", "kg", 100); var flag = false; _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns(ingredient); _ingredientStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; }); // Act _ingredientBusinessLogicContract.DeleteIngredient(id); // Assert _ingredientStorageContact.Verify(x => x.DeleteElement(id), Times.Once); Assert.That(flag); Assert.That(Guid.TryParse(ingredient.Id, out _), Is.True); Assert.That(!ingredient.Name.IsEmpty()); Assert.That(!ingredient.Unit.IsEmpty()); Assert.That(ingredient.Cost >= 0); } [Test] public void DeleteIngredient_RecordNotFound_ThrowException_Test() { // Arrange var id = Guid.NewGuid().ToString(); // Use valid Guid _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(id), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once); } [Test] public void DeleteIngredient_StorageThrowError_ThrowException_Test() { // Arrange var id = Guid.NewGuid().ToString(); _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns(new IngredientDataModel(id, "Sugar", "kg", 100)); _ingredientStorageContact.Setup(x => x.DeleteElement(id)).Throws(new StorageException(new InvalidOperationException())); // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(id), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once); _ingredientStorageContact.Verify(x => x.DeleteElement(id), Times.Once); } [Test] public void DeleteIngredient_NullOrEmptyId_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(null), Throws.TypeOf()); Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(string.Empty), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); } [Test] public void DeleteIngredient_InvalidId_ThrowException_Test() { // Act & Assert Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient("invalid"), Throws.TypeOf()); _ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); } } }