diff --git a/CandyHouseSolution/CandyHouseBase/App.config b/CandyHouseSolution/CandyHouseBase/App.config new file mode 100644 index 0000000..b47a6aa --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/AssemblyInfo.cs b/CandyHouseSolution/CandyHouseBase/AssemblyInfo.cs new file mode 100644 index 0000000..15406df --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("CandyHouseTests")] \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj b/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj index 1a8ba7a..2b89ece 100644 --- a/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj +++ b/CandyHouseSolution/CandyHouseBase/CandyHouseBase.csproj @@ -13,6 +13,7 @@ v4.7.1 512 true + 12 AnyCPU @@ -34,12 +35,65 @@ 4 + + ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Logging.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Options.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Primitives.dll + + + ..\packages\Moq.4.20.72\lib\net462\Moq.dll + + + + ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll + + + + + ..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.1.25080.5\lib\net462\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + @@ -50,10 +104,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + <_Parameter1>$(AssemblyName).Test.dll + + diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs index cb7b168..af1f64f 100644 --- a/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs +++ b/CandyHouseSolution/CandyHouseBase/DataModels/OrderDataModel.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using CandyHouseBase.Enums; using CandyHouseBase.Exceptions; using CandyHouseBase.Extensions; @@ -14,19 +13,19 @@ namespace CandyHouseBase.DataModels public DateTime OrderDate { get; private set; } public decimal TotalAmount { get; private set; } public decimal DiscountAmount { get; private set; } - public string OrderId { get; private set; } + public string ProductId { get; private set; } public string PekarId { get; private set; } public StatusType StatusType { get; private set; } public OrderDataModel(string id, string customerName, DateTime orderDate, decimal totalAmount, - decimal discountAmount, string orderId, string pekarId, StatusType statusType) + decimal discountAmount, string productId, string pekarId, StatusType statusType) { Id = id; CustomerName = customerName; OrderDate = orderDate; TotalAmount = totalAmount; DiscountAmount = discountAmount; - OrderId = orderId; + ProductId = productId; PekarId = pekarId; StatusType = statusType; } @@ -39,8 +38,8 @@ namespace CandyHouseBase.DataModels throw new ValidationException("CustomerName is empty"); if (TotalAmount < 0) throw new ValidationException("TotalAmount cannot be negative"); if (DiscountAmount < 0) throw new ValidationException("DiscountAmount cannot be negative"); - if (OrderId.IsEmpty()) throw new ValidationException("Field OrderId is empty"); - if (!OrderId.IsGuid()) throw new ValidationException("OrderId must be a GUID"); + if (ProductId.IsEmpty()) throw new ValidationException("Field productId is empty"); + if (!ProductId.IsGuid()) throw new ValidationException("productId must be a GUID"); } } } \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs b/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs index 6fa71ac..321d7a6 100644 --- a/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs +++ b/CandyHouseSolution/CandyHouseBase/DataModels/ProductDataModel.cs @@ -12,7 +12,7 @@ namespace CandyHouseBase.DataModels public string Name { get => name; - private set + set { if (!name.IsEmpty()) OldName = name; name = value.Trim(); @@ -22,7 +22,7 @@ namespace CandyHouseBase.DataModels public string Description { get => description; - private set + set { if (!description.IsEmpty()) OldDescription = description; description = value.Trim(); @@ -35,7 +35,7 @@ namespace CandyHouseBase.DataModels private string name; private string description; - + public List IngredientsItems { get; private set; } public ProductDataModel(string id, string name, string description, List ingredients) diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/DateTimeExtensions.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/DateTimeExtensions.cs new file mode 100644 index 0000000..31a72a1 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/DateTimeExtensions.cs @@ -0,0 +1,11 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public static class DateTimeExtensions +{ + public static bool IsDateNotOlder(this DateTime date, DateTime olderDate) + { + return date >= olderDate; + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/ElementExistsException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/ElementExistsException.cs new file mode 100644 index 0000000..92817ae --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/ElementExistsException.cs @@ -0,0 +1,16 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public class ElementExistsException : Exception +{ + public string ParamName { get; private set; } + public string ParamValue { get; private set; } + + public ElementExistsException(string paramName, string paramValue) : + base($"There is already an element with value {paramValue} of parameter {paramName}") + { + ParamName = paramName; + ParamValue = paramValue; + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/ElementNotFoundException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/ElementNotFoundException.cs new file mode 100644 index 0000000..64e2f51 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/ElementNotFoundException.cs @@ -0,0 +1,13 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public class ElementNotFoundException : Exception +{ + public string Value { get; private set; } + + public ElementNotFoundException(string value) : base($"Element not found at value = {value}") + { + Value = value; + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/IncorrectDatesException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/IncorrectDatesException.cs new file mode 100644 index 0000000..4115cae --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/IncorrectDatesException.cs @@ -0,0 +1,11 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public class IncorrectDatesException : Exception +{ + public IncorrectDatesException(DateTime start, DateTime end) : base( + $"The end date must be later than the start date.. StartDate: {start:dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}") + { + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/NullListException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/NullListException.cs new file mode 100644 index 0000000..33a6e79 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/NullListException.cs @@ -0,0 +1,10 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public class NullListException : Exception +{ + public NullListException() : base("The returned list is null") + { + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Exceptions/StorageException.cs b/CandyHouseSolution/CandyHouseBase/Exceptions/StorageException.cs new file mode 100644 index 0000000..0d9e614 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Exceptions/StorageException.cs @@ -0,0 +1,11 @@ +using System; + +namespace CandyHouseBase.Exceptions; + +public class StorageException : Exception + +{ + public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex) + { + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/IngredientBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/IngredientBusinessLogicContract.cs new file mode 100644 index 0000000..f1a6304 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/IngredientBusinessLogicContract.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class IngredientBusinessLogicContract( + IIngredientStorageContact ingredientStorageContact, + ILogger logger) + : IIngredientBusinessLogicContact + { + private readonly IIngredientStorageContact _ingredientStorageContact = ingredientStorageContact; + private readonly ILogger _logger = logger; + + public List GetAllIngredients() + { + return new List(); + } + + public IngredientDataModel GetIngredientByData(string data) + { + return new IngredientDataModel("", "", "", 100); + } + + public void InsertIngredient(IngredientDataModel ingredient) + { + } + + public void UpdateIngredient(IngredientDataModel ingredient) + { + } + + public void DeleteIngredient(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/OrderBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/OrderBusinessLogicContract.cs new file mode 100644 index 0000000..399dd28 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/OrderBusinessLogicContract.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class OrderBusinessLogicContract( + IOrderStorageContact orderStorageContact, + IPekarStorageContact pekarStorageContact, + IProductStorageContact productStorageContact, + ILogger logger) + : IOrderBusinessLogicContact + { + private readonly IOrderStorageContact _orderStorageContact = orderStorageContact; + private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact; + private readonly IProductStorageContact _productStorageContact = productStorageContact; + private readonly ILogger _logger = logger; + + public List GetAllOrders() + { + return new List(); + } + + public OrderDataModel GetOrderByData(string data) + { + return new OrderDataModel("", "", new DateTime(), + 100, 100m, "", "", StatusType.Cancelled); + } + + public void InsertOrder(OrderDataModel order) + { + } + + public void UpdateOrder(OrderDataModel order) + { + } + + public void DeleteOrder(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/PekarBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/PekarBusinessLogicContract.cs new file mode 100644 index 0000000..862aeaf --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/PekarBusinessLogicContract.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class PekarBusinessLogicContract( + IPekarStorageContact pekarStorageContact, + IProductStorageContact productStorageContact, + IPositionStorageContact positionStorageContact, + ILogger logger) + : IPekarBusinessLogicContact + { + private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact; + private readonly IProductStorageContact _productStorageContact = productStorageContact; + private readonly IPositionStorageContact _positionStorageContact = positionStorageContact; + private readonly ILogger _logger = logger; + + public List GetAllPekars() + { + return new List(); + } + + public List GetAllDataOfPekar(string pekarId) + { + return new List(); + } + + public PekarDataModel GetPekarByData(string data) + { + return new PekarDataModel("", "", "", + 0, new List()); + } + + public void InsertPekar(PekarDataModel order) + { + } + + public void UpdatePekar(PekarDataModel order) + { + } + + public void DeletePekar(string id) + { + } + + public void RestorePekar(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/PositionBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/PositionBusinessLogicContract.cs new file mode 100644 index 0000000..c3c21ac --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/PositionBusinessLogicContract.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class PositionBusinessLogicContract( + IPositionStorageContact positionStorageContact, + ILogger logger) + : IPositionBusinessLogicContact + { + private readonly IPositionStorageContact _positionStorageContact = positionStorageContact; + private readonly ILogger _logger = logger; + + public List GetAllPositions() + { + return new List(); + } + + public PositionDataModel GetPositionByData(string data) + { + return new PositionDataModel("", PositionType.Cool, ""); + } + + public void InsertPosition(PositionDataModel position) + { + } + + public void UpdatePosition(PositionDataModel position) + { + } + + public void DeletePosition(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/ProductBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/ProductBusinessLogicContract.cs new file mode 100644 index 0000000..c25e5f5 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/ProductBusinessLogicContract.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class ProductBusinessLogicContract( + IProductStorageContact productStorageContact, + IIngredientStorageContact ingredientStorageContact, + ILogger logger) + : IProductBusinessLogicContact + { + private readonly IProductStorageContact _productStorageContact = productStorageContact; + private readonly IIngredientStorageContact _ingredientStorageContact = ingredientStorageContact; + private readonly ILogger _logger = logger; + + public List GetAllProducts() + { + return new List(); + } + + public ProductDataModel GetProductByData(string data) + { + return new ProductDataModel("", "", "", new List()); + } + + public void InsertProduct(ProductDataModel product) + { + } + + public void UpdateProduct(ProductDataModel product) + { + } + + public void DeleteProduct(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Implementations/SalaryBusinessLogicContract.cs b/CandyHouseSolution/CandyHouseBase/Implementations/SalaryBusinessLogicContract.cs new file mode 100644 index 0000000..4e1babe --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Implementations/SalaryBusinessLogicContract.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseBase.Implementations +{ + internal class SalaryBusinessLogicContract( + ISalaryStorageContact salaryStorageContact, + IPekarStorageContact pekarStorageContact, + ILogger logger) + : ISalaryStorageContact + { + private readonly ISalaryStorageContact _salaryStorageContact = salaryStorageContact; + private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact; + private readonly ILogger _logger = logger; + + public List GetList() + { + return new List(); + } + + public SalaryDataModel GetElementById(string id) + { + return new SalaryDataModel("", "", new DateTime(), 0, 0, 0); + } + + public void AddElement(SalaryDataModel element) + { + } + + public void UpdateElement(SalaryDataModel element) + { + } + + public void DeleteElement(string id) + { + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IIngredientBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IIngredientBusinessLogicContact.cs new file mode 100644 index 0000000..c1f7a8c --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IIngredientBusinessLogicContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface IIngredientBusinessLogicContact + { + List GetAllIngredients(); + IngredientDataModel GetIngredientByData(string data); + void InsertIngredient(IngredientDataModel ingredient); + void UpdateIngredient(IngredientDataModel ingredient); + void DeleteIngredient(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IOrderBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IOrderBusinessLogicContact.cs new file mode 100644 index 0000000..35b19f7 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IOrderBusinessLogicContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface IOrderBusinessLogicContact + { + List GetAllOrders(); + OrderDataModel GetOrderByData(string data); + void InsertOrder(OrderDataModel order); + void UpdateOrder(OrderDataModel order); + void DeleteOrder(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPekarBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPekarBusinessLogicContact.cs new file mode 100644 index 0000000..cc6d1b3 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPekarBusinessLogicContact.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface IPekarBusinessLogicContact + { + List GetAllPekars(); + List GetAllDataOfPekar(string pekarId); + PekarDataModel GetPekarByData(string data); + void InsertPekar(PekarDataModel order); + void UpdatePekar(PekarDataModel order); + void DeletePekar(string id); + void RestorePekar(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPositionBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPositionBusinessLogicContact.cs new file mode 100644 index 0000000..cbec9b2 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IPositionBusinessLogicContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface IPositionBusinessLogicContact + { + List GetAllPositions(); + PositionDataModel GetPositionByData(string data); + void InsertPosition(PositionDataModel position); + void UpdatePosition(PositionDataModel position); + void DeletePosition(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IProductBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IProductBusinessLogicContact.cs new file mode 100644 index 0000000..58a53d3 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/IProductBusinessLogicContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface IProductBusinessLogicContact + { + List GetAllProducts(); + ProductDataModel GetProductByData(string data); + void InsertProduct(ProductDataModel product); + void UpdateProduct(ProductDataModel product); + void DeleteProduct(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/ISalaryBusinessLogicContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/ISalaryBusinessLogicContact.cs new file mode 100644 index 0000000..e788953 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/BusinessLogicsContracts/ISalaryBusinessLogicContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.BusinessLogicsContracts +{ + public interface ISalaryBusinessLogicContact + { + List GetAllSalaries(); + SalaryDataModel GetSalaryByData(string data); + void InsertSalary(SalaryDataModel salary); + void UpdateSalary(SalaryDataModel salary); + void DeleteSalary(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IIngredientStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IIngredientStorageContact.cs new file mode 100644 index 0000000..87c2051 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IIngredientStorageContact.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface IIngredientStorageContact + { + List GetList(); + IngredientDataModel GetElementById(string id); + IngredientDataModel GetElementByName(string name); + void AddElement(IngredientDataModel ingredient); + void UpdateElement(IngredientDataModel ingredient); + void DeleteElement(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IOrderStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IOrderStorageContact.cs new file mode 100644 index 0000000..e3c17e0 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IOrderStorageContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface IOrderStorageContact + { + List GetOrders(); + void AddElement(OrderDataModel order); + void UpdateElement(OrderDataModel order); + void DeleteElement(OrderDataModel order); + OrderDataModel GetElementById(int orderId); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPekarStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPekarStorageContact.cs new file mode 100644 index 0000000..1688a57 --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPekarStorageContact.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface IPekarStorageContact + { + List GetList(); + List GetPekarWithHistory(string id); + PekarDataModel GetElementById(string id); + PekarDataModel GetElementByFio(string fio); + void AddElement(PekarDataModel item); + void UpdateElement(PekarDataModel item); + void DeleteElement(string id); + void RestoreElement(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPositionStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPositionStorageContact.cs new file mode 100644 index 0000000..5686c8b --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IPositionStorageContact.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface IProductStorageContact + { + List GetList(); + ProductDataModel GetElementById(string id); + ProductDataModel GetElementByName(string name); + ProductDataModel GetElementByOldName(string name); + void AddElement(ProductDataModel element); + void UpdateElement(ProductDataModel element); + void DeleteElement(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IProductStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IProductStorageContact.cs new file mode 100644 index 0000000..1565f3b --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/IProductStorageContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface IPositionStorageContact + { + List GetList(); + PositionDataModel GetElementById(string id); + void AddElement(PositionDataModel element); + void UpdateElement(PositionDataModel element); + void DeleteElement(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/ISalaryStorageContact.cs b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/ISalaryStorageContact.cs new file mode 100644 index 0000000..a85e5df --- /dev/null +++ b/CandyHouseSolution/CandyHouseBase/Interfaces/StoragesContracts/ISalaryStorageContact.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using CandyHouseBase.DataModels; + +namespace CandyHouseBase.Interfaces.StoragesContracts +{ + public interface ISalaryStorageContact + { + List GetList(); + SalaryDataModel GetElementById(string id); + void AddElement(SalaryDataModel element); + void UpdateElement(SalaryDataModel element); + void DeleteElement(string id); + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/App.config b/CandyHouseSolution/CandyHouseTests/App.config index 74b8a4e..f0c8414 100644 --- a/CandyHouseSolution/CandyHouseTests/App.config +++ b/CandyHouseSolution/CandyHouseTests/App.config @@ -5,6 +5,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/IngredientBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/IngredientBusinessLogicContractTests.cs new file mode 100644 index 0000000..24fab86 --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/IngredientBusinessLogicContractTests.cs @@ -0,0 +1,383 @@ +using Moq; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Exceptions; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; +using CandyHouseBase.Implementations; + +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(Guid.NewGuid().ToString(), "Sugar", "kg", 100), + new(Guid.NewGuid().ToString(), "Flour", "kg", 200), + new(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)); + } + + [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 GetIngredientById_ReturnsRecord_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)); + _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetIngredientByName_ReturnsRecord_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)); + _ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny()), Times.Once); + } + + [Test] + public void GetIngredientById_NotFoundRecord_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null); + + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(id), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetIngredientByName_NotFoundRecord_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(It.IsAny()), Times.Once); + } + + [Test] + public void GetIngredientById_StorageThrowError_ThrowException_Test() + { + // Arrange + _ingredientStorageContact.Setup(x => x.GetElementById(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetIngredientByName_StorageThrowError_ThrowException_Test() + { + // Arrange + _ingredientStorageContact.Setup(x => x.GetElementByName(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData("Sugar"), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny()), Times.Once); + } + + [Test] + public void AddIngredient_CorrectRecord_Test() + { + // Arrange + var flag = false; + var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); + _ingredientStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((IngredientDataModel x) => + { + flag = x.Id == ingredient.Id && x.Name == ingredient.Name && + x.Cost == ingredient.Cost && x.Unit == ingredient.Unit; + }); + + // Act + _ingredientBusinessLogicContract.InsertIngredient(ingredient); + + // Assert + _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + } + + [Test] + public void AddIngredient_RecordWithExistsData_ThrowException_Test() + { + var ingredient = It.IsAny(); + // Arrange + _ingredientStorageContact.Setup(x => x.AddElement(ingredient)) + .Throws(new ElementExistsException("ID", ingredient.Id)); + + // Act & Assert + Assert.That( + () => _ingredientBusinessLogicContract.InsertIngredient( + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void AddIngredient_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(null), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void AddIngredient_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That( + () => _ingredientBusinessLogicContract.InsertIngredient(new IngredientDataModel("", null, "", -1)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void AddIngredient_StorageThrowError_ThrowException_Test() + { + // Arrange + _ingredientStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That( + () => _ingredientBusinessLogicContract.InsertIngredient( + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateIngredient_CorrectRecord_Test() + { + // Arrange + var flag = false; + var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100); + _ingredientStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((IngredientDataModel x) => + { + flag = x.Id == ingredient.Id && x.Name == ingredient.Name && + x.Cost == ingredient.Cost && x.Unit == ingredient.Unit; + }); + + // Act + _ingredientBusinessLogicContract.UpdateIngredient(ingredient); + + // Assert + _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + } + + [Test] + public void UpdateIngredient_RecordNotFound_ThrowException_Test() + { + var ingredient = It.IsAny(); + // Arrange + _ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)) + .Throws(new ElementNotFoundException(ingredient.ToString())); + + // Act & Assert + Assert.That( + () => _ingredientBusinessLogicContract.UpdateIngredient( + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), 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("", null, "", -1)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateIngredient_StorageThrowError_ThrowException_Test() + { + // Arrange + _ingredientStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That( + () => _ingredientBusinessLogicContract.UpdateIngredient( + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteIngredient_CorrectId_Test() + { + // Arrange + var id = "1"; + var flag = false; + _ingredientStorageContact.Setup(x => x.DeleteElement(It.Is((string x) => x == id))) + .Callback(() => { flag = true; }); + + // Act + _ingredientBusinessLogicContract.DeleteIngredient(id); + + // Assert + _ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + Assert.That(flag); + } + + [Test] + public void DeleteIngredient_RecordNotFound_ThrowException_Test() + { + var ingredient = It.IsAny(); + // Arrange + _ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)) + .Throws(new ElementNotFoundException(ingredient.ToString())); + + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient("nonexistent"), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny()), 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); + } + + [Test] + public void DeleteIngredient_StorageThrowError_ThrowException_Test() + { + // Arrange + _ingredientStorageContact.Setup(x => x.DeleteElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/OrderBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/OrderBusinessLogicContractTests.cs new file mode 100644 index 0000000..e9d3b7c --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/OrderBusinessLogicContractTests.cs @@ -0,0 +1,476 @@ +using Moq; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +using CandyHouseBase.Exceptions; +using CandyHouseBase.Implementations; +using CandyHouseBase.Interfaces.BusinessLogicsContracts; +using CandyHouseBase.Interfaces.StoragesContracts; +using Microsoft.Extensions.Logging; + +namespace CandyHouseTests.BusinessLogicsContractsTests +{ + [TestFixture] + internal class OrderBusinessLogicContractTests + { + private OrderBusinessLogicContract _orderBusinessLogicContract; + private Mock _orderStorageContact; + private Mock _pekarStorageContact; + private Mock _productStorageContact; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _orderStorageContact = new Mock(); + _pekarStorageContact = new Mock(); + _productStorageContact = new Mock(); + _orderBusinessLogicContract = new OrderBusinessLogicContract( + _orderStorageContact.Object, + _pekarStorageContact.Object, + _productStorageContact.Object, + new Mock().Object + ); + } + + [SetUp] + public void SetUp() + { + _orderStorageContact.Reset(); + _pekarStorageContact.Reset(); + _productStorageContact.Reset(); + } + + [Test] + public void GetAllOrders_ReturnsListOfRecords_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var orders = new List + { + new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now.AddDays(-1), + 100.50m, + 10.50m, + productId, + pekarId, + StatusType.Pending + ), + new OrderDataModel( + Guid.NewGuid().ToString(), + "Jane Smith", + DateTime.Now, + 200.00m, + 20.00m, + productId, + pekarId, + StatusType.Completed + ) + }; + _orderStorageContact.Setup(x => x.GetOrders()).Returns(orders); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)) + .Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + _productStorageContact.Setup(x => x.GetElementById(productId)) + .Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List())); + + // Act + var list = _orderBusinessLogicContract.GetAllOrders(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Is.EquivalentTo(orders)); + } + + [Test] + public void GetAllOrders_ReturnsEmptyList_Test() + { + // Arrange + _orderStorageContact.Setup(x => x.GetOrders()).Returns(new List()); + + // Act + var list = _orderBusinessLogicContract.GetAllOrders(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(0)); + _orderStorageContact.Verify(x => x.GetOrders(), Times.Once); + } + + [Test] + public void GetAllOrders_ReturnsNull_ThrowException_Test() + { + // Arrange + _orderStorageContact.Setup(x => x.GetOrders()).Returns((List)null); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.GetAllOrders(), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.GetOrders(), Times.Once); + } + + [Test] + public void GetAllOrders_StorageThrowError_ThrowException_Test() + { + // Arrange + _orderStorageContact.Setup(x => x.GetOrders()) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.GetAllOrders(), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.GetOrders(), Times.Once); + } + + [Test] + public void GetOrderByData_ReturnsOrderById_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var order = new OrderDataModel( + id, + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.GetElementById(It.Is(i => i.ToString() == id))).Returns(order); + + // Act + var element = _orderBusinessLogicContract.GetOrderByData(id); + + // Assert + Assert.That(element, Is.Not.Null); + Assert.That(element.Id, Is.EqualTo(id)); + _orderStorageContact.Verify(x => x.GetElementById(It.Is(i => i.ToString() == id)), Times.Once); + } + + [Test] + public void GetOrderByData_EmptyData_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.GetOrderByData(null), Throws.TypeOf()); + Assert.That(() => _orderBusinessLogicContract.GetOrderByData(string.Empty), + Throws.TypeOf()); + _orderStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); + } + + [Test] + public void GetOrderByData_NotFoundRecord_ThrowException_Test() + { + // Arrange + var id = "999"; + _orderStorageContact.Setup(x => x.GetElementById(It.Is(i => i.ToString() == id))) + .Returns((OrderDataModel)null); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.GetOrderByData(id), + Throws.TypeOf()); + _orderStorageContact.Verify(x => x.GetElementById(It.Is(i => i.ToString() == id)), Times.Once); + } + + [Test] + public void GetOrderByData_StorageThrowError_ThrowException_Test() + { + // Arrange + _orderStorageContact.Setup(x => x.GetElementById(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.GetOrderByData("1"), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void InsertOrder_CorrectRecord_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var flag = false; + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + productId, + pekarId, + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((OrderDataModel x) => + { + flag = x.Id == order.Id && x.CustomerName == order.CustomerName && x.OrderDate == order.OrderDate && + x.TotalAmount == order.TotalAmount && x.DiscountAmount == order.DiscountAmount && + x.ProductId == order.ProductId && x.PekarId == order.PekarId && + x.StatusType == order.StatusType; + }); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)) + .Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + _productStorageContact.Setup(x => x.GetElementById(productId)) + .Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List())); + + // Act + _orderBusinessLogicContract.InsertOrder(order); + + // Assert + _orderStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + } + + [Test] + public void InsertOrder_RecordWithExistsData_ThrowException_Test() + { + // Arrange + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new ElementExistsException("ID", order.Id)); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.InsertOrder(order), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void InsertOrder_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.InsertOrder(null), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertOrder_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.InsertOrder(new OrderDataModel( + "", + "", + DateTime.Now, + -100.50m, + -10.50m, + "", + "", + StatusType.Pending + )), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertOrder_StorageThrowError_ThrowException_Test() + { + // Arrange + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.InsertOrder(order), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateOrder_CorrectRecord_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var flag = false; + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + productId, + pekarId, + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((OrderDataModel x) => + { + flag = x.Id == order.Id && x.CustomerName == order.CustomerName && x.OrderDate == order.OrderDate && + x.TotalAmount == order.TotalAmount && x.DiscountAmount == order.DiscountAmount && + x.ProductId == order.ProductId && x.PekarId == order.PekarId && + x.StatusType == order.StatusType; + }); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)) + .Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + _productStorageContact.Setup(x => x.GetElementById(productId)) + .Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List())); + + // Act + _orderBusinessLogicContract.UpdateOrder(order); + + // Assert + _orderStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + } + + [Test] + public void UpdateOrder_RecordNotFound_ThrowException_Test() + { + // Arrange + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new ElementNotFoundException("Order not found")); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.UpdateOrder(order), + Throws.TypeOf()); + _orderStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateOrder_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.UpdateOrder(null), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateOrder_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.UpdateOrder(new OrderDataModel( + "", + "", + DateTime.Now, + -100.50m, + -10.50m, + "", + "", + StatusType.Pending + )), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateOrder_StorageThrowError_ThrowException_Test() + { + // Arrange + var order = new OrderDataModel( + Guid.NewGuid().ToString(), + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + _orderStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.UpdateOrder(order), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteOrder_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var order = new OrderDataModel( + id, + "John Doe", + DateTime.Now, + 100.50m, + 10.50m, + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + StatusType.Pending + ); + var flag = false; + _orderStorageContact.Setup(x => x.DeleteElement(It.Is(o => o.Id == id))) + .Callback(() => { flag = true; }); + _orderStorageContact.Setup(x => x.GetOrders()).Returns(new List { order }); + + // Act + _orderBusinessLogicContract.DeleteOrder(id); + + // Assert + _orderStorageContact.Verify(x => x.DeleteElement(It.Is(o => o.Id == id)), Times.Once); + Assert.That(flag); + } + + [Test] + public void DeleteOrder_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _orderStorageContact.Setup(x => x.GetOrders()).Returns(new List()); + _orderStorageContact.Setup(x => x.DeleteElement(It.Is(o => o.Id == id))) + .Throws(new ElementNotFoundException("Order not found")); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.DeleteOrder(id), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.DeleteElement(It.Is(o => o.Id == id)), Times.Once); + } + + [Test] + public void DeleteOrder_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.DeleteOrder(null), Throws.TypeOf()); + Assert.That(() => _orderBusinessLogicContract.DeleteOrder(string.Empty), + Throws.TypeOf()); + _orderStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteOrder_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.DeleteOrder("invalid"), Throws.TypeOf()); + _orderStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteOrder_StorageThrowError_ThrowException_Test() + { + // Arrange + _orderStorageContact.Setup(x => x.DeleteElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _orderBusinessLogicContract.DeleteOrder(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _orderStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PekarBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PekarBusinessLogicContractTests.cs new file mode 100644 index 0000000..4b99e08 --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PekarBusinessLogicContractTests.cs @@ -0,0 +1,816 @@ +using Moq; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +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 PekarBusinessLogicContractTests + { + private PekarBusinessLogicContract _pekarBusinessLogicContract; + private Mock _pekarStorageContact; + private Mock _productStorageContact; + private Mock _positionStorageContact; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _pekarStorageContact = new Mock(); + _productStorageContact = new Mock(); + _positionStorageContact = new Mock(); + _pekarBusinessLogicContract = new PekarBusinessLogicContract( + _pekarStorageContact.Object, + _productStorageContact.Object, + _positionStorageContact.Object, + new Mock().Object + ); + } + + [SetUp] + public void SetUp() + { + _pekarStorageContact.Reset(); + _productStorageContact.Reset(); + _positionStorageContact.Reset(); + } + + [Test] + public void GetAllPekars_ReturnsListOfRecords_Test() + { + // Arrange + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var pekars = new List + { + new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ), + new PekarDataModel( + Guid.NewGuid().ToString(), + "Maria Petrova", + "Pastry Chef", + 1.8m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Pastry", + "Sweet pastry", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Flour", "kg", 200) + } + ) + } + ) + }; + _pekarStorageContact.Setup(x => x.GetList()).Returns(pekars); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekars[0].ProductsItems[0]); + + // Act + var list = _pekarBusinessLogicContract.GetAllPekars(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Is.EquivalentTo(pekars)); + Assert.That( + list.All(p => + Guid.TryParse(p.Id, out _) && !p.FIO.IsEmpty() && !p.Position.IsEmpty() && + p.BonusCoefficient > 0), Is.True); + } + + [Test] + public void GetAllPekars_ReturnsEmptyList_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.GetList()).Returns(new List()); + + // Act + var list = _pekarBusinessLogicContract.GetAllPekars(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(0)); + _pekarStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllPekars_ReturnsNull_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.GetList()).Returns((List)null); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllPekars(), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllPekars_StorageThrowError_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllPekars(), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllDataOfPekar_ReturnsListOfHistoryRecords_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var positionId = Guid.NewGuid().ToString(); + var historyRecords = new List + { + new PekarHistoryDataModel( + pekarId, + "Ivan Ivanov", + positionId.ToString(), + 1.5m, + DateTime.Now.AddDays(-30) + ), + new PekarHistoryDataModel( + pekarId, + "Ivan Ivanov", + positionId.ToString(), + 1.7m, + DateTime.Now.AddDays(-15) + ) + }; + var pekarsWithHistory = new List + { + new PekarDataModel( + pekarId, + "Ivan Ivanov", + "Baker", + 1.8m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ) + }; + _pekarStorageContact.Setup(x => x.GetPekarWithHistory(pekarId)).Returns(pekarsWithHistory); + _positionStorageContact.Setup(x => x.GetElementById(positionId)) + .Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position")); + + // Act + var list = _pekarBusinessLogicContract.GetAllDataOfPekar(pekarId); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list.Count, + Is.EqualTo(historyRecords.Count)); + Assert.That( + list.All(h => + Guid.TryParse(h.Id, out _) && !h.FIO.IsEmpty() && Guid.TryParse(h.Position, out _) && + h.BonusCoefficient > 0), Is.True); + _pekarStorageContact.Verify(x => x.GetPekarWithHistory(pekarId), Times.Once); + _positionStorageContact.Verify(x => x.GetElementById(positionId), Times.AtLeastOnce); + } + + [Test] + public void GetAllDataOfPekar_EmptyPekarId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllDataOfPekar(null), + Throws.TypeOf()); + Assert.That(() => _pekarBusinessLogicContract.GetAllDataOfPekar(string.Empty), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetPekarWithHistory(It.IsAny()), Times.Never); + } + + [Test] + public void GetAllDataOfPekar_NotFoundPekar_ThrowException_Test() + { + // Arrange + var pekarId = "nonexistent"; + _pekarStorageContact.Setup(x => x.GetPekarWithHistory(pekarId)).Returns(new List()); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllDataOfPekar(pekarId), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetPekarWithHistory(pekarId), Times.Once); + } + + [Test] + public void GetAllDataOfPekar_StorageThrowError_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.GetPekarWithHistory(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllDataOfPekar(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetPekarWithHistory(It.IsAny()), Times.Once); + } + + [Test] + public void GetAllDataOfPekar_InvalidPosition_ThrowException_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var positionId = "999"; // Invalid position ID + var pekarsWithHistory = new List + { + new PekarDataModel( + pekarId, + "Ivan Ivanov", + "Baker", + 1.8m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ) + }; + _pekarStorageContact.Setup(x => x.GetPekarWithHistory(pekarId)).Returns(pekarsWithHistory); + _positionStorageContact.Setup(x => x.GetElementById(positionId)).Returns((PositionDataModel)null); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetAllDataOfPekar(pekarId), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetPekarWithHistory(pekarId), Times.Once); + _positionStorageContact.Verify(x => x.GetElementById(positionId), Times.Once); + } + + [Test] + public void GetPekarByData_ReturnsPekarById_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var pekar = new PekarDataModel( + id, + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]); + + // Act + var element = _pekarBusinessLogicContract.GetPekarByData(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.FIO.IsEmpty()); + Assert.That(Regex.IsMatch(element.FIO, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(!element.Position.IsEmpty()); + Assert.That(element.BonusCoefficient > 0); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetPekarByData_EmptyData_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetPekarByData(null), Throws.TypeOf()); + Assert.That(() => _pekarBusinessLogicContract.GetPekarByData(string.Empty), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); + } + + [Test] + public void GetPekarByData_NotFoundPekar_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetPekarByData(id), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetPekarByData_StorageThrowError_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.GetElementById(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.GetPekarByData(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void InsertPekar_CorrectRecord_Test() + { + // Arrange + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var flag = false; + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((PekarDataModel x) => + { + flag = x.Id == pekar.Id && x.FIO == pekar.FIO && x.Position == pekar.Position && + x.BonusCoefficient == pekar.BonusCoefficient && + x.ProductsItems.SequenceEqual(pekar.ProductsItems); + }); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]); + + // Act + _pekarBusinessLogicContract.InsertPekar(pekar); + + // Assert + _pekarStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(pekar.Id, out _), Is.True); + Assert.That(!pekar.FIO.IsEmpty()); + Assert.That(Regex.IsMatch(pekar.FIO, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(!pekar.Position.IsEmpty()); + Assert.That(pekar.BonusCoefficient > 0); + } + + [Test] + public void InsertPekar_RecordWithExistsData_ThrowException_Test() + { + // Arrange + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new ElementExistsException("ID", pekar.Id)); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void InsertPekar_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.InsertPekar(null), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertPekar_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.InsertPekar(new PekarDataModel( + "", + "123", + "", + -1.0m, + new List + { + new ProductDataModel( + "", + "", + "", + new List + { + new IngredientDataModel("", "Sugar", "kg", -100) // Invalid Ingredient + } + ) + } + )), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertPekar_StorageThrowError_ThrowException_Test() + { + // Arrange + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdatePekar_CorrectRecord_Test() + { + // Arrange + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var flag = false; + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((PekarDataModel x) => + { + flag = x.Id == pekar.Id && x.FIO == pekar.FIO && x.Position == pekar.Position && + x.BonusCoefficient == pekar.BonusCoefficient && + x.ProductsItems.SequenceEqual(pekar.ProductsItems); + }); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]); + + // Act + _pekarBusinessLogicContract.UpdatePekar(pekar); + + // Assert + _pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(pekar.Id, out _), Is.True); + Assert.That(!pekar.FIO.IsEmpty()); + Assert.That(Regex.IsMatch(pekar.FIO, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(!pekar.Position.IsEmpty()); + Assert.That(pekar.BonusCoefficient > 0); + } + + [Test] + public void UpdatePekar_RecordNotFound_ThrowException_Test() + { + // Arrange + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new ElementNotFoundException("Pekar not found")); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(pekar), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdatePekar_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(null), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdatePekar_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(new PekarDataModel( + "", + "123", + "", + -1.0m, + new List + { + new ProductDataModel( + "", + "", + "", + new List + { + new IngredientDataModel("", "Sugar", "kg", -100) // Invalid Ingredient + } + ) + } + )), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdatePekar_StorageThrowError_ThrowException_Test() + { + // Arrange + var pekar = new PekarDataModel( + Guid.NewGuid().ToString(), + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ) + } + ); + _pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(pekar), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeletePekar_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var pekar = new PekarDataModel( + id, + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ); + var flag = false; + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar); + _pekarStorageContact.Setup(x => x.DeleteElement(id)) + .Callback(() => { flag = true; }); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]); + + // Act + _pekarBusinessLogicContract.DeletePekar(id); + + // Assert + _pekarStorageContact.Verify(x => x.DeleteElement(id), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(pekar.Id, out _), Is.True); + Assert.That(!pekar.FIO.IsEmpty()); + Assert.That(Regex.IsMatch(pekar.FIO, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(!pekar.Position.IsEmpty()); + Assert.That(pekar.BonusCoefficient > 0); + } + + [Test] + public void DeletePekar_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.DeletePekar(id), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void DeletePekar_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.DeletePekar(null), Throws.TypeOf()); + Assert.That(() => _pekarBusinessLogicContract.DeletePekar(string.Empty), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny().Id), Times.Never); + } + + [Test] + public void DeletePekar_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.DeletePekar("invalid"), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny().Id), Times.Never); + } + + [Test] + public void DeletePekar_StorageThrowError_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.DeleteElement(It.IsAny().Id)) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.DeletePekar(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny().Id), Times.Once); + } + + [Test] + public void RestorePekar_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var pekar = new PekarDataModel( + id, + "Ivan Ivanov", + "Baker", + 1.5m, + new List + { + new ProductDataModel( + productId, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ) + } + ); + var flag = false; + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar); + _pekarStorageContact.Setup(x => x.RestoreElement(id)) + .Callback(() => { flag = true; }); + _productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]); + + // Act + _pekarBusinessLogicContract.RestorePekar(id); + + // Assert + _pekarStorageContact.Verify(x => x.RestoreElement(id), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(pekar.Id, out _), Is.True); + Assert.That(!pekar.FIO.IsEmpty()); + Assert.That(Regex.IsMatch(pekar.FIO, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(!pekar.Position.IsEmpty()); + Assert.That(pekar.BonusCoefficient > 0); + } + + [Test] + public void RestorePekar_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.RestorePekar(id), Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void RestorePekar_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.RestorePekar(null), Throws.TypeOf()); + Assert.That(() => _pekarBusinessLogicContract.RestorePekar(string.Empty), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny().Id), Times.Never); + } + + [Test] + public void RestorePekar_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.RestorePekar("invalid"), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny().Id), Times.Never); + } + + [Test] + public void RestorePekar_StorageThrowError_ThrowException_Test() + { + // Arrange + _pekarStorageContact.Setup(x => x.RestoreElement(It.IsAny().Id)) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _pekarBusinessLogicContract.RestorePekar(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny().Id), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PositionBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PositionBusinessLogicContractTests.cs new file mode 100644 index 0000000..0a2852b --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/PositionBusinessLogicContractTests.cs @@ -0,0 +1,413 @@ +using Moq; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using CandyHouseBase.DataModels; +using CandyHouseBase.Enums; +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 PositionBusinessLogicContractTests + { + private PositionBusinessLogicContract _positionBusinessLogicContract; + private Mock _positionStorageContact; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _positionStorageContact = new Mock(); + _positionBusinessLogicContract = new PositionBusinessLogicContract( + _positionStorageContact.Object, + new Mock().Object + ); + } + + [SetUp] + public void SetUp() + { + _positionStorageContact.Reset(); + } + + [Test] + public void GetAllPositions_ReturnsListOfRecords_Test() + { + // Arrange + var positions = new List + { + new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ), + new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Medium, + "Pastry Chef" + ) + }; + _positionStorageContact.Setup(x => x.GetList()).Returns(positions); + + // Act + var list = _positionBusinessLogicContract.GetAllPositions(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Is.EquivalentTo(positions)); + Assert.That( + list.All(p => + Guid.TryParse(p.Id, out _) && !p.Title.IsEmpty() && Enum.IsDefined(typeof(PositionType), p.Type)), + Is.True); + } + + [Test] + public void GetAllPositions_ReturnsEmptyList_Test() + { + // Arrange + _positionStorageContact.Setup(x => x.GetList()).Returns(new List()); + + // Act + var list = _positionBusinessLogicContract.GetAllPositions(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(0)); + _positionStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllPositions_ReturnsNull_ThrowException_Test() + { + // Arrange + _positionStorageContact.Setup(x => x.GetList()).Returns((List)null); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.GetAllPositions(), Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllPositions_StorageThrowError_ThrowException_Test() + { + // Arrange + _positionStorageContact.Setup(x => x.GetList()) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.GetAllPositions(), Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetPositionByData_ReturnsPositionById_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var position = new PositionDataModel( + id, + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position); + + // Act + var element = _positionBusinessLogicContract.GetPositionByData(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.Title.IsEmpty()); + Assert.That(Regex.IsMatch(element.Title, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(Enum.IsDefined(typeof(PositionType), element.Type), Is.True); + _positionStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetPositionByData_EmptyData_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.GetPositionByData(null), + Throws.TypeOf()); + Assert.That(() => _positionBusinessLogicContract.GetPositionByData(string.Empty), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); + } + + [Test] + public void GetPositionByData_NotFoundPosition_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _positionStorageContact.Setup(x => x.GetElementById(id)).Returns((PositionDataModel)null); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.GetPositionByData(id), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetPositionByData_StorageThrowError_ThrowException_Test() + { + // Arrange + _positionStorageContact.Setup(x => x.GetElementById(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.GetPositionByData(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void InsertPosition_CorrectRecord_Test() + { + // Arrange + var flag = false; + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((PositionDataModel x) => + { + flag = x.Id == position.Id && x.Type == position.Type && x.Title == position.Title; + }); + + // Act + _positionBusinessLogicContract.InsertPosition(position); + + // Assert + _positionStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(position.Id, out _), Is.True); + Assert.That(!position.Title.IsEmpty()); + Assert.That(Regex.IsMatch(position.Title, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(Enum.IsDefined(typeof(PositionType), position.Type), Is.True); + } + + [Test] + public void InsertPosition_RecordWithExistsData_ThrowException_Test() + { + // Arrange + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new ElementExistsException("ID", position.Id)); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.InsertPosition(position), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void InsertPosition_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.InsertPosition(null), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertPosition_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.InsertPosition(new PositionDataModel( + "", + (PositionType)999, + "123" + )), Throws.TypeOf()); + _positionStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertPosition_StorageThrowError_ThrowException_Test() + { + // Arrange + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.InsertPosition(position), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdatePosition_CorrectRecord_Test() + { + // Arrange + var flag = false; + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((PositionDataModel x) => + { + flag = x.Id == position.Id && x.Type == position.Type && x.Title == position.Title; + }); + + // Act + _positionBusinessLogicContract.UpdatePosition(position); + + // Assert + _positionStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(position.Id, out _), Is.True); + Assert.That(!position.Title.IsEmpty()); + Assert.That(Regex.IsMatch(position.Title, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(Enum.IsDefined(typeof(PositionType), position.Type), Is.True); + } + + [Test] + public void UpdatePosition_RecordNotFound_ThrowException_Test() + { + // Arrange + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new ElementNotFoundException("Position not found")); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.UpdatePosition(position), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdatePosition_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.UpdatePosition(null), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdatePosition_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.UpdatePosition(new PositionDataModel( + "", // Invalid ID + (PositionType)999, + "123" + )), Throws.TypeOf()); + _positionStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdatePosition_StorageThrowError_ThrowException_Test() + { + // Arrange + var position = new PositionDataModel( + Guid.NewGuid().ToString(), + PositionType.Cool, + "Baker" + ); + _positionStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.UpdatePosition(position), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeletePosition_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var position = new PositionDataModel( + id, + PositionType.Cool, + "Baker" + ); + var flag = false; + _positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position); + _positionStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; }); + + // Act + _positionBusinessLogicContract.DeletePosition(id); + + // Assert + _positionStorageContact.Verify(x => x.DeleteElement(id), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(position.Id, out _), Is.True); + Assert.That(!position.Title.IsEmpty()); + Assert.That(Regex.IsMatch(position.Title, @"^[A-Za-zА-Яа-яЁё\s\-]+$"), Is.True); + Assert.That(Enum.IsDefined(typeof(PositionType), position.Type), Is.True); + } + + [Test] + public void DeletePosition_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _positionStorageContact.Setup(x => x.GetElementById(id)).Returns((PositionDataModel)null); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.DeletePosition(id), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void DeletePosition_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.DeletePosition(null), + Throws.TypeOf()); + Assert.That(() => _positionBusinessLogicContract.DeletePosition(string.Empty), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeletePosition_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.DeletePosition("invalid"), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeletePosition_StorageThrowError_ThrowException_Test() + { + // Arrange + _positionStorageContact.Setup(x => x.DeleteElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _positionBusinessLogicContract.DeletePosition(Guid.NewGuid().ToString()), + Throws.TypeOf()); + _positionStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/ProductBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/ProductBusinessLogicContractTests.cs new file mode 100644 index 0000000..b398607 --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/ProductBusinessLogicContractTests.cs @@ -0,0 +1,572 @@ +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 ProductBusinessLogicContractTests + { + private ProductBusinessLogicContract _productBusinessLogicContract; + private Mock _productStorageContact; + private Mock _ingredientStorageContact; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _productStorageContact = new Mock(); + _ingredientStorageContact = new Mock(); + _productBusinessLogicContract = new ProductBusinessLogicContract( + _productStorageContact.Object, + _ingredientStorageContact.Object, + new Mock().Object + ); + } + + [SetUp] + public void SetUp() + { + _productStorageContact.Reset(); + _ingredientStorageContact.Reset(); + } + + [Test] + public void GetAllProducts_ReturnsListOfRecords_Test() + { + // Arrange + var ingredientId = Guid.NewGuid().ToString(); + var product1 = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product1.Name = "Updated Cake"; + product1.Description = "Updated delicious cake"; + var product2 = new ProductDataModel( + Guid.NewGuid().ToString(), + "Pastry", + "Sweet pastry", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Flour", "kg", 200) + } + ); + product2.Name = "Updated Pastry"; + product2.Description = "Updated sweet pastry"; + var products = new List { product1, product2 }; + _productStorageContact.Setup(x => x.GetList()).Returns(products); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product1.IngredientsItems[0]); + + // Act + var list = _productBusinessLogicContract.GetAllProducts(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Is.EquivalentTo(products)); + Assert.That( + list.All(p => + Guid.TryParse(p.Id, out _) && !p.Name.IsEmpty() && !p.Description.IsEmpty() && + p.IngredientsItems.Count > 0 && !p.OldName.IsEmpty() && !p.OldDescription.IsEmpty()), Is.True); + } + + [Test] + public void GetAllProducts_ReturnsEmptyList_Test() + { + // Arrange + _productStorageContact.Setup(x => x.GetList()).Returns(new List()); + + // Act + var list = _productBusinessLogicContract.GetAllProducts(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(0)); + _productStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllProducts_ReturnsNull_ThrowException_Test() + { + // Arrange + _productStorageContact.Setup(x => x.GetList()).Returns((List)null); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.GetAllProducts(), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetAllProducts_StorageThrowError_ThrowException_Test() + { + // Arrange + _productStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.GetAllProducts(), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetProductByData_ReturnsProductById_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + id, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.GetElementById(id)).Returns(product); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]); + _productStorageContact.Setup(x => x.GetList()).Returns(new List { product }); + + // Act + var elementById = _productBusinessLogicContract.GetProductByData(id); + + // Assert + Assert.That(elementById, Is.Not.Null); + Assert.That(elementById.Id, Is.EqualTo(id)); + Assert.That(Guid.TryParse(elementById.Id, out _), Is.True); + Assert.That(elementById.Name, Is.EqualTo("Updated Cake")); + Assert.That(elementById.Description, Is.EqualTo("Updated delicious cake")); + Assert.That(elementById.IngredientsItems.Count > 0); + Assert.That(elementById.OldName, Is.EqualTo("Cake")); + Assert.That(elementById.OldDescription, Is.EqualTo("Delicious cake")); + _productStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetProductByData_ReturnsProductByName_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + id, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.GetList()).Returns(new List { product }); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]); + + // Act + var elementByName = _productBusinessLogicContract.GetProductByData("Updated Cake"); + + // Assert + Assert.That(elementByName, Is.Not.Null); + Assert.That(elementByName.Id, Is.EqualTo(id)); + Assert.That(Guid.TryParse(elementByName.Id, out _), Is.True); + Assert.That(elementByName.Name, Is.EqualTo("Updated Cake")); + Assert.That(elementByName.Description, Is.EqualTo("Updated delicious cake")); + Assert.That(elementByName.IngredientsItems.Count > 0); + Assert.That(elementByName.OldName, Is.EqualTo("Cake")); + Assert.That(elementByName.OldDescription, Is.EqualTo("Delicious cake")); + _productStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetProductByData_ReturnsProductByOldName_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var ingredientId = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + id, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.GetList()).Returns(new List { product }); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]); + + // Act + var elementByOldName = _productBusinessLogicContract.GetProductByData("Cake"); + + // Assert + Assert.That(elementByOldName, Is.Not.Null); + Assert.That(elementByOldName.Id, Is.EqualTo(id)); + Assert.That(Guid.TryParse(elementByOldName.Id, out _), Is.True); + Assert.That(elementByOldName.Name, Is.EqualTo("Updated Cake")); + Assert.That(elementByOldName.Description, Is.EqualTo("Updated delicious cake")); + Assert.That(elementByOldName.IngredientsItems.Count > 0); + Assert.That(elementByOldName.OldName, Is.EqualTo("Cake")); + Assert.That(elementByOldName.OldDescription, Is.EqualTo("Delicious cake")); + _productStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetProductByData_EmptyData_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.GetProductByData(null), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.GetProductByData(string.Empty), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); + _productStorageContact.Verify(x => x.GetList(), Times.Never); + } + + [Test] + public void GetProductByData_NotFoundProduct_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _productStorageContact.Setup(x => x.GetElementById(id)).Returns((ProductDataModel)null); + _productStorageContact.Setup(x => x.GetList()).Returns(new List()); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.GetProductByData(id), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.GetProductByData("NonExistentProduct"), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.GetProductByData("OldNonExistent"), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + _productStorageContact.Verify(x => x.GetList(), Times.AtLeast(2)); + } + + [Test] + public void GetProductByData_StorageThrowError_ThrowException_Test() + { + // Arrange + _productStorageContact.Setup(x => x.GetElementById(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + _productStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.GetProductByData(Guid.NewGuid().ToString()), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.GetProductByData("Cake"), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.GetProductByData("OldCake"), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + _productStorageContact.Verify(x => x.GetList(), Times.AtLeast(2)); + } + + [Test] + public void InsertProduct_CorrectRecord_Test() + { + // Arrange + var ingredientId = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + var flag = false; + _productStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((ProductDataModel x) => + { + flag = x.Id == product.Id && x.Name == product.Name && x.Description == product.Description && + x.IngredientsItems.SequenceEqual(product.IngredientsItems) && + x.OldName == product.OldName && x.OldDescription == product.OldDescription; + }); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]); + + // Act + _productBusinessLogicContract.InsertProduct(product); + + // Assert + _productStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(product.Id, out _), Is.True); + Assert.That(!product.Name.IsEmpty()); + Assert.That(!product.Description.IsEmpty()); + Assert.That(product.IngredientsItems.Count > 0); + Assert.That( + product.IngredientsItems.All(i => + Guid.TryParse(i.Id, out _) && !i.Name.IsEmpty() && !i.Unit.IsEmpty() && i.Cost >= 0), Is.True); + Assert.That(product.OldName, Is.EqualTo("Cake")); + Assert.That(product.OldDescription, Is.EqualTo("Delicious cake")); + } + + [Test] + public void InsertProduct_RecordWithExistsData_ThrowException_Test() + { + // Arrange + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new ElementExistsException("ID", product.Id)); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.InsertProduct(product), Throws.TypeOf()); + _productStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void InsertProduct_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.InsertProduct(null), Throws.TypeOf()); + _productStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertProduct_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.InsertProduct(new ProductDataModel( + "", + "", + "", + new List + { + new IngredientDataModel("", "", "", -100) + } + )), Throws.TypeOf()); + _productStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void InsertProduct_StorageThrowError_ThrowException_Test() + { + // Arrange + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.InsertProduct(product), Throws.TypeOf()); + _productStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateProduct_CorrectRecord_Test() + { + // Arrange + var ingredientId = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(ingredientId, "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + var flag = false; + _productStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((ProductDataModel x) => + { + flag = x.Id == product.Id && x.Name == product.Name && x.Description == product.Description && + x.IngredientsItems.SequenceEqual(product.IngredientsItems) && + x.OldName == product.OldName && x.OldDescription == product.OldDescription; + }); + _ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]); + + // Act + _productBusinessLogicContract.UpdateProduct(product); + + // Assert + _productStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(product.Id, out _), Is.True); + Assert.That(!product.Name.IsEmpty()); + Assert.That(!product.Description.IsEmpty()); + Assert.That(product.IngredientsItems.Count > 0); + Assert.That( + product.IngredientsItems.All(i => + Guid.TryParse(i.Id, out _) && !i.Name.IsEmpty() && !i.Unit.IsEmpty() && i.Cost >= 0), Is.True); + Assert.That(product.OldName, Is.EqualTo("Cake")); + Assert.That(product.OldDescription, Is.EqualTo("Delicious cake")); + } + + [Test] + public void UpdateProduct_RecordNotFound_ThrowException_Test() + { + // Arrange + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new ElementNotFoundException("Product not found")); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.UpdateProduct(product), Throws.TypeOf()); + _productStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateProduct_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.UpdateProduct(null), Throws.TypeOf()); + _productStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateProduct_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.UpdateProduct(new ProductDataModel( + "", + "", + "", + new List + { + new IngredientDataModel("", "", "", -100) + } + )), Throws.TypeOf()); + _productStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateProduct_StorageThrowError_ThrowException_Test() + { + // Arrange + var product = new ProductDataModel( + Guid.NewGuid().ToString(), + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + _productStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.UpdateProduct(product), Throws.TypeOf()); + _productStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteProduct_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var product = new ProductDataModel( + id, + "Cake", + "Delicious cake", + new List + { + new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100) + } + ); + product.Name = "Updated Cake"; + product.Description = "Updated delicious cake"; + var flag = false; + _productStorageContact.Setup(x => x.GetElementById(id)).Returns(product); + _productStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; }); + + // Act + _productBusinessLogicContract.DeleteProduct(id); + + // Assert + _productStorageContact.Verify(x => x.DeleteElement(id), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(product.Id, out _), Is.True); + Assert.That(!product.Name.IsEmpty()); + Assert.That(!product.Description.IsEmpty()); + Assert.That(product.IngredientsItems.Count > 0); + Assert.That( + product.IngredientsItems.All(i => + Guid.TryParse(i.Id, out _) && !i.Name.IsEmpty() && !i.Unit.IsEmpty() && i.Cost >= 0), Is.True); + Assert.That(product.OldName, Is.EqualTo("Cake")); + Assert.That(product.OldDescription, Is.EqualTo("Delicious cake")); + } + + [Test] + public void DeleteProduct_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _productStorageContact.Setup(x => x.GetElementById(id)).Returns((ProductDataModel)null); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.DeleteProduct(id), Throws.TypeOf()); + _productStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteProduct_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.DeleteProduct(null), Throws.TypeOf()); + Assert.That(() => _productBusinessLogicContract.DeleteProduct(string.Empty), Throws.TypeOf()); + _productStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteProduct_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _productBusinessLogicContract.DeleteProduct("invalid"), Throws.TypeOf()); + _productStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteProduct_StorageThrowError_ThrowException_Test() + { + // Arrange + _productStorageContact.Setup(x => x.DeleteElement(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _productBusinessLogicContract.DeleteProduct(Guid.NewGuid().ToString()), Throws.TypeOf()); + _productStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/SalaryBusinessLogicContractTests.cs b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/SalaryBusinessLogicContractTests.cs new file mode 100644 index 0000000..ca4fbca --- /dev/null +++ b/CandyHouseSolution/CandyHouseTests/BusinessLogicsContractsTests/SalaryBusinessLogicContractTests.cs @@ -0,0 +1,442 @@ +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 SalaryBusinessLogicContractTests + { + private SalaryBusinessLogicContract _salaryBusinessLogicContract; + private Mock _salaryStorageContact; + private Mock _pekarStorageContact; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + _salaryStorageContact = new Mock(); + _pekarStorageContact = new Mock(); + _salaryBusinessLogicContract = new SalaryBusinessLogicContract( + _salaryStorageContact.Object, + _pekarStorageContact.Object, + new Mock().Object + ); + } + + [SetUp] + public void SetUp() + { + _salaryStorageContact.Reset(); + _pekarStorageContact.Reset(); + } + + [Test] + public void GetList_ReturnsListOfRecords_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var salaries = new List + { + new SalaryDataModel( + Guid.NewGuid().ToString(), + pekarId, + DateTime.Now.AddMonths(-1), + 1000.00m, + 200.00m, + 1200.00m + ), + new SalaryDataModel( + Guid.NewGuid().ToString(), + pekarId, + DateTime.Now, + 1500.00m, + 300.00m, + 1800.00m + ) + }; + _salaryStorageContact.Setup(x => x.GetList()).Returns(salaries); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + + // Act + var list = _salaryBusinessLogicContract.GetList(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Is.EquivalentTo(salaries)); + Assert.That(list.All(s => Guid.TryParse(s.Id, out _) && Guid.TryParse(s.PekarId, out _) && s.BaseRate >= 0 && s.BonusRate >= 0 && s.TotalSalary >= 0), Is.True); + } + + [Test] + public void GetList_ReturnsEmptyList_Test() + { + // Arrange + _salaryStorageContact.Setup(x => x.GetList()).Returns(new List()); + + // Act + var list = _salaryBusinessLogicContract.GetList(); + + // Assert + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(0)); + _salaryStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetList_ReturnsNull_ThrowException_Test() + { + // Arrange + _salaryStorageContact.Setup(x => x.GetList()).Returns((List)null); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.GetList(), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetList_StorageThrowError_ThrowException_Test() + { + // Arrange + _salaryStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.GetList(), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetList(), Times.Once); + } + + [Test] + public void GetElementById_ReturnsSalaryById_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var pekarId = Guid.NewGuid().ToString(); + var salary = new SalaryDataModel( + id, + pekarId, + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + + // Act + var element = _salaryBusinessLogicContract.GetElementById(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(Guid.TryParse(element.PekarId, out _), Is.True); + Assert.That(element.BaseRate >= 0); + Assert.That(element.BonusRate >= 0); + Assert.That(element.TotalSalary >= 0); + _salaryStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetElementById_EmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.GetElementById(null), Throws.TypeOf()); + Assert.That(() => _salaryBusinessLogicContract.GetElementById(string.Empty), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Never); + } + + [Test] + public void GetElementById_NotFoundSalary_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.GetElementById(id), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void GetElementById_StorageThrowError_ThrowException_Test() + { + // Arrange + _salaryStorageContact.Setup(x => x.GetElementById(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.GetElementById(Guid.NewGuid().ToString()), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void AddElement_CorrectRecord_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var flag = false; + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + pekarId, + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.AddElement(It.IsAny())) + .Callback((SalaryDataModel x) => + { + flag = x.Id == salary.Id && x.PekarId == salary.PekarId && x.Period == salary.Period && + x.BaseRate == salary.BaseRate && x.BonusRate == salary.BonusRate && x.TotalSalary == salary.TotalSalary; + }); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + + // Act + _salaryBusinessLogicContract.AddElement(salary); + + // Assert + _salaryStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(salary.Id, out _), Is.True); + Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True); + Assert.That(salary.BaseRate >= 0); + Assert.That(salary.BonusRate >= 0); + Assert.That(salary.TotalSalary >= 0); + } + + [Test] + public void AddElement_RecordWithExistsData_ThrowException_Test() + { + // Arrange + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.AddElement(It.IsAny())).Throws(new ElementExistsException("ID", salary.Id)); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.AddElement(salary), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void AddElement_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.AddElement(null), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void AddElement_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.AddElement(new SalaryDataModel( + "", + "", + DateTime.Now, + -1000.00m, + -200.00m, + -1200.00m + )), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Never); + } + + [Test] + public void AddElement_StorageThrowError_ThrowException_Test() + { + // Arrange + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.AddElement(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.AddElement(salary), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.AddElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateElement_CorrectRecord_Test() + { + // Arrange + var pekarId = Guid.NewGuid().ToString(); + var flag = false; + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + pekarId, + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny())) + .Callback((SalaryDataModel x) => + { + flag = x.Id == salary.Id && x.PekarId == salary.PekarId && x.Period == salary.Period && + x.BaseRate == salary.BaseRate && x.BonusRate == salary.BonusRate && x.TotalSalary == salary.TotalSalary; + }); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + + // Act + _salaryBusinessLogicContract.UpdateElement(salary); + + // Assert + _salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(salary.Id, out _), Is.True); + Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True); + Assert.That(salary.BaseRate >= 0); + Assert.That(salary.BonusRate >= 0); + Assert.That(salary.TotalSalary >= 0); + } + + [Test] + public void UpdateElement_RecordNotFound_ThrowException_Test() + { + // Arrange + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny())).Throws(new ElementNotFoundException("Salary not found")); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.UpdateElement(salary), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void UpdateElement_NullRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.UpdateElement(null), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateElement_InvalidRecord_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.UpdateElement(new SalaryDataModel( + "", + "", + DateTime.Now, + -1000.00m, + -200.00m, + -1200.00m + )), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Never); + } + + [Test] + public void UpdateElement_StorageThrowError_ThrowException_Test() + { + // Arrange + var salary = new SalaryDataModel( + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString(), + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + _salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.UpdateElement(salary), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteElement_CorrectId_Test() + { + // Arrange + var id = Guid.NewGuid().ToString(); + var pekarId = Guid.NewGuid().ToString(); + var salary = new SalaryDataModel( + id, + pekarId, + DateTime.Now, + 1000.00m, + 200.00m, + 1200.00m + ); + var flag = false; + _salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary); + _salaryStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; }); + _pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List())); + + // Act + _salaryBusinessLogicContract.DeleteElement(id); + + // Assert + _salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Once); + Assert.That(flag); + Assert.That(Guid.TryParse(salary.Id, out _), Is.True); + Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True); + Assert.That(salary.BaseRate >= 0); + Assert.That(salary.BonusRate >= 0); + Assert.That(salary.TotalSalary >= 0); + } + + [Test] + public void DeleteElement_RecordNotFound_ThrowException_Test() + { + // Arrange + var id = "nonexistent"; + _salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.DeleteElement(id), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.GetElementById(It.IsAny()), Times.Once); + } + + [Test] + public void DeleteElement_NullOrEmptyId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.DeleteElement(null), Throws.TypeOf()); + Assert.That(() => _salaryBusinessLogicContract.DeleteElement(string.Empty), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteElement_InvalidId_ThrowException_Test() + { + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.DeleteElement("invalid"), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Never); + } + + [Test] + public void DeleteElement_StorageThrowError_ThrowException_Test() + { + // Arrange + _salaryStorageContact.Setup(x => x.DeleteElement(It.IsAny())).Throws(new StorageException(new InvalidOperationException())); + + // Act & Assert + Assert.That(() => _salaryBusinessLogicContract.DeleteElement(Guid.NewGuid().ToString()), Throws.TypeOf()); + _salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny()), Times.Once); + } + } +} \ No newline at end of file diff --git a/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj b/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj index 760ff16..df79a78 100644 --- a/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj +++ b/CandyHouseSolution/CandyHouseTests/CandyHouseTests.csproj @@ -16,6 +16,7 @@ CandyHouseTests v4.7.1 512 + latest AnyCPU @@ -37,10 +38,34 @@ 4 + + ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll + ..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Logging.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Options.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Primitives.dll + ..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll @@ -65,42 +90,58 @@ ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll + + ..\packages\Moq.4.20.72\lib\net462\Moq.dll + - - ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll ..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll + - - ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + ..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.1.25080.5\lib\net462\System.Diagnostics.DiagnosticSource.dll - - ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll ..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + ..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll + + + + + + @@ -120,6 +161,9 @@ CandyHouseBase + + + diff --git a/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs b/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs index 2e4a46a..a99eb6b 100644 --- a/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs +++ b/CandyHouseSolution/CandyHouseTests/DataModelsTests/OrderDataModelTests.cs @@ -17,18 +17,19 @@ namespace CandyHouseTests.DataModelsTests var orderDate = DateTime.Now; var totalAmount = 100.0m; var discountAmount = 10.0m; - var orderId = Guid.NewGuid().ToString(); + var productId = Guid.NewGuid().ToString(); var pekarId = Guid.NewGuid().ToString(); var statusType = StatusType.Pending; - var order = new OrderDataModel(id, customerName, orderDate, totalAmount, discountAmount, orderId, pekarId, statusType); + var order = new OrderDataModel(id, customerName, orderDate, totalAmount, discountAmount, productId, pekarId, + statusType); Assert.AreEqual(id, order.Id); Assert.AreEqual(customerName, order.CustomerName); Assert.AreEqual(orderDate, order.OrderDate); Assert.AreEqual(totalAmount, order.TotalAmount); Assert.AreEqual(discountAmount, order.DiscountAmount); - Assert.AreEqual(orderId, order.OrderId); + Assert.AreEqual(productId, order.ProductId); Assert.AreEqual(pekarId, order.PekarId); Assert.AreEqual(statusType, order.StatusType); } diff --git a/CandyHouseSolution/CandyHouseTests/packages.config b/CandyHouseSolution/CandyHouseTests/packages.config index f1136e5..2778040 100644 --- a/CandyHouseSolution/CandyHouseTests/packages.config +++ b/CandyHouseSolution/CandyHouseTests/packages.config @@ -1,6 +1,16 @@  + + + + + + + + + + @@ -9,11 +19,12 @@ - + - - - + + - + + + \ No newline at end of file