Compare commits
2 Commits
lab-3-hard
...
lab-3
| Author | SHA1 | Date | |
|---|---|---|---|
| d2f7afae63 | |||
| b7c31860e1 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -414,3 +414,4 @@ FodyWeavers.xsd
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
/.idea/
|
||||
|
||||
@@ -1,97 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"
|
||||
Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{5DF70B46-31F7-4D15-8C60-52C0A0A364F0}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CandyHouseBase</RootNamespace>
|
||||
<AssemblyName>CandyHouseBase</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<LangVersion>12</LangVersion>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Options, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Options.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Options.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Primitives, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.20.72.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.20.72\lib\net462\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System"/>
|
||||
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core"/>
|
||||
<Reference Include="System.Data"/>
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.1.25080.5\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="DataModels\IngredientDataModel.cs" />
|
||||
@@ -105,19 +20,21 @@
|
||||
<Compile Include="Enums\PositionType.cs" />
|
||||
<Compile Include="Enums\StatusType.cs" />
|
||||
<Compile Include="Exceptions\DateTimeExtensions.cs" />
|
||||
<Compile Include="Exceptions\ElementDeletedException.cs" />
|
||||
<Compile Include="Exceptions\ElementExistsException.cs" />
|
||||
<Compile Include="Exceptions\ElementNotFoundException.cs" />
|
||||
<Compile Include="Exceptions\IncorrectDatesException.cs" />
|
||||
<Compile Include="Exceptions\NullListException.cs" />
|
||||
<Compile Include="Exceptions\StorageException.cs" />
|
||||
<Compile Include="Exceptions\StringExtensions.cs" />
|
||||
<Compile Include="Exceptions\ValidationException.cs" />
|
||||
<Compile Include="Extensions\StringExtensions.cs" />
|
||||
<Compile Include="Implementations\IngredientBusinessLogicContract.cs" />
|
||||
<Compile Include="Implementations\OrderBusinessLogicContract.cs" />
|
||||
<Compile Include="Implementations\PekarBusinessLogicContract.cs" />
|
||||
<Compile Include="Implementations\PositionBusinessLogicContract.cs" />
|
||||
<Compile Include="Implementations\ProductBusinessLogicContract.cs" />
|
||||
<Compile Include="Implementations\SalaryBusinessLogicContract.cs" />
|
||||
<Compile Include="Infrastructure\Infrastructure.cs" />
|
||||
<Compile Include="Infrastructure\IValidation.cs" />
|
||||
<Compile Include="Interfaces\BusinessLogicsContracts\IIngredientBusinessLogicContact.cs" />
|
||||
<Compile Include="Interfaces\BusinessLogicsContracts\IOrderBusinessLogicContact.cs" />
|
||||
@@ -131,30 +48,25 @@
|
||||
<Compile Include="Interfaces\StoragesContracts\IPositionStorageContact.cs" />
|
||||
<Compile Include="Interfaces\StoragesContracts\IProductStorageContact.cs" />
|
||||
<Compile Include="Interfaces\StoragesContracts\ISalaryStorageContact.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="CatHasPawsTests" />
|
||||
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="ILLink\ILLink.Descriptors.LibraryBuild.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>$(AssemblyName).Test.dll</_Parameter1>
|
||||
<_Parameter1>CandyHouseTests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-preview.1.25080.5" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -12,9 +12,13 @@ namespace CandyHouseBase.DataModels
|
||||
public string FIO { get; private set; }
|
||||
public string Position { get; private set; }
|
||||
public decimal BonusCoefficient { get; private set; }
|
||||
public bool IsDeleted { get; private set; }
|
||||
public List<ProductDataModel> ProductsItems { get; private set; }
|
||||
|
||||
|
||||
|
||||
public PekarDataModel()
|
||||
{
|
||||
ProductsItems = new List<ProductDataModel>();
|
||||
}
|
||||
public PekarDataModel(string id, string fio, string position, decimal bonusCoefficient,
|
||||
List<ProductDataModel> productsItems)
|
||||
{
|
||||
|
||||
@@ -29,15 +29,20 @@ namespace CandyHouseBase.DataModels
|
||||
}
|
||||
}
|
||||
|
||||
public string OldName { get; private set; }
|
||||
public string? OldName { get; private set; }
|
||||
|
||||
public string OldDescription { get; private set; }
|
||||
public string? OldDescription { get; private set; }
|
||||
|
||||
private string name;
|
||||
private string description;
|
||||
|
||||
public List<IngredientDataModel> IngredientsItems { get; private set; }
|
||||
|
||||
public ProductDataModel()
|
||||
{
|
||||
IngredientsItems = new List<IngredientDataModel>();
|
||||
}
|
||||
|
||||
public ProductDataModel(string id, string name, string description, List<IngredientDataModel> ingredients)
|
||||
{
|
||||
Id = id;
|
||||
@@ -46,6 +51,17 @@ namespace CandyHouseBase.DataModels
|
||||
IngredientsItems = ingredients;
|
||||
}
|
||||
|
||||
public ProductDataModel(string id, string name, string description, string oldName, string oldDescription,
|
||||
List<IngredientDataModel> ingredients)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Description = description;
|
||||
IngredientsItems = ingredients;
|
||||
OldName = oldName;
|
||||
OldDescription = oldDescription;
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace CandyHouseBase.Exceptions;
|
||||
|
||||
public class ElementDeletedException(string id) : Exception($"Cannot modify a deleted item (id: {id})");
|
||||
@@ -2,10 +2,4 @@ using System;
|
||||
|
||||
namespace CandyHouseBase.Exceptions;
|
||||
|
||||
public class StorageException : Exception
|
||||
|
||||
{
|
||||
public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
public class StorageException(Exception ex) : Exception($"Error while working in storage: {ex.Message}", ex);
|
||||
@@ -1,5 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -16,24 +20,67 @@ namespace CandyHouseBase.Implementations
|
||||
|
||||
public List<IngredientDataModel> GetAllIngredients()
|
||||
{
|
||||
return new List<IngredientDataModel>();
|
||||
_logger.LogInformation("GetAllIngredients");
|
||||
var ingredients = _ingredientStorageContact.GetList() ?? throw new NullListException();
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
public IngredientDataModel GetIngredientByData(string data)
|
||||
{
|
||||
return new IngredientDataModel("", "", "", 100);
|
||||
_logger.LogInformation("GetIngredientByData for data: {data}", data);
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (string.IsNullOrEmpty(data))
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (data.IsGuid())
|
||||
{
|
||||
var ingredient = _ingredientStorageContact.GetElementById(data);
|
||||
if (ingredient == null)
|
||||
throw new ElementNotFoundException(data);
|
||||
return ingredient;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ingredient = _ingredientStorageContact.GetElementByName(data);
|
||||
if (ingredient == null)
|
||||
throw new ElementNotFoundException(data);
|
||||
return ingredient;
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertIngredient(IngredientDataModel ingredient)
|
||||
{
|
||||
_logger.LogInformation("InsertIngredient: {json}", JsonSerializer.Serialize(ingredient));
|
||||
if (ingredient == null)
|
||||
throw new ArgumentNullException(nameof(ingredient));
|
||||
ingredient.Validate();
|
||||
_ingredientStorageContact.AddElement(ingredient);
|
||||
}
|
||||
|
||||
public void UpdateIngredient(IngredientDataModel ingredient)
|
||||
{
|
||||
_logger.LogInformation("UpdateIngredient: {json}", JsonSerializer.Serialize(ingredient));
|
||||
if (ingredient == null)
|
||||
throw new ArgumentNullException(nameof(ingredient));
|
||||
ingredient.Validate();
|
||||
_ingredientStorageContact.UpdateElement(ingredient);
|
||||
}
|
||||
|
||||
public void DeleteIngredient(string id)
|
||||
{
|
||||
_logger.LogInformation("DeleteIngredient for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var ingredient = _ingredientStorageContact.GetElementById(id);
|
||||
if (ingredient == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
_ingredientStorageContact.DeleteElement(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -22,25 +25,102 @@ namespace CandyHouseBase.Implementations
|
||||
|
||||
public List<OrderDataModel> GetAllOrders()
|
||||
{
|
||||
return new List<OrderDataModel>();
|
||||
_logger.LogInformation("GetAllOrders");
|
||||
var orders = _orderStorageContact.GetOrders() ?? throw new NullListException();
|
||||
return orders;
|
||||
}
|
||||
|
||||
public OrderDataModel GetOrderByData(string data)
|
||||
{
|
||||
return new OrderDataModel("", "", new DateTime(),
|
||||
100, 100m, "", "", StatusType.Cancelled);
|
||||
_logger.LogInformation("GetOrderByData for data: {data}", data);
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (string.IsNullOrEmpty(data))
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (!data.IsGuid())
|
||||
throw new ValidationException("data must be a GUID");
|
||||
|
||||
var order = _orderStorageContact.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||
return order;
|
||||
}
|
||||
|
||||
public void InsertOrder(OrderDataModel order)
|
||||
{
|
||||
_logger.LogInformation("InsertOrder: {json}", JsonSerializer.Serialize(order));
|
||||
if (order == null)
|
||||
throw new ArgumentNullException(nameof(order));
|
||||
order.Validate();
|
||||
|
||||
// Check if Pekar exists
|
||||
if (_pekarStorageContact.GetElementById(order.PekarId) == null)
|
||||
throw new ElementNotFoundException(order.PekarId);
|
||||
|
||||
// Check if Product exists
|
||||
if (_productStorageContact.GetElementById(order.ProductId) == null)
|
||||
throw new ElementNotFoundException(order.ProductId);
|
||||
|
||||
// Check if order with this ID already exists
|
||||
var existingOrder = _orderStorageContact.GetElementById(order.Id);
|
||||
if (existingOrder != null)
|
||||
throw new ElementExistsException("ID", order.Id);
|
||||
|
||||
try
|
||||
{
|
||||
_orderStorageContact.AddElement(order);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateOrder(OrderDataModel order)
|
||||
{
|
||||
_logger.LogInformation("UpdateOrder: {json}", JsonSerializer.Serialize(order));
|
||||
if (order == null)
|
||||
throw new ArgumentNullException(nameof(order));
|
||||
order.Validate();
|
||||
|
||||
// Check if Pekar exists
|
||||
if (_pekarStorageContact.GetElementById(order.PekarId) == null)
|
||||
throw new ElementNotFoundException(order.PekarId);
|
||||
|
||||
// Check if Product exists
|
||||
if (_productStorageContact.GetElementById(order.ProductId) == null)
|
||||
throw new ElementNotFoundException(order.ProductId);
|
||||
|
||||
try
|
||||
{
|
||||
_orderStorageContact.UpdateElement(order);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteOrder(string id)
|
||||
{
|
||||
_logger.LogInformation("DeleteOrder for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var order = _orderStorageContact.GetElementById(id);
|
||||
if (order == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
try
|
||||
{
|
||||
_orderStorageContact.DeleteElement(order);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -22,34 +27,148 @@ namespace CandyHouseBase.Implementations
|
||||
|
||||
public List<PekarDataModel> GetAllPekars()
|
||||
{
|
||||
return new List<PekarDataModel>();
|
||||
_logger.LogInformation("GetAllPekars");
|
||||
var pekars = _pekarStorageContact.GetList() ?? throw new NullListException();
|
||||
return pekars;
|
||||
}
|
||||
|
||||
public List<PekarDataModel> GetAllDataOfPekar(string pekarId)
|
||||
{
|
||||
return new List<PekarDataModel>();
|
||||
_logger.LogInformation("GetAllDataOfPekar for pekarId: {pekarId}", pekarId);
|
||||
if (pekarId.IsEmpty())
|
||||
throw new ArgumentNullException(nameof(pekarId));
|
||||
if (!pekarId.IsGuid())
|
||||
throw new ValidationException("pekarId must be a GUID");
|
||||
|
||||
var pekarsWithHistory = _pekarStorageContact.GetPekarWithHistory(pekarId);
|
||||
if (pekarsWithHistory == null || !pekarsWithHistory.Any())
|
||||
throw new ElementNotFoundException(pekarId);
|
||||
|
||||
var historyRecords = new List<PekarDataModel>();
|
||||
foreach (var pekar in pekarsWithHistory)
|
||||
{
|
||||
Guid positionGuid;
|
||||
if (!Guid.TryParse(pekar.Position, out positionGuid))
|
||||
{
|
||||
_logger.LogWarning("Invalid Position GUID: {Position}", pekar.Position);
|
||||
continue;
|
||||
}
|
||||
|
||||
var position = _positionStorageContact.GetElementById(positionGuid.ToString());
|
||||
if (position == null)
|
||||
throw new ElementNotFoundException(pekar.Position);
|
||||
historyRecords.Add(new PekarDataModel(pekar.Id, pekar.FIO, position.Id, pekar.BonusCoefficient,
|
||||
new List<ProductDataModel>()));
|
||||
}
|
||||
|
||||
if (!historyRecords.Any())
|
||||
{
|
||||
var firstPekar = pekarsWithHistory.First();
|
||||
Guid positionGuid;
|
||||
if (Guid.TryParse(firstPekar.Position, out positionGuid))
|
||||
{
|
||||
var position = _positionStorageContact.GetElementById(positionGuid.ToString());
|
||||
if (position != null)
|
||||
historyRecords.Add(new PekarDataModel(firstPekar.Id, firstPekar.FIO, position.Id,
|
||||
firstPekar.BonusCoefficient,
|
||||
new List<ProductDataModel>()));
|
||||
}
|
||||
}
|
||||
|
||||
return historyRecords;
|
||||
}
|
||||
|
||||
public PekarDataModel GetPekarByData(string data)
|
||||
{
|
||||
return new PekarDataModel("", "", "",
|
||||
0, new List<ProductDataModel>());
|
||||
_logger.LogInformation("GetPekarByData for data: {data}", data);
|
||||
if (data.IsEmpty())
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (!data.IsGuid() && !Regex.IsMatch(data, @"^[A-Za-zА-Яа-яЁё\s\-]+$"))
|
||||
throw new ValidationException("data must be a GUID or FIO");
|
||||
|
||||
var pekar = _pekarStorageContact.GetElementById(data) ?? _pekarStorageContact.GetElementByFio(data) ??
|
||||
throw new ElementNotFoundException(data);
|
||||
return pekar;
|
||||
}
|
||||
|
||||
public void InsertPekar(PekarDataModel order)
|
||||
public void InsertPekar(PekarDataModel pekar)
|
||||
{
|
||||
_logger.LogInformation("InsertPekar: {json}", JsonSerializer.Serialize(pekar));
|
||||
if (pekar == null)
|
||||
throw new ArgumentNullException(nameof(pekar));
|
||||
|
||||
pekar.Validate();
|
||||
|
||||
var existingPekar = _pekarStorageContact.GetElementById(pekar.Id);
|
||||
if (existingPekar != null)
|
||||
{
|
||||
var history = new PekarHistoryDataModel(
|
||||
existingPekar.Id,
|
||||
existingPekar.FIO,
|
||||
existingPekar.Position,
|
||||
existingPekar.BonusCoefficient,
|
||||
DateTime.Now
|
||||
);
|
||||
}
|
||||
|
||||
foreach (var product in pekar.ProductsItems)
|
||||
{
|
||||
if (_productStorageContact.GetElementById(product.Id) == null)
|
||||
throw new ElementNotFoundException(product.Id);
|
||||
}
|
||||
|
||||
_pekarStorageContact.AddElement(pekar);
|
||||
}
|
||||
|
||||
public void UpdatePekar(PekarDataModel order)
|
||||
public void UpdatePekar(PekarDataModel pekar)
|
||||
{
|
||||
_logger.LogInformation("UpdatePekar: {json}", JsonSerializer.Serialize(pekar));
|
||||
if (pekar == null)
|
||||
throw new ArgumentNullException(nameof(pekar));
|
||||
|
||||
pekar.Validate();
|
||||
|
||||
foreach (var product in pekar.ProductsItems)
|
||||
{
|
||||
if (_productStorageContact.GetElementById(product.Id) == null)
|
||||
throw new ElementNotFoundException(product.Id);
|
||||
}
|
||||
|
||||
_pekarStorageContact.UpdateElement(pekar);
|
||||
}
|
||||
|
||||
public void DeletePekar(string id)
|
||||
{
|
||||
_logger.LogInformation("DeletePekar for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var pekar = _pekarStorageContact.GetElementById(id);
|
||||
if (pekar == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
_pekarStorageContact.DeleteElement(id);
|
||||
}
|
||||
|
||||
public void RestorePekar(string id)
|
||||
{
|
||||
_logger.LogInformation("RestorePekar for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var pekar = _pekarStorageContact.GetElementById(id);
|
||||
if (pekar == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
_pekarStorageContact.RestoreElement(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -18,24 +21,67 @@ namespace CandyHouseBase.Implementations
|
||||
|
||||
public List<PositionDataModel> GetAllPositions()
|
||||
{
|
||||
return new List<PositionDataModel>();
|
||||
_logger.LogInformation("GetAllPositions");
|
||||
var positions = _positionStorageContact.GetList() ?? throw new NullListException();
|
||||
return positions;
|
||||
}
|
||||
|
||||
public PositionDataModel GetPositionByData(string data)
|
||||
{
|
||||
return new PositionDataModel("", PositionType.Cool, "");
|
||||
_logger.LogInformation("GetPositionByData for data: {data}", data);
|
||||
if (data.IsEmpty())
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
var position = _positionStorageContact.GetElementById(data);
|
||||
if (position == null)
|
||||
throw new ElementNotFoundException(data);
|
||||
if (!data.IsGuid())
|
||||
throw new ValidationException("data must be a GUID");
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
public void InsertPosition(PositionDataModel position)
|
||||
{
|
||||
_logger.LogInformation("InsertPosition: {json}", JsonSerializer.Serialize(position));
|
||||
if (position == null)
|
||||
throw new ArgumentNullException(nameof(position));
|
||||
|
||||
position.Validate();
|
||||
_positionStorageContact.AddElement(position);
|
||||
}
|
||||
|
||||
public void UpdatePosition(PositionDataModel position)
|
||||
{
|
||||
_logger.LogInformation("UpdatePosition: {json}", JsonSerializer.Serialize(position));
|
||||
if (position == null)
|
||||
throw new ArgumentNullException(nameof(position));
|
||||
|
||||
position.Validate();
|
||||
_positionStorageContact.UpdateElement(position);
|
||||
}
|
||||
|
||||
public void DeletePosition(string id)
|
||||
{
|
||||
_logger.LogInformation("DeletePosition for id: {id}", id);
|
||||
if (id.IsEmpty())
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var position = _positionStorageContact.GetElementById(id);
|
||||
if (position == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
_positionStorageContact.DeleteElement(id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -20,24 +23,92 @@ namespace CandyHouseBase.Implementations
|
||||
|
||||
public List<ProductDataModel> GetAllProducts()
|
||||
{
|
||||
return new List<ProductDataModel>();
|
||||
_logger.LogInformation("GetAllProducts");
|
||||
var products = _productStorageContact.GetList() ?? throw new NullListException();
|
||||
return products;
|
||||
}
|
||||
|
||||
public ProductDataModel GetProductByData(string data)
|
||||
{
|
||||
return new ProductDataModel("", "", "", new List<IngredientDataModel>());
|
||||
_logger.LogInformation("GetProductByData for data: {data}", data);
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (string.IsNullOrEmpty(data))
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
if (data.IsGuid())
|
||||
{
|
||||
var product = _productStorageContact.GetElementById(data);
|
||||
if (product == null)
|
||||
throw new ElementNotFoundException(data);
|
||||
if (!data.IsGuid()) // Validate after existence check (redundant but kept for consistency)
|
||||
throw new ValidationException("data must be a GUID");
|
||||
return product;
|
||||
}
|
||||
else
|
||||
{
|
||||
var products = _productStorageContact.GetList();
|
||||
var productByName = products.FirstOrDefault(p => p.Name == data || (p.OldName != null && p.OldName == data));
|
||||
if (productByName == null)
|
||||
throw new ElementNotFoundException(data);
|
||||
return productByName;
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertProduct(ProductDataModel product)
|
||||
{
|
||||
_logger.LogInformation("InsertProduct: {json}", JsonSerializer.Serialize(product));
|
||||
if (product == null)
|
||||
throw new ArgumentNullException(nameof(product));
|
||||
product.Validate();
|
||||
|
||||
foreach (var ingredient in product.IngredientsItems)
|
||||
{
|
||||
if (_ingredientStorageContact.GetElementById(ingredient.Id) == null)
|
||||
throw new ElementNotFoundException(ingredient.Id);
|
||||
}
|
||||
|
||||
_productStorageContact.AddElement(product);
|
||||
}
|
||||
|
||||
public void UpdateProduct(ProductDataModel product)
|
||||
{
|
||||
_logger.LogInformation("UpdateProduct: {json}", JsonSerializer.Serialize(product));
|
||||
if (product == null)
|
||||
throw new ArgumentNullException(nameof(product));
|
||||
product.Validate();
|
||||
|
||||
foreach (var ingredient in product.IngredientsItems)
|
||||
{
|
||||
if (_ingredientStorageContact.GetElementById(ingredient.Id) == null)
|
||||
throw new ElementNotFoundException(ingredient.Id);
|
||||
}
|
||||
|
||||
_productStorageContact.UpdateElement(product);
|
||||
}
|
||||
|
||||
public void DeleteProduct(string id)
|
||||
{
|
||||
_logger.LogInformation("DeleteProduct for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var product = _productStorageContact.GetElementById(id);
|
||||
if (product == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
try
|
||||
{
|
||||
_productStorageContact.DeleteElement(id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -12,32 +14,72 @@ namespace CandyHouseBase.Implementations
|
||||
ISalaryStorageContact salaryStorageContact,
|
||||
IPekarStorageContact pekarStorageContact,
|
||||
ILogger logger)
|
||||
: ISalaryStorageContact
|
||||
: ISalaryBusinessLogicContact
|
||||
{
|
||||
private readonly ISalaryStorageContact _salaryStorageContact = salaryStorageContact;
|
||||
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
|
||||
private readonly ILogger _logger = logger;
|
||||
|
||||
public List<SalaryDataModel> GetList()
|
||||
public List<SalaryDataModel> GetAllSalaries()
|
||||
{
|
||||
return new List<SalaryDataModel>();
|
||||
_logger.LogInformation("GetAllSalaries");
|
||||
var salaries = _salaryStorageContact.GetList() ?? throw new NullListException();
|
||||
return salaries;
|
||||
}
|
||||
|
||||
public SalaryDataModel GetElementById(string id)
|
||||
public SalaryDataModel GetSalaryByData(string data)
|
||||
{
|
||||
return new SalaryDataModel("", "", new DateTime(), 0, 0, 0);
|
||||
_logger.LogInformation("GetSalaryByData for data: {data}", data);
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (string.IsNullOrEmpty(data))
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
if (!data.IsGuid())
|
||||
throw new ValidationException("data must be a GUID");
|
||||
|
||||
var salary = _salaryStorageContact.GetElementById(data) ?? throw new ElementNotFoundException(data);
|
||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
||||
throw new ElementNotFoundException(salary.PekarId);
|
||||
return salary;
|
||||
}
|
||||
|
||||
public void AddElement(SalaryDataModel element)
|
||||
public void InsertSalary(SalaryDataModel salary)
|
||||
{
|
||||
_logger.LogInformation("InsertSalary: {json}", JsonSerializer.Serialize(salary));
|
||||
if (salary == null)
|
||||
throw new ArgumentNullException(nameof(salary));
|
||||
salary.Validate();
|
||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
||||
throw new ElementNotFoundException(salary.PekarId);
|
||||
_salaryStorageContact.AddElement(salary);
|
||||
}
|
||||
|
||||
public void UpdateElement(SalaryDataModel element)
|
||||
public void UpdateSalary(SalaryDataModel salary)
|
||||
{
|
||||
_logger.LogInformation("UpdateSalary: {json}", JsonSerializer.Serialize(salary));
|
||||
if (salary == null)
|
||||
throw new ArgumentNullException(nameof(salary));
|
||||
salary.Validate();
|
||||
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
|
||||
throw new ElementNotFoundException(salary.PekarId);
|
||||
_salaryStorageContact.UpdateElement(salary);
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
public void DeleteSalary(string id)
|
||||
{
|
||||
_logger.LogInformation("DeleteSalary for id: {id}", id);
|
||||
if (id == null)
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (string.IsNullOrEmpty(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
if (!id.IsGuid())
|
||||
throw new ValidationException("id must be a GUID");
|
||||
|
||||
var salary = _salaryStorageContact.GetElementById(id);
|
||||
if (salary == null)
|
||||
throw new ElementNotFoundException(id);
|
||||
|
||||
_salaryStorageContact.DeleteElement(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace CandyHouseBase.Infrastructure;
|
||||
|
||||
public interface IConfigurationDatabase
|
||||
{
|
||||
public string ConnectionString =>
|
||||
"Host=127.0.0.1;Port=5432;Database=CandyHouseTest;Username=postgres;Password=postgres;";
|
||||
}
|
||||
@@ -9,6 +9,6 @@ namespace CandyHouseBase.Interfaces.StoragesContracts
|
||||
void AddElement(OrderDataModel order);
|
||||
void UpdateElement(OrderDataModel order);
|
||||
void DeleteElement(OrderDataModel order);
|
||||
OrderDataModel GetElementById(int orderId);
|
||||
OrderDataModel GetElementById(string orderId);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace CandyHouseBase
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
61
CandyHouseSolution/CandyHouseDataBase/CandyHouseDataBase.cs
Normal file
61
CandyHouseSolution/CandyHouseDataBase/CandyHouseDataBase.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using CandyHouseBase.Infrastructure;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CandyHouseDataBase;
|
||||
|
||||
public class CandyHouseDbContext(IConfigurationDatabase configurationDatabase) : DbContext
|
||||
{
|
||||
private readonly IConfigurationDatabase? _configurationDatabase = configurationDatabase;
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseNpgsql(_configurationDatabase?.ConnectionString);
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Uniqueness for Ingredient
|
||||
modelBuilder.Entity<Ingredient>()
|
||||
.HasIndex(x => x.Name)
|
||||
.IsUnique();
|
||||
|
||||
// Uniqueness for Product (only non-deleted)
|
||||
modelBuilder.Entity<Product>()
|
||||
.HasIndex(x => new { x.Name, x.IsDeleted })
|
||||
.IsUnique()
|
||||
.HasFilter($"\"{nameof(Product.IsDeleted)}\" = FALSE");
|
||||
|
||||
// Composite key for Recipe
|
||||
modelBuilder.Entity<Recipe>()
|
||||
.HasKey(x => new { x.ProductId, x.IngredientId });
|
||||
|
||||
// Uniqueness for Position (Title for active records)
|
||||
modelBuilder.Entity<Position>()
|
||||
.HasIndex(x => new { x.Title, x.IsActual })
|
||||
.IsUnique()
|
||||
.HasFilter($"\"{nameof(Position.IsActual)}\" = TRUE");
|
||||
|
||||
modelBuilder.Entity<Position>()
|
||||
.HasIndex(x => new { x.PositionId, x.IsActual })
|
||||
.IsUnique()
|
||||
.HasFilter($"\"{nameof(Position.IsActual)}\" = TRUE");
|
||||
|
||||
// Uniqueness for Order
|
||||
modelBuilder.Entity<Order>()
|
||||
.HasIndex(x => new { x.PekarId, x.OrderDate })
|
||||
.IsUnique();
|
||||
}
|
||||
|
||||
public DbSet<Ingredient> Ingredients { get; set; }
|
||||
public DbSet<Product> Products { get; set; }
|
||||
public DbSet<Recipe> Recipes { get; set; }
|
||||
public DbSet<Position> Positions { get; set; }
|
||||
public DbSet<Pekar> Pekars { get; set; }
|
||||
public DbSet<PekarHistory> PekarHistories { get; set; }
|
||||
public DbSet<Salary> Salaries { get; set; }
|
||||
public DbSet<Order> Orders { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CandyHouseBase\CandyHouseBase.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>CandyHouseTests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,177 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class IngredientStorageContract : IIngredientStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public IngredientStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Ingredient, IngredientDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.Unit, opt => opt.MapFrom(src => src.Unit))
|
||||
.ForMember(dest => dest.Cost, opt => opt.MapFrom(src => src.Cost));
|
||||
cfg.CreateMap<IngredientDataModel, Ingredient>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.Unit, opt => opt.MapFrom(src => src.Unit))
|
||||
.ForMember(dest => dest.Cost, opt => opt.MapFrom(src => src.Cost));
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<IngredientDataModel> GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _dbContext.Ingredients
|
||||
.Select(x => _mapper.Map<IngredientDataModel>(x))
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientDataModel GetElementById(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetIngredientById(id) ?? throw new ElementNotFoundException(id);
|
||||
return _mapper.Map<IngredientDataModel>(entity);
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientDataModel GetElementByName(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetIngredientByName(name) ?? throw new ElementNotFoundException(name);
|
||||
return _mapper.Map<IngredientDataModel>(entity);
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(IngredientDataModel ingredient)
|
||||
{
|
||||
try
|
||||
{
|
||||
ingredient.Validate();
|
||||
var entity = _mapper.Map<Ingredient>(ingredient);
|
||||
_dbContext.Ingredients.Add(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException
|
||||
{
|
||||
ConstraintName: "IX_Ingredients_Name"
|
||||
})
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Name", ingredient.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateElement(IngredientDataModel ingredient)
|
||||
{
|
||||
try
|
||||
{
|
||||
ingredient.Validate();
|
||||
var entity = GetIngredientById(ingredient.Id) ?? throw new ElementNotFoundException(ingredient.Id);
|
||||
_dbContext.Ingredients.Update(_mapper.Map(ingredient, entity));
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException
|
||||
{
|
||||
ConstraintName: "IX_Ingredients_Name"
|
||||
})
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Name", ingredient.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetIngredientById(id) ?? throw new ElementNotFoundException(id);
|
||||
_dbContext.Ingredients.Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Ingredient? GetIngredientById(string id) =>
|
||||
_dbContext.Ingredients.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
private Ingredient? GetIngredientByName(string name) =>
|
||||
_dbContext.Ingredients.FirstOrDefault(x => x.Name == name);
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class OrderStorageContract : IOrderStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public OrderStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Order, OrderDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.CustomerName))
|
||||
.ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate))
|
||||
.ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount))
|
||||
.ForMember(dest => dest.DiscountAmount, opt => opt.MapFrom(src => src.DiscountAmount))
|
||||
.ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.ProductId))
|
||||
.ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId))
|
||||
.ForMember(dest => dest.StatusType, opt => opt.MapFrom(src => src.StatusType));
|
||||
cfg.CreateMap<OrderDataModel, Order>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.CustomerName))
|
||||
.ForMember(dest => dest.OrderDate, opt => opt.MapFrom(src => src.OrderDate))
|
||||
.ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount))
|
||||
.ForMember(dest => dest.DiscountAmount, opt => opt.MapFrom(src => src.DiscountAmount))
|
||||
.ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.ProductId))
|
||||
.ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId))
|
||||
.ForMember(dest => dest.StatusType, opt => opt.MapFrom(src => src.StatusType));
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<OrderDataModel> GetOrders()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _dbContext.Orders
|
||||
.Select(x => _mapper.Map<OrderDataModel>(x))
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(OrderDataModel order)
|
||||
{
|
||||
try
|
||||
{
|
||||
order.Validate();
|
||||
var entity = _mapper.Map<Order>(order);
|
||||
_dbContext.Orders.Add(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Orders_PekarId_OrderDate" })
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("OrderDate", order.OrderDate.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateElement(OrderDataModel order)
|
||||
{
|
||||
try
|
||||
{
|
||||
order.Validate();
|
||||
var entity = GetOrderById(order.Id) ?? throw new ElementNotFoundException(order.Id);
|
||||
_dbContext.Orders.Update(_mapper.Map(order, entity));
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Orders_PekarId_OrderDate" })
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("OrderDate", order.OrderDate.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteElement(OrderDataModel order)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetOrderById(order.Id) ?? throw new ElementNotFoundException(order.Id);
|
||||
_dbContext.Orders.Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public OrderDataModel GetElementById(string orderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetOrderById(orderId) ?? throw new ElementNotFoundException(orderId);
|
||||
return _mapper.Map<OrderDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Order? GetOrderById(string id) =>
|
||||
_dbContext.Orders.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class PekarStorageContract : IPekarStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public PekarStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Pekar, PekarDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.FIO, opt => opt.MapFrom(src => src.FIO))
|
||||
.ForMember(dest => dest.Position, opt => opt.MapFrom(src => src.PositionId))
|
||||
.ForMember(dest => dest.BonusCoefficient, opt => opt.MapFrom(src => src.BonusCoefficient))
|
||||
.ForMember(dest => dest.ProductsItems, opt => opt.MapFrom(src => src.Orders
|
||||
.Select(o => new ProductDataModel(
|
||||
o.Product.Id,
|
||||
o.Product.Name,
|
||||
o.Product.Description,
|
||||
o.Product.Recipes.Select(r => new IngredientDataModel(
|
||||
r.Ingredient.Id,
|
||||
r.Ingredient.Name,
|
||||
r.Ingredient.Unit,
|
||||
r.Ingredient.Cost)).ToList() ?? new List<IngredientDataModel>()))));
|
||||
|
||||
cfg.CreateMap<PekarDataModel, Pekar>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.FIO, opt => opt.MapFrom(src => src.FIO))
|
||||
.ForMember(dest => dest.PositionId, opt => opt.MapFrom(src => src.Position))
|
||||
.ForMember(dest => dest.BonusCoefficient, opt => opt.MapFrom(src => src.BonusCoefficient))
|
||||
.ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Position, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Orders, opt =>
|
||||
opt.MapFrom(src => src.ProductsItems.Select(p => new Order
|
||||
{
|
||||
Product = new Product
|
||||
{
|
||||
Id = p.Id,
|
||||
Name = p.Name,
|
||||
Description = p.Description,
|
||||
Recipes = p.IngredientsItems.Select(i => new Recipe
|
||||
{
|
||||
Ingredient = new Ingredient
|
||||
{
|
||||
Id = i.Id,
|
||||
Name = i.Name,
|
||||
Unit = i.Unit,
|
||||
Cost = i.Cost
|
||||
}
|
||||
}).ToList()
|
||||
}
|
||||
}).ToList())); // Explicitly ignore navigation property
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<PekarDataModel> GetList()
|
||||
{
|
||||
return ExecuteWithErrorHandling(() =>
|
||||
_dbContext.Pekars
|
||||
.Where(x => !x.IsDeleted)
|
||||
.Select(x => _mapper.Map<PekarDataModel>(x))
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public List<PekarDataModel> GetPekarWithHistory(string id)
|
||||
{
|
||||
return ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
var pekar = GetPekarById(id) ?? throw new ElementNotFoundException(id);
|
||||
var history = _dbContext.PekarHistories
|
||||
.Where(h => h.PekarId == id)
|
||||
.Select(h => new PekarDataModel(
|
||||
pekar.Id,
|
||||
h.FIO,
|
||||
h.PositionId,
|
||||
h.BonusCoefficient,
|
||||
new List<ProductDataModel>())) // Empty list as placeholder
|
||||
.ToList();
|
||||
|
||||
return history.Any() ? history : new List<PekarDataModel> { _mapper.Map<PekarDataModel>(pekar) };
|
||||
});
|
||||
}
|
||||
|
||||
public PekarDataModel GetElementById(string id)
|
||||
{
|
||||
return ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
var entity = _dbContext.Pekars
|
||||
.FirstOrDefault(x => x.Id == id && !x.IsDeleted)
|
||||
?? throw new ElementNotFoundException(id);
|
||||
return _mapper.Map<PekarDataModel>(entity);
|
||||
});
|
||||
}
|
||||
|
||||
public PekarDataModel GetElementByFio(string fio)
|
||||
{
|
||||
return ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
var entity = _dbContext.Pekars
|
||||
.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)
|
||||
?? throw new ElementNotFoundException($"Pekar with FIO {fio} not found.");
|
||||
return _mapper.Map<PekarDataModel>(entity);
|
||||
});
|
||||
}
|
||||
|
||||
public void AddElement(PekarDataModel item)
|
||||
{
|
||||
ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
item.Validate();
|
||||
var entity = _mapper.Map<Pekar>(item);
|
||||
entity.IsDeleted = false;
|
||||
_dbContext.Pekars.Add(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}, specificExceptions: ex =>
|
||||
{
|
||||
if (ex is ValidationException) throw ex;
|
||||
if (ex is DbUpdateException dbEx && dbEx.InnerException is PostgresException pgEx &&
|
||||
pgEx.ConstraintName == "IX_Pekars_PositionId")
|
||||
throw new ElementExistsException("PositionId", item.Position);
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateElement(PekarDataModel item)
|
||||
{
|
||||
ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
item.Validate();
|
||||
var entity = GetPekarById(item.Id) ?? throw new ElementNotFoundException(item.Id);
|
||||
if (entity.IsDeleted) throw new ElementDeletedException(item.Id);
|
||||
_mapper.Map(item, entity); // Update existing entity
|
||||
_dbContext.SaveChanges();
|
||||
}, specificExceptions: ex =>
|
||||
{
|
||||
if (ex is ValidationException || ex is ElementNotFoundException || ex is ElementDeletedException) throw ex;
|
||||
});
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
{
|
||||
ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
var entity = GetPekarById(id) ?? throw new ElementNotFoundException(id);
|
||||
if (entity.IsDeleted) throw new ElementDeletedException(id);
|
||||
entity.IsDeleted = true;
|
||||
_dbContext.SaveChanges();
|
||||
}, specificExceptions: ex =>
|
||||
{
|
||||
if (ex is ElementNotFoundException || ex is ElementDeletedException) throw ex;
|
||||
});
|
||||
}
|
||||
|
||||
public void RestoreElement(string id)
|
||||
{
|
||||
ExecuteWithErrorHandling(() =>
|
||||
{
|
||||
var entity = GetPekarById(id) ?? throw new ElementNotFoundException(id);
|
||||
if (!entity.IsDeleted) throw new ElementDeletedException(id); // Misnamed but kept for consistency
|
||||
entity.IsDeleted = false;
|
||||
_dbContext.SaveChanges();
|
||||
}, specificExceptions: ex =>
|
||||
{
|
||||
if (ex is ElementNotFoundException || ex is ElementDeletedException) throw ex;
|
||||
});
|
||||
}
|
||||
|
||||
private Pekar? GetPekarById(string id) => _dbContext.Pekars.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
private T ExecuteWithErrorHandling<T>(Func<T> action, Action<Exception> specificExceptions = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
specificExceptions?.Invoke(ex);
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteWithErrorHandling(Action action, Action<Exception> specificExceptions = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
specificExceptions?.Invoke(ex);
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class PositionStorageContract : IPositionStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public PositionStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Position, PositionDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.PositionId))
|
||||
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Type))
|
||||
.ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title));
|
||||
cfg.CreateMap<PositionDataModel, Position>()
|
||||
.ForMember(dest => dest.PositionId, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Type))
|
||||
.ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title))
|
||||
.ForMember(dest => dest.IsActual, opt => opt.MapFrom(src => true))
|
||||
.ForMember(dest => dest.ChangeDate, opt => opt.MapFrom(src => DateTime.UtcNow));
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<PositionDataModel> GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _dbContext.Positions
|
||||
.Where(x => x.IsActual)
|
||||
.Select(x => _mapper.Map<PositionDataModel>(x))
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public PositionDataModel GetElementById(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = _dbContext.Positions.FirstOrDefault(x => x.PositionId == id && x.IsActual)
|
||||
?? throw new ElementNotFoundException(id);
|
||||
return _mapper.Map<PositionDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(PositionDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
var entity = _mapper.Map<Position>(element);
|
||||
_dbContext.Positions.Add(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException pgEx &&
|
||||
pgEx.ConstraintName == "IX_Positions_Title_IsActual")
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Title", element.Title);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateElement(PositionDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
using var transaction = _dbContext.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var oldEntity = _dbContext.Positions.FirstOrDefault(x => x.PositionId == element.Id && x.IsActual)
|
||||
?? throw new ElementNotFoundException(element.Id);
|
||||
if (!oldEntity.IsActual) throw new ElementDeletedException(element.Id);
|
||||
oldEntity.IsActual = false;
|
||||
_dbContext.SaveChanges();
|
||||
|
||||
var newEntity = _mapper.Map<Position>(element);
|
||||
newEntity.Id = Guid.NewGuid().ToString(); // New ID for history
|
||||
newEntity.PositionId = element.Id;
|
||||
newEntity.ChangeDate = DateTime.UtcNow;
|
||||
_dbContext.Positions.Add(newEntity);
|
||||
_dbContext.SaveChanges();
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementDeletedException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException pgEx &&
|
||||
pgEx.ConstraintName == "IX_Positions_Title_IsActual")
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Title", element.Title);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = _dbContext.Positions.FirstOrDefault(x => x.PositionId == id)
|
||||
?? throw new ElementNotFoundException(id);
|
||||
if (!entity.IsActual) throw new ElementDeletedException(id);
|
||||
entity.IsActual = false;
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ElementDeletedException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class ProductStorageContract : IProductStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public ProductStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Product, ProductDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Description))
|
||||
.ForMember(dest => dest.OldName, opt => opt.MapFrom(src => src.OldName))
|
||||
.ForMember(dest => dest.OldDescription, opt => opt.MapFrom(src => src.OldDescription))
|
||||
.ForMember(dest => dest.IngredientsItems,
|
||||
opt => opt.MapFrom(src =>
|
||||
src.Recipes.Select(r => new IngredientDataModel(r.Ingredient.Id, r.Ingredient.Name,
|
||||
r.Ingredient.Unit, r.Ingredient.Cost)).ToList() ?? new List<IngredientDataModel>()));
|
||||
cfg.CreateMap<ProductDataModel, Product>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Description))
|
||||
.ForMember(dest => dest.OldName, opt => opt.MapFrom(src => src.OldName))
|
||||
.ForMember(dest => dest.OldDescription, opt => opt.MapFrom(src => src.OldDescription))
|
||||
.ForMember(dest => dest.IsDeleted, opt => opt.MapFrom(src => false));
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<ProductDataModel> GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _dbContext.Products
|
||||
.Where(x => !x.IsDeleted)
|
||||
.Select(x => _mapper.Map<ProductDataModel>(x))
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductDataModel GetElementById(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetProductById(id) ?? throw new ElementNotFoundException(id);
|
||||
return _mapper.Map<ProductDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductDataModel GetElementByName(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = _dbContext.Products.FirstOrDefault(x => x.Name == name && !x.IsDeleted) ??
|
||||
throw new ElementNotFoundException($"Product with name {name} not found.");
|
||||
return _mapper.Map<ProductDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductDataModel GetElementByOldName(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = _dbContext.Products.FirstOrDefault(x => x.OldName == name && !x.IsDeleted) ??
|
||||
throw new ElementNotFoundException($"Product with old name {name} not found.");
|
||||
return _mapper.Map<ProductDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(ProductDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
var entity = _mapper.Map<Product>(element);
|
||||
|
||||
// Add the Product first to persist its Id
|
||||
_dbContext.Products.Add(entity);
|
||||
_dbContext.SaveChanges(); // Save Product to get a persisted Id
|
||||
|
||||
// Create Ingredients and Recipes from IngredientsItems
|
||||
var recipes = new List<Recipe>();
|
||||
foreach (var ingredientItem in element.IngredientsItems)
|
||||
{
|
||||
var ingredient = new Ingredient
|
||||
{
|
||||
Id = ingredientItem.Id,
|
||||
Name = ingredientItem.Name,
|
||||
Unit = ingredientItem.Unit,
|
||||
Cost = ingredientItem.Cost
|
||||
};
|
||||
_dbContext.Ingredients.Add(ingredient);
|
||||
_dbContext.SaveChanges(); // Ensure Ingredient is persisted
|
||||
|
||||
var recipe = new Recipe
|
||||
{
|
||||
ProductId = entity.Id,
|
||||
IngredientId = ingredient.Id,
|
||||
Quantity = 1
|
||||
};
|
||||
recipes.Add(recipe);
|
||||
}
|
||||
|
||||
// Explicitly add Recipes to the DbSet
|
||||
_dbContext.Recipes.AddRange(recipes);
|
||||
_dbContext.SaveChanges(); // Save Recipes
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException
|
||||
{
|
||||
ConstraintName: "IX_Products_Name"
|
||||
})
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Name", element.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateElement(ProductDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
var entity = GetProductById(element.Id);
|
||||
if (entity == null) throw new ElementNotFoundException(element.Id);
|
||||
if (entity.IsDeleted) throw new ElementDeletedException(element.Id);
|
||||
|
||||
// Store the original values before mapping
|
||||
var originalName = entity.Name;
|
||||
var originalDescription = entity.Description;
|
||||
|
||||
// Map the updated values from element
|
||||
_mapper.Map(element, entity);
|
||||
|
||||
// Set OldName and OldDescription after mapping
|
||||
entity.OldName = originalName;
|
||||
entity.OldDescription = originalDescription;
|
||||
|
||||
// Update Recipes
|
||||
var existingRecipes = _dbContext.Recipes.Where(r => r.ProductId == entity.Id).ToList();
|
||||
_dbContext.Recipes.RemoveRange(existingRecipes);
|
||||
_dbContext.SaveChanges();
|
||||
|
||||
var recipes = new List<Recipe>();
|
||||
foreach (var ingredientItem in element.IngredientsItems)
|
||||
{
|
||||
// Check if an Ingredient with the same Name already exists
|
||||
var existingIngredient = _dbContext.Ingredients
|
||||
.FirstOrDefault(i => i.Name == ingredientItem.Name);
|
||||
var ingredient = existingIngredient ?? new Ingredient
|
||||
{
|
||||
Id = ingredientItem.Id,
|
||||
Name = ingredientItem.Name,
|
||||
Unit = ingredientItem.Unit,
|
||||
Cost = ingredientItem.Cost
|
||||
};
|
||||
if (existingIngredient == null)
|
||||
{
|
||||
_dbContext.Ingredients.Add(ingredient);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
var recipe = new Recipe
|
||||
{
|
||||
ProductId = entity.Id,
|
||||
IngredientId = ingredient.Id,
|
||||
Quantity = 1
|
||||
};
|
||||
recipes.Add(recipe);
|
||||
}
|
||||
|
||||
_dbContext.Recipes.AddRange(recipes);
|
||||
_dbContext.Products.Update(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementDeletedException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is PostgresException
|
||||
{
|
||||
ConstraintName: "IX_Products_Name"
|
||||
})
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new ElementExistsException("Name", element.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetProductById(id) ?? throw new ElementNotFoundException(id);
|
||||
if (entity.IsDeleted) throw new ElementDeletedException(id);
|
||||
entity.IsDeleted = true;
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ElementDeletedException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Product? GetProductById(string id) =>
|
||||
_dbContext.Products.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CandyHouseDataBase.Implementations;
|
||||
|
||||
internal class SalaryStorageContract : ISalaryStorageContact
|
||||
{
|
||||
private readonly CandyHouseDbContext _dbContext;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public SalaryStorageContract(CandyHouseDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<Salary, SalaryDataModel>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId))
|
||||
.ForMember(dest => dest.Period, opt => opt.MapFrom(src => src.Period))
|
||||
.ForMember(dest => dest.BaseRate, opt => opt.MapFrom(src => src.BaseRate))
|
||||
.ForMember(dest => dest.BonusRate, opt => opt.MapFrom(src => src.BonusRate))
|
||||
.ForMember(dest => dest.TotalSalary, opt => opt.MapFrom(src => src.TotalSalary));
|
||||
cfg.CreateMap<SalaryDataModel, Salary>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.PekarId, opt => opt.MapFrom(src => src.PekarId))
|
||||
.ForMember(dest => dest.Period, opt => opt.MapFrom(src => src.Period))
|
||||
.ForMember(dest => dest.BaseRate, opt => opt.MapFrom(src => src.BaseRate))
|
||||
.ForMember(dest => dest.BonusRate, opt => opt.MapFrom(src => src.BonusRate))
|
||||
.ForMember(dest => dest.TotalSalary, opt => opt.MapFrom(src => src.TotalSalary));
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public List<SalaryDataModel> GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _dbContext.Salaries
|
||||
.Select(x => _mapper.Map<SalaryDataModel>(x))
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public SalaryDataModel GetElementById(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = _dbContext.Salaries.FirstOrDefault(x => x.Id == id) ?? throw new ElementNotFoundException(id);
|
||||
return _mapper.Map<SalaryDataModel>(entity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(SalaryDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
var entity = _mapper.Map<Salary>(element);
|
||||
_dbContext.Salaries.Add(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateElement(SalaryDataModel element)
|
||||
{
|
||||
try
|
||||
{
|
||||
element.Validate();
|
||||
var entity = GetSalaryById(element.Id) ?? throw new ElementNotFoundException(element.Id);
|
||||
_dbContext.Salaries.Update(_mapper.Map(element, entity));
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ValidationException ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteElement(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = GetSalaryById(id) ?? throw new ElementNotFoundException(id);
|
||||
_dbContext.Salaries.Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
catch (ElementNotFoundException)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Salary? GetSalaryById(string id) =>
|
||||
_dbContext.Salaries.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
21
CandyHouseSolution/CandyHouseDataBase/Models/Ingredient.cs
Normal file
21
CandyHouseSolution/CandyHouseDataBase/Models/Ingredient.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Ingredient
|
||||
{
|
||||
[Key]
|
||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Unit { get; set; }
|
||||
|
||||
[Required]
|
||||
public decimal Cost { get; set; }
|
||||
|
||||
public List<Recipe> Recipes { get; set; }
|
||||
}
|
||||
27
CandyHouseSolution/CandyHouseDataBase/Models/Order.cs
Normal file
27
CandyHouseSolution/CandyHouseDataBase/Models/Order.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using CandyHouseBase.Enums;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Order
|
||||
{
|
||||
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
public string CustomerName { get; set; } // Can be null for one-time customers
|
||||
|
||||
[Required] public DateTime OrderDate { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Required] public decimal TotalAmount { get; set; }
|
||||
|
||||
[Required] public decimal DiscountAmount { get; set; }
|
||||
|
||||
[Required] public string ProductId { get; set; }
|
||||
[Required] public string PekarId { get; set; }
|
||||
|
||||
[Required] public StatusType StatusType { get; set; }
|
||||
|
||||
public Pekar Pekar { get; set; }
|
||||
|
||||
public Product Product { get; set; }
|
||||
}
|
||||
24
CandyHouseSolution/CandyHouseDataBase/Models/Pekar.cs
Normal file
24
CandyHouseSolution/CandyHouseDataBase/Models/Pekar.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Pekar
|
||||
{
|
||||
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Required] public string FIO { get; set; }
|
||||
|
||||
[Required] public string PositionId { get; set; }
|
||||
|
||||
[Required] public decimal BonusCoefficient { get; set; }
|
||||
|
||||
public bool IsDeleted { get; set; } = false;
|
||||
|
||||
public Position Position { get; set; }
|
||||
|
||||
[ForeignKey("PekarId")] public List<Salary> Salaries { get; set; }
|
||||
|
||||
[ForeignKey("PekarId")] public List<PekarHistory> PekarHistories { get; set; }
|
||||
[ForeignKey("PekarId")] public List<Order> Orders { get; set; }
|
||||
}
|
||||
22
CandyHouseSolution/CandyHouseDataBase/Models/PekarHistory.cs
Normal file
22
CandyHouseSolution/CandyHouseDataBase/Models/PekarHistory.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class PekarHistory
|
||||
{
|
||||
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Required] public string PekarId { get; set; }
|
||||
|
||||
[Required] public string FIO { get; set; }
|
||||
|
||||
[Required] public string PositionId { get; set; }
|
||||
|
||||
[Required] public DateTime Date { get; set; }
|
||||
|
||||
[Required] public decimal BonusCoefficient { get; set; }
|
||||
|
||||
public Pekar Pekar { get; set; }
|
||||
public Position Position { get; set; }
|
||||
}
|
||||
21
CandyHouseSolution/CandyHouseDataBase/Models/Position.cs
Normal file
21
CandyHouseSolution/CandyHouseDataBase/Models/Position.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using CandyHouseBase.Enums;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Position
|
||||
{
|
||||
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
public string PositionId { get; set; }
|
||||
|
||||
[Required] public string Title { get; set; }
|
||||
|
||||
public PositionType Type { get; set; }
|
||||
|
||||
public bool IsActual { get; set; } = true;
|
||||
|
||||
public DateTime ChangeDate { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[ForeignKey("PositionId")] public List<Pekar> Pekars { get; set; }
|
||||
}
|
||||
25
CandyHouseSolution/CandyHouseDataBase/Models/Product.cs
Normal file
25
CandyHouseSolution/CandyHouseDataBase/Models/Product.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Product
|
||||
{
|
||||
[Key]
|
||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
|
||||
public string OldName { get; set; }
|
||||
|
||||
public string OldDescription { get; set; }
|
||||
|
||||
public bool IsDeleted { get; set; } = false;
|
||||
|
||||
[ForeignKey("ProductId")]
|
||||
public List<Recipe> Recipes { get; set; }
|
||||
}
|
||||
19
CandyHouseSolution/CandyHouseDataBase/Models/Recipe.cs
Normal file
19
CandyHouseSolution/CandyHouseDataBase/Models/Recipe.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Recipe
|
||||
{
|
||||
[Required]
|
||||
public string ProductId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string IngredientId { get; set; }
|
||||
|
||||
[Required]
|
||||
public int Quantity { get; set; }
|
||||
|
||||
public Product Product { get; set; }
|
||||
public Ingredient Ingredient { get; set; }
|
||||
}
|
||||
21
CandyHouseSolution/CandyHouseDataBase/Models/Salary.cs
Normal file
21
CandyHouseSolution/CandyHouseDataBase/Models/Salary.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace CandyHouseDataBase.Models;
|
||||
|
||||
public class Salary
|
||||
{
|
||||
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
|
||||
[Required] public string PekarId { get; set; }
|
||||
|
||||
[Required] public DateTime Period { get; set; }
|
||||
|
||||
[Required] public decimal BaseRate { get; set; }
|
||||
|
||||
[Required] public decimal BonusRate { get; set; }
|
||||
|
||||
[Required] public decimal TotalSalary { get; set; }
|
||||
|
||||
public Pekar Pekar { get; set; }
|
||||
}
|
||||
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseBase", "CandyHous
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseTests", "CandyHouseTests\CandyHouseTests.csproj", "{396EA8C4-6102-479E-83A2-C83E6B74A14E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseDataBase", "CandyHouseDataBase\CandyHouseDataBase.csproj", "{54F7ED2D-9E96-4546-BA6B-B65140E1F602}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -18,5 +20,9 @@ Global
|
||||
{396EA8C4-6102-479E-83A2-C83E6B74A14E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{396EA8C4-6102-479E-83A2-C83E6B74A14E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{396EA8C4-6102-479E-83A2-C83E6B74A14E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{54F7ED2D-9E96-4546-BA6B-B65140E1F602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{54F7ED2D-9E96-4546-BA6B-B65140E1F602}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54F7ED2D-9E96-4546-BA6B-B65140E1F602}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54F7ED2D-9E96-4546-BA6B-B65140E1F602}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -2,11 +2,14 @@ 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;
|
||||
using CandyHouseBase.Implementations;
|
||||
|
||||
namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
{
|
||||
@@ -20,8 +23,10 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void OneTimeSetUp()
|
||||
{
|
||||
_ingredientStorageContact = new Mock<IIngredientStorageContact>();
|
||||
_ingredientBusinessLogicContract =
|
||||
new IngredientBusinessLogicContract(_ingredientStorageContact.Object, new Mock<ILogger>().Object);
|
||||
_ingredientBusinessLogicContract = new IngredientBusinessLogicContract(
|
||||
_ingredientStorageContact.Object,
|
||||
new Mock<ILogger>().Object
|
||||
);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
@@ -36,9 +41,9 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Arrange
|
||||
var ingredients = new List<IngredientDataModel>
|
||||
{
|
||||
new(Guid.NewGuid().ToString(), "Sugar", "kg", 100),
|
||||
new(Guid.NewGuid().ToString(), "Flour", "kg", 200),
|
||||
new(Guid.NewGuid().ToString(), "Cocoa", "kg", 50)
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100),
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Flour", "kg", 200),
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Cocoa", "kg", 50)
|
||||
};
|
||||
_ingredientStorageContact.Setup(x => x.GetList()).Returns(ingredients);
|
||||
|
||||
@@ -48,6 +53,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Assert
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.EquivalentTo(ingredients));
|
||||
Assert.That(list.All(i => Guid.TryParse(i.Id, out _) && !i.Name.IsEmpty() && !i.Unit.IsEmpty() && i.Cost >= 0), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -80,8 +86,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void GetAllIngredients_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.GetList())
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_ingredientStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetAllIngredients(), Throws.TypeOf<StorageException>());
|
||||
@@ -89,7 +94,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientById_ReturnsRecord_Test()
|
||||
public void GetIngredientByData_ReturnsIngredientById_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
@@ -102,11 +107,15 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Id, Is.EqualTo(id));
|
||||
Assert.That(Guid.TryParse(element.Id, out _), Is.True);
|
||||
Assert.That(!element.Name.IsEmpty());
|
||||
Assert.That(!element.Unit.IsEmpty());
|
||||
Assert.That(element.Cost >= 0);
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientByName_ReturnsRecord_Test()
|
||||
public void GetIngredientByData_ReturnsIngredientByName_Test()
|
||||
{
|
||||
// Arrange
|
||||
var name = "Sugar";
|
||||
@@ -119,175 +128,148 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Name, Is.EqualTo(name));
|
||||
Assert.That(Guid.TryParse(element.Id, out _), Is.True);
|
||||
Assert.That(!element.Unit.IsEmpty());
|
||||
Assert.That(element.Cost >= 0);
|
||||
_ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientById_NotFoundRecord_ThrowException_Test()
|
||||
public void GetIngredientByData_EmptyData_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(id),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
_ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientByName_NotFoundRecord_ThrowException_Test()
|
||||
public void GetIngredientByData_NotFoundById_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString(); // Valid Guid
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientByData_NotFoundByName_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var name = "Nonexistent";
|
||||
_ingredientStorageContact.Setup(x => x.GetElementByName(name)).Returns((IngredientDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(name),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(name), Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementByName(name), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientById_StorageThrowError_ThrowException_Test()
|
||||
public void GetIngredientByData_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementByName(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData("Sugar"), Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIngredientByName_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.GetElementByName(It.IsAny<string>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.GetIngredientByData("Sugar"),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementByName(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddIngredient_CorrectRecord_Test()
|
||||
public void InsertIngredient_CorrectRecord_Test()
|
||||
{
|
||||
// Arrange
|
||||
var flag = false;
|
||||
var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100);
|
||||
_ingredientStorageContact.Setup(x => x.AddElement(It.IsAny<IngredientDataModel>()))
|
||||
.Callback((IngredientDataModel x) =>
|
||||
{
|
||||
flag = x.Id == ingredient.Id && x.Name == ingredient.Name &&
|
||||
x.Cost == ingredient.Cost && x.Unit == ingredient.Unit;
|
||||
});
|
||||
_ingredientStorageContact.Setup(x => x.AddElement(ingredient)).Verifiable();
|
||||
|
||||
// Act
|
||||
_ingredientBusinessLogicContract.InsertIngredient(ingredient);
|
||||
|
||||
// Assert
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(flag);
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(ingredient), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddIngredient_RecordWithExistsData_ThrowException_Test()
|
||||
public void InsertIngredient_RecordWithExistsData_ThrowException_Test()
|
||||
{
|
||||
var ingredient = It.IsAny<IngredientDataModel>();
|
||||
// Arrange
|
||||
var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100);
|
||||
_ingredientStorageContact.Setup(x => x.AddElement(ingredient))
|
||||
.Throws(new ElementExistsException("ID", ingredient.Id));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.InsertIngredient(
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)),
|
||||
Throws.TypeOf<ElementExistsException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(ingredient), Throws.TypeOf<ElementExistsException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(ingredient), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddIngredient_NullRecord_ThrowException_Test()
|
||||
public void InsertIngredient_NullRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(null),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(null), Throws.TypeOf<ArgumentNullException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(It.IsAny<IngredientDataModel>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddIngredient_InvalidRecord_ThrowException_Test()
|
||||
public void InsertIngredient_InvalidRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.InsertIngredient(new IngredientDataModel("", null, "", -1)),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(new IngredientDataModel("", "", "", -1)), Throws.TypeOf<ValidationException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(It.IsAny<IngredientDataModel>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddIngredient_StorageThrowError_ThrowException_Test()
|
||||
public void InsertIngredient_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.AddElement(It.IsAny<IngredientDataModel>()))
|
||||
var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100);
|
||||
_ingredientStorageContact.Setup(x => x.AddElement(ingredient))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.InsertIngredient(
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.InsertIngredient(ingredient), Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.AddElement(ingredient), 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<IngredientDataModel>()))
|
||||
.Callback((IngredientDataModel x) =>
|
||||
{
|
||||
flag = x.Id == ingredient.Id && x.Name == ingredient.Name &&
|
||||
x.Cost == ingredient.Cost && x.Unit == ingredient.Unit;
|
||||
});
|
||||
_ingredientStorageContact.Setup(x => x.UpdateElement(ingredient)).Verifiable();
|
||||
|
||||
// Act
|
||||
_ingredientBusinessLogicContract.UpdateIngredient(ingredient);
|
||||
|
||||
// Assert
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(flag);
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateIngredient_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
var ingredient = It.IsAny<IngredientDataModel>();
|
||||
// Arrange
|
||||
var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100);
|
||||
_ingredientStorageContact.Setup(x => x.UpdateElement(ingredient))
|
||||
.Throws(new ElementNotFoundException(ingredient.ToString()));
|
||||
.Throws(new ElementNotFoundException(ingredient.Id));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.UpdateIngredient(
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(ingredient), Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateIngredient_NullRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(null),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(null), Throws.TypeOf<ArgumentNullException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny<IngredientDataModel>()), Times.Never);
|
||||
}
|
||||
|
||||
@@ -295,9 +277,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdateIngredient_InvalidRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.UpdateIngredient(new IngredientDataModel("", null, "", -1)),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(new IngredientDataModel("", "", "", -1)), Throws.TypeOf<ValidationException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny<IngredientDataModel>()), Times.Never);
|
||||
}
|
||||
|
||||
@@ -305,56 +285,69 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdateIngredient_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.UpdateElement(It.IsAny<IngredientDataModel>()))
|
||||
var ingredient = new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100);
|
||||
_ingredientStorageContact.Setup(x => x.UpdateElement(ingredient))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(
|
||||
() => _ingredientBusinessLogicContract.UpdateIngredient(
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(It.IsAny<IngredientDataModel>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.UpdateIngredient(ingredient), Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.UpdateElement(ingredient), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteIngredient_CorrectId_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "1";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var ingredient = new IngredientDataModel(id, "Sugar", "kg", 100);
|
||||
var flag = false;
|
||||
_ingredientStorageContact.Setup(x => x.DeleteElement(It.Is((string x) => x == id)))
|
||||
.Callback(() => { flag = true; });
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns(ingredient);
|
||||
_ingredientStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; });
|
||||
|
||||
// Act
|
||||
_ingredientBusinessLogicContract.DeleteIngredient(id);
|
||||
|
||||
// Assert
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
Assert.That(flag);
|
||||
Assert.That(Guid.TryParse(ingredient.Id, out _), Is.True);
|
||||
Assert.That(!ingredient.Name.IsEmpty());
|
||||
Assert.That(!ingredient.Unit.IsEmpty());
|
||||
Assert.That(ingredient.Cost >= 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteIngredient_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
var ingredient = It.IsAny<IngredientDataModel>();
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.UpdateElement(ingredient))
|
||||
.Throws(new ElementNotFoundException(ingredient.ToString()));
|
||||
var id = Guid.NewGuid().ToString(); // Use valid Guid
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns((IngredientDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient("nonexistent"),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteIngredient_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(id)).Returns(new IngredientDataModel(id, "Sugar", "kg", 100));
|
||||
_ingredientStorageContact.Setup(x => x.DeleteElement(id)).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(id), Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteIngredient_NullOrEmptyId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(null),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(string.Empty),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
@@ -362,22 +355,8 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void DeleteIngredient_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient("invalid"),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient("invalid"), Throws.TypeOf<ValidationException>());
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteIngredient_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_ingredientStorageContact.Setup(x => x.DeleteElement(It.IsAny<string>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _ingredientBusinessLogicContract.DeleteIngredient(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_ingredientStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Extensions;
|
||||
using CandyHouseBase.Implementations;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.Interfaces.StoragesContracts;
|
||||
@@ -138,7 +139,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Guid.NewGuid().ToString(),
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.GetElementById(It.Is<int>(i => i.ToString() == id))).Returns(order);
|
||||
_orderStorageContact.Setup(x => x.GetElementById(id)).Returns(order);
|
||||
|
||||
// Act
|
||||
var element = _orderBusinessLogicContract.GetOrderByData(id);
|
||||
@@ -146,7 +147,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Id, Is.EqualTo(id));
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.Is<int>(i => i.ToString() == id)), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -154,35 +155,32 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(string.Empty),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.IsAny<int>()), Times.Never);
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetOrderByData_NotFoundRecord_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "999";
|
||||
_orderStorageContact.Setup(x => x.GetElementById(It.Is<int>(i => i.ToString() == id)))
|
||||
.Returns((OrderDataModel)null);
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_orderStorageContact.Setup(x => x.GetElementById(id)).Returns((OrderDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(id),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.Is<int>(i => i.ToString() == id)), Times.Once);
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetOrderByData_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_orderStorageContact.Setup(x => x.GetElementById(It.IsAny<int>()))
|
||||
_orderStorageContact.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData("1"), Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.IsAny<int>()), Times.Once);
|
||||
Assert.That(() => _orderBusinessLogicContract.GetOrderByData(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -202,14 +200,16 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.AddElement(It.IsAny<OrderDataModel>()))
|
||||
_orderStorageContact.Setup(x => x.GetElementById(order.Id)).Returns((OrderDataModel)null); // No existing order
|
||||
_orderStorageContact.Setup(x => x.AddElement(It.Is<OrderDataModel>(o => o.Id == order.Id)))
|
||||
.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;
|
||||
});
|
||||
})
|
||||
.Verifiable();
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId))
|
||||
.Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
@@ -219,7 +219,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_orderBusinessLogicContract.InsertOrder(order);
|
||||
|
||||
// Assert
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.Is<OrderDataModel>(o => o.Id == order.Id)), Times.Once);
|
||||
Assert.That(flag);
|
||||
}
|
||||
|
||||
@@ -227,22 +227,27 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertOrder_RecordWithExistsData_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var order = new OrderDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"John Doe",
|
||||
DateTime.Now,
|
||||
100.50m,
|
||||
10.50m,
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
productId,
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.AddElement(It.IsAny<OrderDataModel>()))
|
||||
.Throws(new ElementExistsException("ID", order.Id));
|
||||
_orderStorageContact.Setup(x => x.GetElementById(order.Id)).Returns(order); // Existing order
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId))
|
||||
.Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
.Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List<IngredientDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.InsertOrder(order), Throws.TypeOf<ElementExistsException>());
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.GetElementById(order.Id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -261,10 +266,10 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
"",
|
||||
"",
|
||||
DateTime.Now,
|
||||
-100.50m,
|
||||
-10.50m,
|
||||
"",
|
||||
"",
|
||||
-100.50m,
|
||||
-10.50m,
|
||||
"",
|
||||
"",
|
||||
StatusType.Pending
|
||||
)), Throws.TypeOf<ValidationException>());
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.IsAny<OrderDataModel>()), Times.Never);
|
||||
@@ -274,22 +279,30 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertOrder_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var order = new OrderDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"John Doe",
|
||||
DateTime.Now,
|
||||
100.50m,
|
||||
10.50m,
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
productId,
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.AddElement(It.IsAny<OrderDataModel>()))
|
||||
_orderStorageContact.Setup(x => x.GetElementById(order.Id)).Returns((OrderDataModel)null); // No existing order
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId))
|
||||
.Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
.Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List<IngredientDataModel>()));
|
||||
_orderStorageContact.Setup(x => x.AddElement(It.Is<OrderDataModel>(o => o.Id == order.Id)))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.InsertOrder(order), Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.GetElementById(order.Id), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.AddElement(It.Is<OrderDataModel>(o => o.Id == order.Id)), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -309,14 +322,15 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.IsAny<OrderDataModel>()))
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)))
|
||||
.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;
|
||||
});
|
||||
})
|
||||
.Verifiable();
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId))
|
||||
.Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
@@ -326,7 +340,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_orderBusinessLogicContract.UpdateOrder(order);
|
||||
|
||||
// Assert
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)), Times.Once);
|
||||
Assert.That(flag);
|
||||
}
|
||||
|
||||
@@ -334,23 +348,25 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdateOrder_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var order = new OrderDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"John Doe",
|
||||
DateTime.Now,
|
||||
100.50m,
|
||||
10.50m,
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
productId,
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.IsAny<OrderDataModel>()))
|
||||
.Throws(new ElementNotFoundException("Order not found"));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns((PekarDataModel)null); // Trigger not found
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)))
|
||||
.Verifiable();
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.UpdateOrder(order),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
Assert.That(() => _orderBusinessLogicContract.UpdateOrder(order), Throws.TypeOf<ElementNotFoundException>());
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -366,13 +382,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.UpdateOrder(new OrderDataModel(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
DateTime.Now,
|
||||
-100.50m,
|
||||
-10.50m,
|
||||
"",
|
||||
"",
|
||||
-10.50m,
|
||||
"",
|
||||
"",
|
||||
StatusType.Pending
|
||||
)), Throws.TypeOf<ValidationException>());
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.IsAny<OrderDataModel>()), Times.Never);
|
||||
@@ -382,22 +398,28 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdateOrder_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var order = new OrderDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"John Doe",
|
||||
DateTime.Now,
|
||||
100.50m,
|
||||
10.50m,
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
productId,
|
||||
pekarId,
|
||||
StatusType.Pending
|
||||
);
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.IsAny<OrderDataModel>()))
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId))
|
||||
.Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
.Returns(new ProductDataModel(productId, "Cake", "Super soft cake", new List<IngredientDataModel>()));
|
||||
_orderStorageContact.Setup(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.UpdateOrder(order), Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.UpdateElement(It.Is<OrderDataModel>(o => o.Id == order.Id)), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -416,30 +438,31 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
StatusType.Pending
|
||||
);
|
||||
var flag = false;
|
||||
_orderStorageContact.Setup(x => x.DeleteElement(It.Is<OrderDataModel>(o => o.Id == id)))
|
||||
.Callback(() => { flag = true; });
|
||||
_orderStorageContact.Setup(x => x.GetOrders()).Returns(new List<OrderDataModel> { order });
|
||||
_orderStorageContact.Setup(x => x.GetElementById(id)).Returns(order);
|
||||
_orderStorageContact.Setup(x => x.DeleteElement(order)).Callback(() => { flag = true; });
|
||||
|
||||
// Act
|
||||
_orderBusinessLogicContract.DeleteOrder(id);
|
||||
|
||||
// Assert
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(It.Is<OrderDataModel>(o => o.Id == id)), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(order), Times.Once);
|
||||
Assert.That(flag);
|
||||
Assert.That(Guid.TryParse(order.Id, out _), Is.True);
|
||||
Assert.That(!order.CustomerName.IsEmpty());
|
||||
Assert.That(order.TotalAmount >= 0);
|
||||
Assert.That(order.DiscountAmount >= 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteOrder_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
_orderStorageContact.Setup(x => x.GetOrders()).Returns(new List<OrderDataModel>());
|
||||
_orderStorageContact.Setup(x => x.DeleteElement(It.Is<OrderDataModel>(o => o.Id == id)))
|
||||
.Throws(new ElementNotFoundException("Order not found"));
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_orderStorageContact.Setup(x => x.GetElementById(id)).Returns((OrderDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(It.Is<OrderDataModel>(o => o.Id == id)), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -447,8 +470,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(string.Empty),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(It.IsAny<OrderDataModel>()), Times.Never);
|
||||
}
|
||||
|
||||
@@ -464,13 +486,15 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void DeleteOrder_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_orderStorageContact.Setup(x => x.DeleteElement(It.IsAny<OrderDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
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(id)).Returns(order);
|
||||
_orderStorageContact.Setup(x => x.DeleteElement(order)).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(It.IsAny<OrderDataModel>()), Times.Once);
|
||||
Assert.That(() => _orderBusinessLogicContract.DeleteOrder(id), Throws.TypeOf<StorageException>());
|
||||
_orderStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_orderStorageContact.Verify(x => x.DeleteElement(order), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
Guid.NewGuid().ToString(), // Use Guid for Position
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Maria Petrova",
|
||||
"Pastry Chef",
|
||||
Guid.NewGuid().ToString(), // Use Guid for Position
|
||||
1.8m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -92,6 +92,10 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
};
|
||||
_pekarStorageContact.Setup(x => x.GetList()).Returns(pekars);
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekars[0].ProductsItems[0]);
|
||||
_positionStorageContact.Setup(x => x.GetElementById(pekars[0].Position))
|
||||
.Returns(new PositionDataModel(pekars[0].Position, PositionType.Cool, "Baking position"));
|
||||
_positionStorageContact.Setup(x => x.GetElementById(pekars[1].Position))
|
||||
.Returns(new PositionDataModel(pekars[1].Position, PositionType.Cool, "Pastry Chef position"));
|
||||
|
||||
// Act
|
||||
var list = _pekarBusinessLogicContract.GetAllPekars();
|
||||
@@ -101,7 +105,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(list, Is.EquivalentTo(pekars));
|
||||
Assert.That(
|
||||
list.All(p =>
|
||||
Guid.TryParse(p.Id, out _) && !p.FIO.IsEmpty() && !p.Position.IsEmpty() &&
|
||||
Guid.TryParse(p.Id, out _) && !p.FIO.IsEmpty() && Guid.TryParse(p.Position, out _) &&
|
||||
p.BonusCoefficient > 0), Is.True);
|
||||
}
|
||||
|
||||
@@ -148,29 +152,17 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var historyRecords = new List<PekarHistoryDataModel>
|
||||
var historyRecords = new List<PekarDataModel>
|
||||
{
|
||||
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)
|
||||
)
|
||||
new PekarDataModel(pekarId, "Ivan Ivanov", positionId, 1.5m, new List<ProductDataModel>()),
|
||||
new PekarDataModel(pekarId, "Ivan Ivanov", positionId, 1.7m, new List<ProductDataModel>())
|
||||
};
|
||||
var pekarsWithHistory = new List<PekarDataModel>
|
||||
{
|
||||
new PekarDataModel(
|
||||
pekarId,
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.8m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -195,8 +187,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
|
||||
// Assert
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list.Count,
|
||||
Is.EqualTo(historyRecords.Count));
|
||||
Assert.That(2, Is.EqualTo(historyRecords.Count));
|
||||
Assert.That(
|
||||
list.All(h =>
|
||||
Guid.TryParse(h.Id, out _) && !h.FIO.IsEmpty() && Guid.TryParse(h.Position, out _) &&
|
||||
@@ -220,7 +211,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void GetAllDataOfPekar_NotFoundPekar_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = "nonexistent";
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
_pekarStorageContact.Setup(x => x.GetPekarWithHistory(pekarId)).Returns(new List<PekarDataModel>());
|
||||
|
||||
// Act & Assert
|
||||
@@ -247,13 +238,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
var positionId = "999"; // Invalid position ID
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var pekarsWithHistory = new List<PekarDataModel>
|
||||
{
|
||||
new PekarDataModel(
|
||||
pekarId,
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.8m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -286,10 +277,11 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
id,
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -306,6 +298,8 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar);
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
|
||||
// Act
|
||||
var element = _pekarBusinessLogicContract.GetPekarByData(id);
|
||||
@@ -316,7 +310,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
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(Guid.TryParse(element.Position, out _), Is.True);
|
||||
Assert.That(element.BonusCoefficient > 0);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
@@ -335,13 +329,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void GetPekarByData_NotFoundPekar_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.GetPekarByData(id),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -363,11 +357,12 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Arrange
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var flag = false;
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -382,7 +377,9 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
)
|
||||
}
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.AddElement(It.IsAny<PekarDataModel>()))
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekar.Id))
|
||||
.Returns((PekarDataModel)null);
|
||||
_pekarStorageContact.Setup(x => x.AddElement(It.Is<PekarDataModel>(p => p.Id == pekar.Id)))
|
||||
.Callback((PekarDataModel x) =>
|
||||
{
|
||||
flag = x.Id == pekar.Id && x.FIO == pekar.FIO && x.Position == pekar.Position &&
|
||||
@@ -390,17 +387,19 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
x.ProductsItems.SequenceEqual(pekar.ProductsItems);
|
||||
});
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
|
||||
// Act
|
||||
_pekarBusinessLogicContract.InsertPekar(pekar);
|
||||
|
||||
// Assert
|
||||
_pekarStorageContact.Verify(x => x.AddElement(It.IsAny<PekarDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.AddElement(It.Is<PekarDataModel>(p => p.Id == pekar.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(Guid.TryParse(pekar.Position, out _), Is.True);
|
||||
Assert.That(pekar.BonusCoefficient > 0);
|
||||
}
|
||||
|
||||
@@ -408,30 +407,42 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertPekar_RecordWithExistsData_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
productId,
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)
|
||||
new IngredientDataModel(ingredientId, "Sugar", "kg", 100)
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
var existingPekar = new PekarDataModel(pekar.Id, "Old Name", positionId, 1.0m, new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(productId, "Old Cake", "Old cake", new List<IngredientDataModel>())
|
||||
});
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekar.Id)).Returns(existingPekar);
|
||||
_pekarStorageContact.Setup(x => x.AddElement(It.IsAny<PekarDataModel>()))
|
||||
.Throws(new ElementExistsException("ID", pekar.Id));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
.Returns(existingPekar.ProductsItems[0]); // Mock product existence
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf<ElementExistsException>());
|
||||
_pekarStorageContact.Verify(x => x.AddElement(It.IsAny<PekarDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekar.Id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -448,18 +459,18 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(new PekarDataModel(
|
||||
"",
|
||||
"123",
|
||||
"",
|
||||
"123",
|
||||
Guid.NewGuid().ToString(),
|
||||
-1.0m,
|
||||
new List<ProductDataModel>
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel("", "Sugar", "kg", -100) // Invalid Ingredient
|
||||
new IngredientDataModel("", "Sugar", "kg", -100)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -471,43 +482,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertPekar_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.AddElement(It.IsAny<PekarDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.AddElement(It.IsAny<PekarDataModel>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdatePekar_CorrectRecord_Test()
|
||||
{
|
||||
// Arrange
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var flag = false;
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -522,7 +503,47 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
)
|
||||
}
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny<PekarDataModel>()))
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekar.Id)).Returns((PekarDataModel)null);
|
||||
_pekarStorageContact.Setup(x => x.AddElement(It.IsAny<PekarDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId))
|
||||
.Returns(pekar.ProductsItems[0]); // Mock product existence
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekar.Id), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.AddElement(It.IsAny<PekarDataModel>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdatePekar_CorrectRecord_Test()
|
||||
{
|
||||
// Arrange
|
||||
var productId = Guid.NewGuid().ToString();
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var flag = false;
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(
|
||||
productId,
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(ingredientId, "Sugar", "kg", 100)
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.UpdateElement(It.Is<PekarDataModel>(p => p.Id == pekar.Id)))
|
||||
.Callback((PekarDataModel x) =>
|
||||
{
|
||||
flag = x.Id == pekar.Id && x.FIO == pekar.FIO && x.Position == pekar.Position &&
|
||||
@@ -530,17 +551,19 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
x.ProductsItems.SequenceEqual(pekar.ProductsItems);
|
||||
});
|
||||
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
|
||||
// Act
|
||||
_pekarBusinessLogicContract.UpdatePekar(pekar);
|
||||
|
||||
// Assert
|
||||
_pekarStorageContact.Verify(x => x.UpdateElement(It.IsAny<PekarDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.UpdateElement(It.Is<PekarDataModel>(p => p.Id == pekar.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(Guid.TryParse(pekar.Position, out _), Is.True);
|
||||
Assert.That(pekar.BonusCoefficient > 0);
|
||||
}
|
||||
|
||||
@@ -548,10 +571,11 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdatePekar_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -566,6 +590,10 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
)
|
||||
}
|
||||
);
|
||||
_productStorageContact.Setup(x => x.GetElementById(pekar.ProductsItems[0].Id))
|
||||
.Returns(pekar.ProductsItems[0]);
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
_pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny<PekarDataModel>()))
|
||||
.Throws(new ElementNotFoundException("Pekar not found"));
|
||||
|
||||
@@ -590,17 +618,17 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(new PekarDataModel(
|
||||
"",
|
||||
"123",
|
||||
"",
|
||||
-1.0m,
|
||||
new List<ProductDataModel>
|
||||
Guid.NewGuid().ToString(),
|
||||
-1.0m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
new ProductDataModel(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel("", "Sugar", "kg", -100) // Invalid Ingredient
|
||||
new IngredientDataModel("", "Sugar", "kg", -100)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -612,10 +640,11 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void UpdatePekar_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
positionId,
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -630,8 +659,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
)
|
||||
}
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekar.Id)).Returns(pekar); // Ensure Pekar exists
|
||||
_pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny<PekarDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_positionStorageContact.Setup(x => x.GetElementById(positionId))
|
||||
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
|
||||
_productStorageContact.Setup(x => x.GetElementById(pekar.ProductsItems[0].Id))
|
||||
.Returns(pekar.ProductsItems[0]);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.UpdatePekar(pekar), Throws.TypeOf<StorageException>());
|
||||
@@ -648,7 +682,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
var pekar = new PekarDataModel(
|
||||
id,
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
Guid.NewGuid().ToString(),
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -686,12 +720,12 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void DeletePekar_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -701,28 +735,41 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(string.Empty),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
_pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny<PekarDataModel>().Id), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeletePekar_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "invalid";
|
||||
// No need to setup GetElementById for invalid ID since validation should prevent it
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar("invalid"), Throws.TypeOf<ValidationException>());
|
||||
_pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny<PekarDataModel>().Id), Times.Never);
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(id), Throws.TypeOf<ValidationException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeletePekar_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_pekarStorageContact.Setup(x => x.DeleteElement(It.IsAny<PekarDataModel>().Id))
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
id,
|
||||
"Ivan Ivanov",
|
||||
Guid.NewGuid().ToString(),
|
||||
1.5m,
|
||||
new List<ProductDataModel>()
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar);
|
||||
_pekarStorageContact.Setup(x => x.DeleteElement(id))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.DeleteElement(It.IsAny<PekarDataModel>().Id), Times.Once);
|
||||
Assert.That(() => _pekarBusinessLogicContract.DeletePekar(id), Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -735,7 +782,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
var pekar = new PekarDataModel(
|
||||
id,
|
||||
"Ivan Ivanov",
|
||||
"Baker",
|
||||
Guid.NewGuid().ToString(),
|
||||
1.5m,
|
||||
new List<ProductDataModel>
|
||||
{
|
||||
@@ -773,12 +820,12 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void RestorePekar_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -788,29 +835,41 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(string.Empty),
|
||||
Throws.TypeOf<ArgumentNullException>());
|
||||
_pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny<PekarDataModel>().Id), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RestorePekar_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "invalid";
|
||||
// No need to setup GetElementById for invalid ID since validation should prevent it
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar("invalid"),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
_pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny<PekarDataModel>().Id), Times.Never);
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(id), Throws.TypeOf<ValidationException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RestorePekar_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_pekarStorageContact.Setup(x => x.RestoreElement(It.IsAny<PekarDataModel>().Id))
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var pekar = new PekarDataModel(
|
||||
id,
|
||||
"Ivan Ivanov",
|
||||
Guid.NewGuid().ToString(),
|
||||
1.5m,
|
||||
new List<ProductDataModel>()
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar);
|
||||
_pekarStorageContact.Setup(x => x.RestoreElement(id))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.RestoreElement(It.IsAny<PekarDataModel>().Id), Times.Once);
|
||||
Assert.That(() => _pekarBusinessLogicContract.RestorePekar(id), Throws.TypeOf<StorageException>());
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.RestoreElement(id), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,13 +146,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void GetPositionByData_NotFoundPosition_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString(); // Use a valid Guid to test not found scenario
|
||||
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns((PositionDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _positionBusinessLogicContract.GetPositionByData(id),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_positionStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_positionStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -368,13 +368,13 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void DeletePosition_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString(); // Use a valid Guid to test not found scenario
|
||||
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns((PositionDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _positionBusinessLogicContract.DeletePosition(id),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
_positionStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_positionStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -391,23 +391,31 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
[Test]
|
||||
public void DeletePosition_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "invalid";
|
||||
// No need to setup GetElementById for invalid ID since validation should be after existence check
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _positionBusinessLogicContract.DeletePosition("invalid"),
|
||||
Assert.That(() => _positionBusinessLogicContract.DeletePosition(id),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
_positionStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
_positionStorageContact.Verify(x => x.GetElementById(id), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeletePosition_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_positionStorageContact.Setup(x => x.DeleteElement(It.IsAny<string>()))
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var position = new PositionDataModel(id, PositionType.Cool, "Baker");
|
||||
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position);
|
||||
_positionStorageContact.Setup(x => x.DeleteElement(id))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _positionBusinessLogicContract.DeletePosition(Guid.NewGuid().ToString()),
|
||||
Assert.That(() => _positionBusinessLogicContract.DeletePosition(id),
|
||||
Throws.TypeOf<StorageException>());
|
||||
_positionStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
_positionStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_positionStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
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<string>()), Times.Once);
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -239,7 +239,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void GetProductByData_NotFoundProduct_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_productStorageContact.Setup(x => x.GetElementById(id)).Returns((ProductDataModel)null);
|
||||
_productStorageContact.Setup(x => x.GetList()).Returns(new List<ProductDataModel>());
|
||||
|
||||
@@ -247,25 +247,23 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData("NonExistentProduct"), Throws.TypeOf<ElementNotFoundException>());
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData("OldNonExistent"), Throws.TypeOf<ElementNotFoundException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_productStorageContact.Verify(x => x.GetList(), Times.AtLeast(2));
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), 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<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_productStorageContact.Setup(x => x.GetElementById(id)).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<StorageException>());
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData("Cake"), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData("OldCake"), Throws.TypeOf<StorageException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_productStorageContact.Verify(x => x.GetList(), Times.AtLeast(2));
|
||||
Assert.That(() => _productBusinessLogicContract.GetProductByData(id), Throws.TypeOf<StorageException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_productStorageContact.Verify(x => x.GetList(), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertProduct_CorrectRecord_Test()
|
||||
{
|
||||
@@ -313,19 +311,21 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertProduct_RecordWithExistsData_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var product = new ProductDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)
|
||||
new IngredientDataModel(ingredientId, "Sugar", "kg", 100)
|
||||
}
|
||||
);
|
||||
product.Name = "Updated Cake";
|
||||
product.Description = "Updated delicious cake";
|
||||
_productStorageContact.Setup(x => x.AddElement(It.IsAny<ProductDataModel>()))
|
||||
.Throws(new ElementExistsException("ID", product.Id));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.InsertProduct(product), Throws.TypeOf<ElementExistsException>());
|
||||
@@ -360,19 +360,21 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void InsertProduct_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var product = new ProductDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)
|
||||
new IngredientDataModel(ingredientId, "Sugar", "kg", 100)
|
||||
}
|
||||
);
|
||||
product.Name = "Updated Cake";
|
||||
product.Description = "Updated delicious cake";
|
||||
_productStorageContact.Setup(x => x.AddElement(It.IsAny<ProductDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(ingredientId)).Returns(product.IngredientsItems[0]);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.InsertProduct(product), Throws.TypeOf<StorageException>());
|
||||
@@ -439,6 +441,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
product.Description = "Updated delicious cake";
|
||||
_productStorageContact.Setup(x => x.UpdateElement(It.IsAny<ProductDataModel>()))
|
||||
.Throws(new ElementNotFoundException("Product not found"));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(product.IngredientsItems[0].Id)).Returns(product.IngredientsItems[0]); // Mock ingredient existence
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.UpdateProduct(product), Throws.TypeOf<ElementNotFoundException>());
|
||||
@@ -486,6 +489,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
product.Description = "Updated delicious cake";
|
||||
_productStorageContact.Setup(x => x.UpdateElement(It.IsAny<ProductDataModel>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
_ingredientStorageContact.Setup(x => x.GetElementById(product.IngredientsItems[0].Id)).Returns(product.IngredientsItems[0]); // Mock ingredient existence
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.UpdateProduct(product), Throws.TypeOf<StorageException>());
|
||||
@@ -533,40 +537,50 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
public void DeleteProduct_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString(); // Use a valid Guid
|
||||
_productStorageContact.Setup(x => x.GetElementById(id)).Returns((ProductDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteProduct_NullOrEmptyId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_productStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteProduct_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "invalid";
|
||||
// No need to setup GetElementById for invalid ID since validation should occur first
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct("invalid"), Throws.TypeOf<ValidationException>());
|
||||
_productStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(id), Throws.TypeOf<ValidationException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), Times.Never); // Should not call GetElementById for invalid GUID
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteProduct_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_productStorageContact.Setup(x => x.DeleteElement(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var product = new ProductDataModel(
|
||||
id,
|
||||
"Cake",
|
||||
"Delicious cake",
|
||||
new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Sugar", "kg", 100)
|
||||
}
|
||||
);
|
||||
product.Name = "Updated Cake";
|
||||
product.Description = "Updated delicious cake";
|
||||
_productStorageContact.Setup(x => x.GetElementById(id)).Returns(product);
|
||||
_productStorageContact.Setup(x => x.DeleteElement(id))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
_productStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _productBusinessLogicContract.DeleteProduct(id), Throws.TypeOf<StorageException>());
|
||||
_productStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_productStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetList_ReturnsListOfRecords_Test()
|
||||
public void GetAllSalaries_ReturnsListOfRecords_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
@@ -67,22 +67,23 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act
|
||||
var list = _salaryBusinessLogicContract.GetList();
|
||||
var list = _salaryBusinessLogicContract.GetAllSalaries();
|
||||
|
||||
// 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);
|
||||
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetList_ReturnsEmptyList_Test()
|
||||
public void GetAllSalaries_ReturnsEmptyList_Test()
|
||||
{
|
||||
// Arrange
|
||||
_salaryStorageContact.Setup(x => x.GetList()).Returns(new List<SalaryDataModel>());
|
||||
|
||||
// Act
|
||||
var list = _salaryBusinessLogicContract.GetList();
|
||||
var list = _salaryBusinessLogicContract.GetAllSalaries();
|
||||
|
||||
// Assert
|
||||
Assert.That(list, Is.Not.Null);
|
||||
@@ -91,29 +92,29 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetList_ReturnsNull_ThrowException_Test()
|
||||
public void GetAllSalaries_ReturnsNull_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_salaryStorageContact.Setup(x => x.GetList()).Returns((List<SalaryDataModel>)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetList(), Throws.TypeOf<NullListException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetAllSalaries(), Throws.TypeOf<NullListException>());
|
||||
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetList_StorageThrowError_ThrowException_Test()
|
||||
public void GetAllSalaries_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_salaryStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetList(), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetAllSalaries(), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetElementById_ReturnsSalaryById_Test()
|
||||
public void GetSalaryByData_ReturnsSalaryById_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
@@ -130,7 +131,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act
|
||||
var element = _salaryBusinessLogicContract.GetElementById(id);
|
||||
var element = _salaryBusinessLogicContract.GetSalaryByData(id);
|
||||
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
@@ -140,43 +141,71 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(element.BaseRate >= 0);
|
||||
Assert.That(element.BonusRate >= 0);
|
||||
Assert.That(element.TotalSalary >= 0);
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetElementById_EmptyId_ThrowException_Test()
|
||||
public void GetSalaryByData_EmptyId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetElementById(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetElementById(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetElementById_NotFoundSalary_ThrowException_Test()
|
||||
public void GetSalaryByData_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null);
|
||||
var id = "invalid";
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetElementById(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ValidationException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetElementById_StorageThrowError_ThrowException_Test()
|
||||
public void GetSalaryByData_NotFoundSalary_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalaryByData_PekarNotFound_ThrowException_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((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalaryByData_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_salaryStorageContact.Setup(x => x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetElementById(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddElement_CorrectRecord_Test()
|
||||
public void InsertSalary_CorrectRecord_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
@@ -198,7 +227,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act
|
||||
_salaryBusinessLogicContract.AddElement(salary);
|
||||
_salaryBusinessLogicContract.InsertSalary(salary);
|
||||
|
||||
// Assert
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
@@ -208,10 +237,31 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(salary.BaseRate >= 0);
|
||||
Assert.That(salary.BonusRate >= 0);
|
||||
Assert.That(salary.TotalSalary >= 0);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddElement_RecordWithExistsData_ThrowException_Test()
|
||||
public void InsertSalary_PekarNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
DateTime.Now,
|
||||
1000.00m,
|
||||
200.00m,
|
||||
1200.00m
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertSalary_RecordWithExistsData_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
@@ -223,25 +273,28 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
1200.00m
|
||||
);
|
||||
_salaryStorageContact.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>())).Throws(new ElementExistsException("ID", salary.Id));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.AddElement(salary), Throws.TypeOf<ElementExistsException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<ElementExistsException>());
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddElement_NullRecord_ThrowException_Test()
|
||||
public void InsertSalary_NullRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.AddElement(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(null), Throws.TypeOf<ArgumentNullException>());
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddElement_InvalidRecord_ThrowException_Test()
|
||||
public void InsertSalary_InvalidRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.AddElement(new SalaryDataModel(
|
||||
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(new SalaryDataModel(
|
||||
"",
|
||||
"",
|
||||
DateTime.Now,
|
||||
@@ -250,10 +303,11 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
-1200.00m
|
||||
)), Throws.TypeOf<ValidationException>());
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddElement_StorageThrowError_ThrowException_Test()
|
||||
public void InsertSalary_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
@@ -265,14 +319,16 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
1200.00m
|
||||
);
|
||||
_salaryStorageContact.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.AddElement(salary), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateElement_CorrectRecord_Test()
|
||||
public void UpdateSalary_CorrectRecord_Test()
|
||||
{
|
||||
// Arrange
|
||||
var pekarId = Guid.NewGuid().ToString();
|
||||
@@ -294,7 +350,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act
|
||||
_salaryBusinessLogicContract.UpdateElement(salary);
|
||||
_salaryBusinessLogicContract.UpdateSalary(salary);
|
||||
|
||||
// Assert
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
@@ -304,10 +360,31 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
Assert.That(salary.BaseRate >= 0);
|
||||
Assert.That(salary.BonusRate >= 0);
|
||||
Assert.That(salary.TotalSalary >= 0);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateElement_RecordNotFound_ThrowException_Test()
|
||||
public void UpdateSalary_PekarNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
Guid.NewGuid().ToString(),
|
||||
DateTime.Now,
|
||||
1000.00m,
|
||||
200.00m,
|
||||
1200.00m
|
||||
);
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns((PekarDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateSalary_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
@@ -319,25 +396,28 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
1200.00m
|
||||
);
|
||||
_salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny<SalaryDataModel>())).Throws(new ElementNotFoundException("Salary not found"));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateElement(salary), Throws.TypeOf<ElementNotFoundException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateElement_NullRecord_ThrowException_Test()
|
||||
public void UpdateSalary_NullRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateElement(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(null), Throws.TypeOf<ArgumentNullException>());
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateElement_InvalidRecord_ThrowException_Test()
|
||||
public void UpdateSalary_InvalidRecord_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateElement(new SalaryDataModel(
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(new SalaryDataModel(
|
||||
"",
|
||||
"",
|
||||
DateTime.Now,
|
||||
@@ -346,10 +426,11 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
-1200.00m
|
||||
)), Throws.TypeOf<ValidationException>());
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateElement_StorageThrowError_ThrowException_Test()
|
||||
public void UpdateSalary_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var salary = new SalaryDataModel(
|
||||
@@ -361,14 +442,16 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
1200.00m
|
||||
);
|
||||
_salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny<SalaryDataModel>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateElement(salary), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
|
||||
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteElement_CorrectId_Test()
|
||||
public void DeleteSalary_CorrectId_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
@@ -387,7 +470,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act
|
||||
_salaryBusinessLogicContract.DeleteElement(id);
|
||||
_salaryBusinessLogicContract.DeleteSalary(id);
|
||||
|
||||
// Assert
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
@@ -400,43 +483,53 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteElement_RecordNotFound_ThrowException_Test()
|
||||
public void DeleteSalary_RecordNotFound_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
var id = "nonexistent";
|
||||
var id = Guid.NewGuid().ToString();
|
||||
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null);
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteElement(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<ElementNotFoundException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteElement_NullOrEmptyId_ThrowException_Test()
|
||||
public void DeleteSalary_NullOrEmptyId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteElement(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteElement(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(null), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(string.Empty), Throws.TypeOf<ArgumentNullException>());
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteElement_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteElement("invalid"), Throws.TypeOf<ValidationException>());
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteElement_StorageThrowError_ThrowException_Test()
|
||||
public void DeleteSalary_InvalidId_ThrowException_Test()
|
||||
{
|
||||
// Arrange
|
||||
_salaryStorageContact.Setup(x => x.DeleteElement(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
var id = "invalid";
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteElement(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Once);
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<ValidationException>());
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Never);
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteSalary_StorageThrowError_ThrowException_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);
|
||||
_salaryStorageContact.Setup(x => x.DeleteElement(id)).Throws(new StorageException(new InvalidOperationException()));
|
||||
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
|
||||
|
||||
// Act & Assert
|
||||
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
|
||||
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,189 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.props')" />
|
||||
<Import Project="..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props" Condition="Exists('..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props')" />
|
||||
<Import Project="..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.props" Condition="Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.props')" />
|
||||
<Import Project="..\packages\Microsoft.Testing.Platform.1.5.3\build\netstandard2.0\Microsoft.Testing.Platform.props" Condition="Exists('..\packages\Microsoft.Testing.Platform.1.5.3\build\netstandard2.0\Microsoft.Testing.Platform.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{396EA8C4-6102-479E-83A2-C83E6B74A14E}</ProjectGuid>
|
||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CandyHouseTests</RootNamespace>
|
||||
<AssemblyName>CandyHouseTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<OutputType>Library</OutputType> <!-- Changed to Library for test project -->
|
||||
<EnableDefaultItems>true</EnableDefaultItems> <!-- Enable default file inclusion -->
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.ApplicationInsights, Version=2.22.0.997, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Options, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Options.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Options.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Primitives, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.1.25080.5\lib\net462\Microsoft.Extensions.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.MSBuild, Version=1.5.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.Telemetry, Version=1.5.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.TrxReport.Abstractions, Version=1.5.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Extensions.VSTestBridge, Version=1.5.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.5.3\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Testing.Platform, Version=1.5.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Testing.Platform.1.5.3\lib\netstandard2.0\Microsoft.Testing.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TestPlatform.CoreUtilities, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TestPlatform.PlatformAbstractions, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.ObjectModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.20.72.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.20.72\lib\net462\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.1.25080.5\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Metadata, Version=1.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb">
|
||||
<HintPath>..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BusinessLogicsContractsTests\IngredientBusinessLogicContractTests.cs" />
|
||||
<Compile Include="BusinessLogicsContractsTests\OrderBusinessLogicContractTests.cs" />
|
||||
<Compile Include="BusinessLogicsContractsTests\PekarBusinessLogicContractTests.cs" />
|
||||
<Compile Include="BusinessLogicsContractsTests\PositionBusinessLogicContractTests.cs" />
|
||||
<Compile Include="BusinessLogicsContractsTests\ProductBusinessLogicContractTests.cs" />
|
||||
<Compile Include="BusinessLogicsContractsTests\SalaryBusinessLogicContractTests.cs" />
|
||||
<Compile Include="DataModelsTests\IngredientDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\OrderDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\PekarDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\PekarHistoryModelDataTests.cs" />
|
||||
<Compile Include="DataModelsTests\PositionDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\ProductDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\RecipeDataModelTests.cs" />
|
||||
<Compile Include="DataModelsTests\SalaryDataModelTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CandyHouseBase\CandyHouseBase.csproj">
|
||||
<Project>{5df70b46-31f7-4d15-8c60-52c0a0a364f0}</Project>
|
||||
<Name>CandyHouseBase</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="ILLink\ILLink.Descriptors.LibraryBuild.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Platform.1.5.3\build\netstandard2.0\Microsoft.Testing.Platform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Platform.1.5.3\build\netstandard2.0\Microsoft.Testing.Platform.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.3\build\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.props'))" />
|
||||
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.props'))" />
|
||||
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.targets" Condition="Exists('..\packages\Microsoft.Testing.Platform.MSBuild.1.5.3\build\Microsoft.Testing.Platform.MSBuild.targets')" />
|
||||
<Import Project="..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.targets" Condition="Exists('..\packages\NUnit3TestAdapter.5.0.0\build\net462\NUnit3TestAdapter.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-preview.1.25080.5" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="NUnit" Version="3.14.0" /> <!-- Updated to a recent version -->
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> <!-- Added test adapter -->
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> <!-- Added test SDK -->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CandyHouseBase\CandyHouseBase.csproj">
|
||||
<Project>{5df70b46-31f7-4d15-8c60-52c0a0a364f0}</Project>
|
||||
<Name>CandyHouseBase</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CandyHouseDataBase\CandyHouseDataBase.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseTests.Infrastructure;
|
||||
|
||||
internal class ConfigurationDatabaseTest : IConfigurationDatabase
|
||||
{
|
||||
public string ConnectionString =>
|
||||
"Host=127.0.0.1;Port=5432;Database=candyhousetest;Username=postgres;Password=postgres;Include Error Detail=true;";
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using CandyHouseDataBase;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts;
|
||||
|
||||
public class BaseStorageContractTest
|
||||
{
|
||||
protected CandyHouseDbContext CandyHouseDbContext { get; private set; }
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetUp()
|
||||
{
|
||||
CandyHouseDbContext = new CandyHouseDbContext(new ConfigurationDatabaseTest());
|
||||
|
||||
CandyHouseDbContext.Database.EnsureDeleted();
|
||||
CandyHouseDbContext.Database.EnsureCreated();
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.EnsureDeleted();
|
||||
CandyHouseDbContext.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class IngredientStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private IngredientStorageContract _ingredientStorageContract;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_ingredientStorageContract = new IngredientStorageContract(CandyHouseDbContext);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Ingredients\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenHaveRecords_Test()
|
||||
{
|
||||
var ingredient = InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Flour");
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Salt");
|
||||
|
||||
var list = _ingredientStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(3));
|
||||
AssertElement(list.First(x => x.Id == ingredient.Id), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenNoRecords_Test()
|
||||
{
|
||||
var list = _ingredientStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenHaveRecord_Test()
|
||||
{
|
||||
var ingredient = InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
AssertElement(_ingredientStorageContract.GetElementById(ingredient.Id), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenNoRecord_Test()
|
||||
{
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.GetElementById(Guid.NewGuid().ToString()), Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByName_WhenHaveRecord_Test()
|
||||
{
|
||||
var ingredient = InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
AssertElement(_ingredientStorageContract.GetElementByName(ingredient.Name), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByName_WhenNoRecord_Test()
|
||||
{
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.GetElementByName("Salt"), Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_Test()
|
||||
{
|
||||
var ingredient = CreateModel(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
_ingredientStorageContract.AddElement(ingredient);
|
||||
AssertElement(GetIngredientFromDatabase(ingredient.Id), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
|
||||
{
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var ingredient = CreateModel(ingredientId, "Sugar");
|
||||
InsertIngredientToDatabaseAndReturn(ingredientId, "Flour");
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.AddElement(ingredient), Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_WhenHaveRecordWithSameName_Test()
|
||||
{
|
||||
var ingredient = CreateModel(Guid.NewGuid().ToString(), "Sugar");
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), ingredient.Name);
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.AddElement(ingredient), Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_Test()
|
||||
{
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var ingredient = CreateModel(ingredientId, "Sugar");
|
||||
InsertIngredientToDatabaseAndReturn(ingredientId, "Flour");
|
||||
|
||||
_ingredientStorageContract.UpdateElement(ingredient);
|
||||
AssertElement(GetIngredientFromDatabase(ingredient.Id), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenNoRecordWithThisId_Test()
|
||||
{
|
||||
var ingredient = CreateModel(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.UpdateElement(ingredient), Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenHaveRecordWithSameName_Test()
|
||||
{
|
||||
var ingredientId = Guid.NewGuid().ToString();
|
||||
var ingredient = CreateModel(ingredientId, "Sugar");
|
||||
InsertIngredientToDatabaseAndReturn(ingredientId, "Flour");
|
||||
InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
Assert.That(() => _ingredientStorageContract.UpdateElement(ingredient), Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_Test()
|
||||
{
|
||||
var ingredient = InsertIngredientToDatabaseAndReturn(Guid.NewGuid().ToString(), "Sugar");
|
||||
|
||||
_ingredientStorageContract.DeleteElement(ingredient.Id);
|
||||
var element = GetIngredientFromDatabase(ingredient.Id);
|
||||
|
||||
Assert.That(element, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_WhenNoRecordWithThisId_Test()
|
||||
{
|
||||
Assert.That(() => _ingredientStorageContract.DeleteElement(Guid.NewGuid().ToString()), Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
private Ingredient InsertIngredientToDatabaseAndReturn(string id, string name, string unit = "kg", decimal cost = 1.5m)
|
||||
{
|
||||
var ingredient = new Ingredient { Id = id, Name = name, Unit = unit, Cost = cost };
|
||||
CandyHouseDbContext.Ingredients.Add(ingredient);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
private static void AssertElement(IngredientDataModel? actual, Ingredient expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Name, Is.EqualTo(expected.Name));
|
||||
Assert.That(actual.Unit, Is.EqualTo(expected.Unit));
|
||||
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
|
||||
});
|
||||
}
|
||||
|
||||
private static IngredientDataModel CreateModel(string id, string name, string unit = "kg", decimal cost = 1.5m)
|
||||
{
|
||||
return new IngredientDataModel(id, name, unit, cost);
|
||||
}
|
||||
|
||||
private Ingredient? GetIngredientFromDatabase(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Ingredients.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private static void AssertElement(Ingredient? actual, IngredientDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Name, Is.EqualTo(expected.Name));
|
||||
Assert.That(actual.Unit, Is.EqualTo(expected.Unit));
|
||||
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class OrderStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private OrderStorageContract _orderStorageContract;
|
||||
private string _pekarId;
|
||||
private string _productId;
|
||||
private Position _position;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_orderStorageContract = new OrderStorageContract(CandyHouseDbContext);
|
||||
_position = InsertPositionToDatabaseAndReturn();
|
||||
_pekarId = InsertPekarToDatabaseAndReturn(_position.Id).Id; // Insert a Pekar for foreign key
|
||||
_productId = InsertProductToDatabaseAndReturn().Id; // Insert a Product for foreign key
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Orders\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Products\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetOrders_WhenHaveRecords_Test()
|
||||
{
|
||||
var order1 = InsertOrderToDatabaseAndReturn("Customer1", DateTime.UtcNow);
|
||||
var order2 = InsertOrderToDatabaseAndReturn("Customer2", DateTime.UtcNow.AddDays(-1));
|
||||
|
||||
var orders = _orderStorageContract.GetOrders();
|
||||
|
||||
Assert.That(orders, Is.Not.Null);
|
||||
Assert.That(orders, Has.Count.EqualTo(2));
|
||||
AssertOrder(orders.First(o => o.Id == order1.Id), order1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetOrders_WhenNoRecords_Test()
|
||||
{
|
||||
var orders = _orderStorageContract.GetOrders();
|
||||
|
||||
Assert.That(orders, Is.Not.Null);
|
||||
Assert.That(orders, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_ValidOrder_Test()
|
||||
{
|
||||
var order = CreateOrderModel(Guid.NewGuid().ToString(), "John Doe", DateTime.UtcNow, 100m, 10m);
|
||||
|
||||
_orderStorageContract.AddElement(order);
|
||||
var dbOrder = GetOrderFromDatabaseById(order.Id);
|
||||
|
||||
Assert.That(dbOrder, Is.Not.Null);
|
||||
AssertOrder(dbOrder, order);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_DuplicatePekarIdAndOrderDate_Test()
|
||||
{
|
||||
var order1 = CreateOrderModel(Guid.NewGuid().ToString(), "John Doe", DateTime.UtcNow, 100m, 10m);
|
||||
_orderStorageContract.AddElement(order1);
|
||||
|
||||
var order2 = CreateOrderModel(Guid.NewGuid().ToString(), "Jane Doe", order1.OrderDate, 200m, 20m);
|
||||
|
||||
Assert.That(() => _orderStorageContract.AddElement(order2),
|
||||
Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_InvalidOrder_Test()
|
||||
{
|
||||
var order = CreateOrderModel("", "John Doe", DateTime.UtcNow, -100m, 10m); // Invalid Id and TotalAmount
|
||||
|
||||
Assert.That(() => _orderStorageContract.AddElement(order),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_ValidOrder_Test()
|
||||
{
|
||||
var originalOrder = InsertOrderToDatabaseAndReturn("Original Customer", DateTime.UtcNow);
|
||||
var updatedOrder = CreateOrderModel(originalOrder.Id, "Updated Customer", DateTime.UtcNow.AddHours(1), 200m,
|
||||
20m);
|
||||
|
||||
_orderStorageContract.UpdateElement(updatedOrder);
|
||||
var dbOrder = GetOrderFromDatabaseById(updatedOrder.Id);
|
||||
|
||||
Assert.That(dbOrder, Is.Not.Null);
|
||||
AssertOrder(dbOrder, updatedOrder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_NonExistentOrder_Test()
|
||||
{
|
||||
var order = CreateOrderModel(Guid.NewGuid().ToString(), "John Doe", DateTime.UtcNow, 100m, 10m);
|
||||
|
||||
Assert.That(() => _orderStorageContract.UpdateElement(order),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_DuplicatePekarIdAndOrderDate_Test()
|
||||
{
|
||||
var order1 = InsertOrderToDatabaseAndReturn("Customer1", DateTime.UtcNow);
|
||||
var order2 = InsertOrderToDatabaseAndReturn("Customer2", DateTime.UtcNow.AddDays(1));
|
||||
var updatedOrder2 = CreateOrderModel(order2.Id, "Customer2 Updated", order1.OrderDate, 200m, 20m);
|
||||
|
||||
Assert.That(() => _orderStorageContract.UpdateElement(updatedOrder2),
|
||||
Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_ValidOrder_Test()
|
||||
{
|
||||
var order = InsertOrderToDatabaseAndReturn("John Doe", DateTime.UtcNow);
|
||||
|
||||
_orderStorageContract.DeleteElement(CreateOrderModel(order.Id, order.CustomerName, order.OrderDate,
|
||||
order.TotalAmount, order.DiscountAmount));
|
||||
var dbOrder = GetOrderFromDatabaseById(order.Id);
|
||||
|
||||
Assert.That(dbOrder, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_NonExistentOrder_Test()
|
||||
{
|
||||
var order = CreateOrderModel(Guid.NewGuid().ToString(), "John Doe", DateTime.UtcNow, 100m, 10m);
|
||||
|
||||
Assert.That(() => _orderStorageContract.DeleteElement(order),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_ValidOrder_Test()
|
||||
{
|
||||
var order = InsertOrderToDatabaseAndReturn("John Doe", DateTime.UtcNow);
|
||||
|
||||
var result = _orderStorageContract.GetElementById(order.Id);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertOrder(result, order);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_NonExistentOrder_Test()
|
||||
{
|
||||
Assert.That(() => _orderStorageContract.GetElementById(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
// Helper Methods
|
||||
private Order InsertOrderToDatabaseAndReturn(string customerName, DateTime orderDate)
|
||||
{
|
||||
var order = new Order
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
CustomerName = customerName,
|
||||
OrderDate = orderDate,
|
||||
TotalAmount = 100m,
|
||||
DiscountAmount = 10m,
|
||||
ProductId = _productId,
|
||||
PekarId = _pekarId,
|
||||
StatusType = StatusType.Pending
|
||||
};
|
||||
CandyHouseDbContext.Orders.Add(order);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return order;
|
||||
}
|
||||
|
||||
private Pekar InsertPekarToDatabaseAndReturn(string positonId = null)
|
||||
{
|
||||
var pekar = new Pekar
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
FIO = "Test Pekar",
|
||||
PositionId = positonId, // Assuming a valid PositionId
|
||||
BonusCoefficient = 1.0m
|
||||
};
|
||||
CandyHouseDbContext.Pekars.Add(pekar);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return pekar;
|
||||
}
|
||||
|
||||
private Product InsertProductToDatabaseAndReturn()
|
||||
{
|
||||
var product = new Product
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Test Product",
|
||||
Description = "Test Description",
|
||||
OldName = "Test Old Name",
|
||||
OldDescription = "Test Old Description"
|
||||
};
|
||||
CandyHouseDbContext.Products.Add(product);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return product;
|
||||
}
|
||||
|
||||
private Order GetOrderFromDatabaseById(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Orders.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private OrderDataModel CreateOrderModel(string id, string customerName, DateTime orderDate, decimal totalAmount,
|
||||
decimal discountAmount)
|
||||
{
|
||||
return new OrderDataModel(id, customerName, orderDate, totalAmount, discountAmount, _productId, _pekarId,
|
||||
StatusType.Pending);
|
||||
}
|
||||
|
||||
private static void AssertOrder(OrderDataModel actual, Order expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.CustomerName, Is.EqualTo(expected.CustomerName));
|
||||
Assert.That(actual.OrderDate, Is.EqualTo(expected.OrderDate));
|
||||
Assert.That(actual.TotalAmount, Is.EqualTo(expected.TotalAmount));
|
||||
Assert.That(actual.DiscountAmount, Is.EqualTo(expected.DiscountAmount));
|
||||
Assert.That(actual.ProductId, Is.EqualTo(expected.ProductId));
|
||||
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
|
||||
Assert.That(actual.StatusType, Is.EqualTo(expected.StatusType));
|
||||
});
|
||||
}
|
||||
|
||||
private static void AssertOrder(Order actual, OrderDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.CustomerName, Is.EqualTo(expected.CustomerName));
|
||||
Assert.That(actual.OrderDate, Is.EqualTo(expected.OrderDate));
|
||||
Assert.That(actual.TotalAmount, Is.EqualTo(expected.TotalAmount));
|
||||
Assert.That(actual.DiscountAmount, Is.EqualTo(expected.DiscountAmount));
|
||||
Assert.That(actual.ProductId, Is.EqualTo(expected.ProductId));
|
||||
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
|
||||
Assert.That(actual.StatusType, Is.EqualTo(expected.StatusType));
|
||||
});
|
||||
}
|
||||
|
||||
private Position InsertPositionToDatabaseAndReturn(string? positionId = null)
|
||||
{
|
||||
var position = new Position
|
||||
{
|
||||
Id = positionId ?? Guid.NewGuid().ToString(), // Unique ID for each record
|
||||
PositionId = positionId ?? Guid.NewGuid().ToString(), // Unique ID for each record
|
||||
Type = PositionType.Cool, // Assuming string; adjust if PositionType enum is used
|
||||
Title = "TestPosition",
|
||||
IsActual = true,
|
||||
ChangeDate = DateTime.UtcNow
|
||||
};
|
||||
CandyHouseDbContext.Positions.Add(position);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Enums; // For PositionType if needed elsewhere
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class PekarStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private PekarStorageContract _pekarStorageContract;
|
||||
private Position _position;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_pekarStorageContract = new PekarStorageContract(CandyHouseDbContext);
|
||||
_position = InsertPositionToDatabaseAndReturn(); // Insert a default position for tests
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"PekarHistories\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenHaveRecords_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "Jane Smith");
|
||||
InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "Bob Johnson");
|
||||
|
||||
var list = _pekarStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(3));
|
||||
AssertElement(list.First(x => x.Id == pekar.Id), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenNoRecords_Test()
|
||||
{
|
||||
var list = _pekarStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_OnlyActive_Test()
|
||||
{
|
||||
InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "Jane Smith", false);
|
||||
InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "Bob Johnson", false);
|
||||
|
||||
var list = _pekarStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Has.Count.EqualTo(2));
|
||||
Assert.That(!list.Any(x => x.IsDeleted));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetPekarWithHistory_WhenHaveRecords_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
InsertPekarHistoryToDatabaseAndReturn(pekar.Id, "John Doe Old", _position.Id, 1.5m,
|
||||
DateTime.UtcNow.AddDays(-1));
|
||||
InsertPekarHistoryToDatabaseAndReturn(pekar.Id, "John Doe Older", _position.Id, 1.0m,
|
||||
DateTime.UtcNow.AddDays(-2));
|
||||
|
||||
var list = _pekarStorageContract.GetPekarWithHistory(pekar.Id);
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(2)); // History only, current pekar excluded if history exists
|
||||
Assert.That(list.Any(x => x.FIO == "John Doe Old"), Is.True);
|
||||
Assert.That(list.Any(x => x.FIO == "John Doe Older"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetPekarWithHistory_WhenNoHistory_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
|
||||
var list = _pekarStorageContract.GetPekarWithHistory(pekar.Id);
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(1)); // Only current pekar
|
||||
AssertElement(list.First(), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenHaveRecord_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
|
||||
AssertElement(_pekarStorageContract.GetElementById(pekar.Id), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenNoRecord_Test()
|
||||
{
|
||||
Assert.That(() => _pekarStorageContract.GetElementById(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenRecordIsDeleted_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
|
||||
Assert.That(() => _pekarStorageContract.GetElementById(pekar.Id),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByFio_WhenHaveRecord_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
var result = _pekarStorageContract.GetElementByFio(pekar.FIO);
|
||||
AssertElement(pekar, result); // Should match PekarDataModel, Pekar overload
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByFio_WhenNoRecord_Test()
|
||||
{
|
||||
Assert.That(() => _pekarStorageContract.GetElementByFio("Unknown"),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByFio_WhenRecordIsDeleted_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
|
||||
Assert.That(() => _pekarStorageContract.GetElementByFio(pekar.FIO),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_Test()
|
||||
{
|
||||
var pekar = CreateModel(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
|
||||
_pekarStorageContract.AddElement(pekar);
|
||||
AssertElement(GetPekarFromDatabaseById(pekar.Id), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_WhenIsDeletedIsTrue_Test()
|
||||
{
|
||||
var pekar = CreateModel(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
|
||||
_pekarStorageContract.AddElement(pekar);
|
||||
AssertElement(GetPekarFromDatabaseById(pekar.Id), CreateModel(pekar.Id, _position.Id, pekar.FIO, false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_Test()
|
||||
{
|
||||
var pekar = CreateModel(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
InsertPekarToDatabaseAndReturn(pekar.Id, _position.Id, "Jane Smith");
|
||||
|
||||
_pekarStorageContract.UpdateElement(pekar);
|
||||
AssertElement(GetPekarFromDatabaseById(pekar.Id), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenNoRecordWithThisId_Test()
|
||||
{
|
||||
var pekar = CreateModel(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
|
||||
Assert.That(() => _pekarStorageContract.UpdateElement(pekar),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenRecordWasDeleted_Test()
|
||||
{
|
||||
var pekar = CreateModel(Guid.NewGuid().ToString(), _position.Id, "John Doe");
|
||||
InsertPekarToDatabaseAndReturn(pekar.Id, _position.Id, "Jane Smith", true);
|
||||
|
||||
Assert.That(() => _pekarStorageContract.UpdateElement(pekar),
|
||||
Throws.TypeOf<ElementDeletedException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", false);
|
||||
|
||||
_pekarStorageContract.DeleteElement(pekar.Id);
|
||||
var element = GetPekarFromDatabaseById(pekar.Id);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.IsDeleted, Is.True);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_WhenNoRecordWithThisId_Test()
|
||||
{
|
||||
Assert.That(() => _pekarStorageContract.DeleteElement(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_WhenRecordWasDeleted_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
|
||||
Assert.That(() => _pekarStorageContract.DeleteElement(pekar.Id),
|
||||
Throws.TypeOf<ElementDeletedException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_RestoreElement_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", true);
|
||||
|
||||
_pekarStorageContract.RestoreElement(pekar.Id);
|
||||
var element = GetPekarFromDatabaseById(pekar.Id);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.IsDeleted, Is.False);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_RestoreElement_WhenNoRecordWithThisId_Test()
|
||||
{
|
||||
Assert.That(() => _pekarStorageContract.RestoreElement(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_RestoreElement_WhenRecordNotDeleted_Test()
|
||||
{
|
||||
var pekar = InsertPekarToDatabaseAndReturn(Guid.NewGuid().ToString(), _position.Id, "John Doe", false);
|
||||
|
||||
Assert.That(() => _pekarStorageContract.RestoreElement(pekar.Id),
|
||||
Throws.TypeOf<ElementDeletedException>());
|
||||
}
|
||||
|
||||
private Position InsertPositionToDatabaseAndReturn(string? positionId = null)
|
||||
{
|
||||
var position = new Position
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(), // Unique ID for each record
|
||||
PositionId = positionId ?? Guid.NewGuid().ToString(), // Unique ID for each record
|
||||
Type = PositionType.Cool, // Assuming string; adjust if PositionType enum is used
|
||||
Title = "TestPosition",
|
||||
IsActual = true,
|
||||
ChangeDate = DateTime.UtcNow
|
||||
};
|
||||
CandyHouseDbContext.Positions.Add(position);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return position;
|
||||
}
|
||||
|
||||
private Pekar InsertPekarToDatabaseAndReturn(string id, string positionId, string fio, bool isDeleted = false,
|
||||
decimal bonusCoefficient = 1.0m)
|
||||
{
|
||||
var pekar = new Pekar
|
||||
{
|
||||
Id = id,
|
||||
PositionId = positionId,
|
||||
FIO = fio,
|
||||
BonusCoefficient = bonusCoefficient,
|
||||
IsDeleted = isDeleted
|
||||
};
|
||||
CandyHouseDbContext.Pekars.Add(pekar);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return pekar;
|
||||
}
|
||||
|
||||
private PekarHistory InsertPekarHistoryToDatabaseAndReturn(string pekarId, string fio, string positionId,
|
||||
decimal bonusCoefficient, DateTime changeDate)
|
||||
{
|
||||
var history = new PekarHistory
|
||||
{
|
||||
PekarId = pekarId,
|
||||
FIO = fio,
|
||||
PositionId = positionId,
|
||||
BonusCoefficient = bonusCoefficient
|
||||
};
|
||||
CandyHouseDbContext.PekarHistories.Add(history);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return history;
|
||||
}
|
||||
|
||||
private static void AssertElement(PekarDataModel actual, Pekar expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.FIO, Is.EqualTo(expected.FIO));
|
||||
Assert.That(actual.Position, Is.EqualTo(expected.PositionId));
|
||||
Assert.That(actual.BonusCoefficient, Is.EqualTo(expected.BonusCoefficient));
|
||||
});
|
||||
}
|
||||
|
||||
private static PekarDataModel CreateModel(string id, string positionId, string fio, bool isDeleted = false,
|
||||
decimal bonusCoefficient = 1.0m)
|
||||
{
|
||||
return new PekarDataModel(id, fio, positionId, bonusCoefficient,
|
||||
new System.Collections.Generic.List<ProductDataModel>())
|
||||
{
|
||||
// Assuming IsDeleted isn't in PekarDataModel; adjust if needed
|
||||
};
|
||||
}
|
||||
|
||||
private Pekar GetPekarFromDatabaseById(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Pekars.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private static void AssertElement(Pekar actual, PekarDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.FIO, Is.EqualTo(expected.FIO));
|
||||
Assert.That(actual.PositionId, Is.EqualTo(expected.Position));
|
||||
Assert.That(actual.BonusCoefficient, Is.EqualTo(expected.BonusCoefficient));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Enums; // Add this for PositionType
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class PositionStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private PositionStorageContract _positionStorageContract;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_positionStorageContract = new PositionStorageContract(CandyHouseDbContext);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenHaveRecords_Test()
|
||||
{
|
||||
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
|
||||
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Medium, "Clerk");
|
||||
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Cool, "Supervisor",
|
||||
false); // Not actual
|
||||
|
||||
var list = _positionStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(2)); // Only actual positions
|
||||
AssertElement(list.First(x => x.Id == position.Id), position);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenNoRecords_Test()
|
||||
{
|
||||
var list = _positionStorageContract.GetList();
|
||||
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenHaveRecord_Test()
|
||||
{
|
||||
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
|
||||
Console.WriteLine($"Inserted PositionId: {position.PositionId}");
|
||||
Console.WriteLine($"Querying with id: {position.Id}");
|
||||
var result = _positionStorageContract.GetElementById(position.PositionId);
|
||||
Console.WriteLine($"Returned Id: {result.Id}");
|
||||
Console.WriteLine($"Position Id: {position.Id}");
|
||||
AssertElement(result, position);
|
||||
// Explicitly verify the Id matches PositionId
|
||||
Assert.That(result.Id, Is.EqualTo(position.Id),
|
||||
"PositionDataModel.Id should match Position.PositionId");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenNoRecord_Test()
|
||||
{
|
||||
Assert.That(() => _positionStorageContract.GetElementById(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_Test()
|
||||
{
|
||||
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
|
||||
|
||||
_positionStorageContract.AddElement(position);
|
||||
AssertElement(GetPositionFromDatabase(position.Id), position);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_WhenHaveRecordWithSameTitle_Test()
|
||||
{
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
InsertPositionToDatabaseAndReturn(positionId, PositionType.Small, "Manager");
|
||||
var duplicatePosition = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
|
||||
|
||||
Assert.That(() => _positionStorageContract.AddElement(duplicatePosition),
|
||||
Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenHaveRecord_Test()
|
||||
{
|
||||
var positionId = Guid.NewGuid().ToString();
|
||||
InsertPositionToDatabaseAndReturn(positionId, PositionType.Small, "Manager");
|
||||
var updatedPosition = CreateModel(positionId, PositionType.Cool, "Senior Manager");
|
||||
|
||||
_positionStorageContract.UpdateElement(updatedPosition);
|
||||
|
||||
var currentPosition = GetPositionFromDatabaseByPositionId(positionId, true);
|
||||
AssertElement(currentPosition, updatedPosition);
|
||||
var oldPosition = GetPositionFromDatabaseByPositionId(positionId, false);
|
||||
Assert.That(oldPosition, Is.Not.Null);
|
||||
Assert.That(oldPosition.IsActual, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenNoRecord_Test()
|
||||
{
|
||||
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
|
||||
|
||||
Assert.That(() => _positionStorageContract.UpdateElement(position),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
[Test]
|
||||
public void Try_UpdateElement_WhenDuplicateTitleExists_Test()
|
||||
{
|
||||
var positionId1 = Guid.NewGuid().ToString();
|
||||
var positionId2 = Guid.NewGuid().ToString();
|
||||
InsertPositionToDatabaseAndReturn(positionId1, PositionType.Small, "Manager");
|
||||
InsertPositionToDatabaseAndReturn(positionId2, PositionType.Medium, "Senior Manager");
|
||||
var updatedPosition = CreateModel(positionId1, PositionType.Cool, "Senior Manager");
|
||||
|
||||
Assert.That(() => _positionStorageContract.UpdateElement(updatedPosition),
|
||||
Throws.TypeOf<ElementExistsException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_Test()
|
||||
{
|
||||
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
|
||||
|
||||
_positionStorageContract.DeleteElement(position.PositionId);
|
||||
var deletedPosition = GetPositionFromDatabaseByPositionId(position.PositionId, true);
|
||||
Assert.That(deletedPosition, Is.Null);
|
||||
var historicalPosition = GetPositionFromDatabaseByPositionId(position.PositionId, false);
|
||||
Assert.That(historicalPosition, Is.Not.Null);
|
||||
Assert.That(historicalPosition.IsActual, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_WhenNoRecord_Test()
|
||||
{
|
||||
Assert.That(() => _positionStorageContract.DeleteElement(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_WhenAlreadyNotActual_Test()
|
||||
{
|
||||
var position =
|
||||
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager", false);
|
||||
|
||||
Assert.That(() => _positionStorageContract.DeleteElement(position.PositionId),
|
||||
Throws.TypeOf<ElementDeletedException>());
|
||||
}
|
||||
|
||||
private Position InsertPositionToDatabaseAndReturn(string positionId, PositionType type, string title,
|
||||
bool isActual = true)
|
||||
{
|
||||
var position = new Position
|
||||
{
|
||||
PositionId = positionId,
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Type = type,
|
||||
Title = title,
|
||||
IsActual = isActual,
|
||||
ChangeDate = DateTime.UtcNow
|
||||
};
|
||||
CandyHouseDbContext.Positions.Add(position);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return position;
|
||||
}
|
||||
|
||||
private static void AssertElement(PositionDataModel actual, Position expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Type, Is.EqualTo(expected.Type));
|
||||
Assert.That(actual.Title, Is.EqualTo(expected.Title));
|
||||
});
|
||||
}
|
||||
|
||||
private static void AssertElement(Position actual, PositionDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.PositionId, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Type, Is.EqualTo(expected.Type));
|
||||
Assert.That(actual.Title, Is.EqualTo(expected.Title));
|
||||
Assert.That(actual.IsActual, Is.True); // Assumes we only check actual records
|
||||
});
|
||||
}
|
||||
|
||||
private static PositionDataModel CreateModel(string id, PositionType type, string title)
|
||||
{
|
||||
return new PositionDataModel(id, type, title);
|
||||
}
|
||||
|
||||
private Position GetPositionFromDatabase(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Positions.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private Position GetPositionFromDatabaseByPositionId(string positionId, bool isActual)
|
||||
{
|
||||
return CandyHouseDbContext.Positions
|
||||
.Where(x => x.PositionId == positionId && x.IsActual == isActual)
|
||||
.OrderByDescending(x => x.ChangeDate)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class ProductStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private ProductStorageContract _productStorageContract;
|
||||
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_productStorageContract = new ProductStorageContract(CandyHouseDbContext);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Products\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Recipes\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Ingredients\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenNoRecords_Test()
|
||||
{
|
||||
var products = _productStorageContract.GetList();
|
||||
|
||||
Assert.That(products, Is.Not.Null);
|
||||
Assert.That(products, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_ValidProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1");
|
||||
|
||||
var result = _productStorageContract.GetElementById(product.Id);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertProduct(result, product);
|
||||
Assert.That(result.IngredientsItems, Has.Count.EqualTo(2));
|
||||
Assert.That(result.IngredientsItems.First().Name, Is.EqualTo("Ingredient1"));
|
||||
Assert.That(result.IngredientsItems.First().Cost, Is.EqualTo(10));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_NonExistentProduct_Test()
|
||||
{
|
||||
Assert.That(() => _productStorageContract.GetElementById(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_DeletedProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1", isDeleted: true);
|
||||
|
||||
var result = _productStorageContract.GetElementById(product.Id);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertProduct(result, product);
|
||||
Assert.That(result.IngredientsItems, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByName_ValidProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1");
|
||||
|
||||
var result = _productStorageContract.GetElementByName(product.Name);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertProduct(result, product);
|
||||
Assert.That(result.IngredientsItems, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByName_NonExistentProduct_Test()
|
||||
{
|
||||
Assert.That(() => _productStorageContract.GetElementByName("NonExistent"),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByName_DeletedProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1", isDeleted: true);
|
||||
|
||||
Assert.That(() => _productStorageContract.GetElementByName(product.Name),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByOldName_ValidProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1", oldName: "OldProduct1");
|
||||
|
||||
var result = _productStorageContract.GetElementByOldName(product.OldName);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertProduct(result, product);
|
||||
Assert.That(result.IngredientsItems, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByOldName_NonExistentProduct_Test()
|
||||
{
|
||||
Assert.That(() => _productStorageContract.GetElementByOldName("NonExistent"),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementByOldName_DeletedProduct_Test()
|
||||
{
|
||||
var product =
|
||||
InsertProductToDatabaseAndReturn("Product1", "Desc1", oldName: "OldProduct1", isDeleted: true);
|
||||
|
||||
Assert.That(() => _productStorageContract.GetElementByOldName(product.OldName),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_ValidProduct_Test()
|
||||
{
|
||||
var product = CreateProductModel(Guid.NewGuid().ToString(), "Product1", "Desc1");
|
||||
|
||||
_productStorageContract.AddElement(product);
|
||||
var dbProduct = GetProductFromDatabaseById(product.Id);
|
||||
|
||||
Assert.That(dbProduct, Is.Not.Null);
|
||||
AssertProduct(dbProduct, product);
|
||||
Assert.That(dbProduct.IsDeleted, Is.False);
|
||||
Assert.That(dbProduct.Recipes, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_DuplicateName_Test()
|
||||
{
|
||||
var product1 = CreateProductModel(Guid.NewGuid().ToString(), "Product1", "Desc1");
|
||||
_productStorageContract.AddElement(product1);
|
||||
|
||||
var product2 = CreateProductModel(Guid.NewGuid().ToString(), "Product1", "Desc2");
|
||||
|
||||
Assert.That(() => _productStorageContract.AddElement(product2),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_InvalidProduct_Test()
|
||||
{
|
||||
var product = CreateProductModel("", "", ""); // Invalid Id, Name, Description
|
||||
|
||||
Assert.That(() => _productStorageContract.AddElement(product),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_ValidProduct_Test()
|
||||
{
|
||||
var originalProduct = InsertProductToDatabaseAndReturn("Product1", "Desc1", "OldProduct1", "OldDesc1");
|
||||
var updatedProduct = CreateProductModel(originalProduct.Id, "UpdatedProduct", "UpdatedDesc");
|
||||
|
||||
_productStorageContract.UpdateElement(updatedProduct);
|
||||
var dbProduct = GetProductFromDatabaseById(updatedProduct.Id);
|
||||
|
||||
Assert.That(dbProduct, Is.Not.Null);
|
||||
AssertProduct(dbProduct, updatedProduct); // Should now pass
|
||||
Assert.That(dbProduct.OldName, Is.EqualTo("Product1")); // Already passes
|
||||
Assert.That(dbProduct.OldDescription, Is.EqualTo("Desc1")); // Already passes
|
||||
Assert.That(dbProduct.Recipes, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_NonExistentProduct_Test()
|
||||
{
|
||||
var product = CreateProductModel(Guid.NewGuid().ToString(), "Product1", "Desc1");
|
||||
|
||||
Assert.That(() => _productStorageContract.UpdateElement(product),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_DeletedProduct_Test()
|
||||
{
|
||||
var product = InsertProductToDatabaseAndReturn("Product1", "Desc1", isDeleted: true);
|
||||
var updatedProduct = CreateProductModel(product.Id, "UpdatedProduct", "UpdatedDesc");
|
||||
|
||||
Assert.That(() => _productStorageContract.UpdateElement(updatedProduct),
|
||||
Throws.TypeOf<ElementDeletedException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_NonExistentProduct_Test()
|
||||
{
|
||||
Assert.That(() => _productStorageContract.DeleteElement(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
// Helper Methods
|
||||
private Product InsertProductToDatabaseAndReturn(string name, string description, string oldName = "",
|
||||
string oldDescription = "", bool isDeleted = false)
|
||||
{
|
||||
|
||||
var ingredient1 = new Ingredient
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Ingredient1",
|
||||
Unit = "Unit1",
|
||||
Cost = 10m
|
||||
};
|
||||
var ingredient2 = new Ingredient
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Ingredient2",
|
||||
Unit = "Unit2",
|
||||
Cost = 20m
|
||||
};
|
||||
CandyHouseDbContext.Ingredients.AddRange(ingredient1, ingredient2);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
|
||||
var product = new Product
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = name,
|
||||
Description = description,
|
||||
OldName = oldName,
|
||||
OldDescription = oldDescription,
|
||||
IsDeleted = isDeleted,
|
||||
Recipes = new List<Recipe>
|
||||
{
|
||||
new Recipe { ProductId = Guid.NewGuid().ToString(), IngredientId = ingredient1.Id, Quantity = 5 },
|
||||
new Recipe { ProductId = Guid.NewGuid().ToString(), IngredientId = ingredient2.Id, Quantity = 10 }
|
||||
}
|
||||
};
|
||||
CandyHouseDbContext.Products.Add(product);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return product;
|
||||
}
|
||||
|
||||
private Product GetProductFromDatabaseById(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Products
|
||||
.Include(p => p.Recipes)
|
||||
.ThenInclude(r => r.Ingredient)
|
||||
.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private ProductDataModel CreateProductModel(string id, string name, string description, string oldName = "",
|
||||
string oldDescription = "")
|
||||
{
|
||||
var ingredients = new List<IngredientDataModel>
|
||||
{
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Ingredient1", "Unit1", 10m),
|
||||
new IngredientDataModel(Guid.NewGuid().ToString(), "Ingredient2", "Unit2", 20m)
|
||||
};
|
||||
return new ProductDataModel(id, name, description, oldName, oldDescription, ingredients);
|
||||
}
|
||||
|
||||
private static void AssertProduct(ProductDataModel actual, Product expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Name, Is.EqualTo(expected.Name));
|
||||
Assert.That(actual.Description, Is.EqualTo(expected.Description));
|
||||
});
|
||||
}
|
||||
|
||||
private static void AssertProduct(Product actual, ProductDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.Name, Is.EqualTo(expected.Name));
|
||||
Assert.That(actual.Description, Is.EqualTo(expected.Description));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseDataBase.Implementations;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CandyHouseTests.StoragesContracts
|
||||
{
|
||||
[TestFixture]
|
||||
internal class SalaryStorageContractTests : BaseStorageContractTest
|
||||
{
|
||||
private SalaryStorageContract _salaryStorageContract;
|
||||
private string _pekarId;
|
||||
private Position _position;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_salaryStorageContract = new SalaryStorageContract(CandyHouseDbContext);
|
||||
_position = InsertPositionToDatabaseAndReturn();
|
||||
_pekarId = InsertPekarToDatabaseAndReturn(_position.Id).Id; // Insert a Pekar for foreign key
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Salaries\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
|
||||
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenHaveRecords_Test()
|
||||
{
|
||||
var salary1 = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
var salary2 = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow.AddMonths(-1), 1100m, 300m, 1400m);
|
||||
|
||||
var salaries = _salaryStorageContract.GetList();
|
||||
|
||||
Assert.That(salaries, Is.Not.Null);
|
||||
Assert.That(salaries, Has.Count.EqualTo(2));
|
||||
AssertSalary(salaries.First(s => s.Id == salary1.Id), salary1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_WhenNoRecords_Test()
|
||||
{
|
||||
var salaries = _salaryStorageContract.GetList();
|
||||
|
||||
Assert.That(salaries, Is.Not.Null);
|
||||
Assert.That(salaries, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_ValidSalary_Test()
|
||||
{
|
||||
var salary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
|
||||
var result = _salaryStorageContract.GetElementById(salary.Id);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
AssertSalary(result, salary);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_NonExistentSalary_Test()
|
||||
{
|
||||
Assert.That(() => _salaryStorageContract.GetElementById(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_ValidSalary_Test()
|
||||
{
|
||||
var salary = CreateSalaryModel(Guid.NewGuid().ToString(), DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
|
||||
_salaryStorageContract.AddElement(salary);
|
||||
var dbSalary = GetSalaryFromDatabaseById(salary.Id);
|
||||
|
||||
Assert.That(dbSalary, Is.Not.Null);
|
||||
AssertSalary(dbSalary, salary);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_AddElement_InvalidSalary_Test()
|
||||
{
|
||||
var salary = CreateSalaryModel("", DateTime.UtcNow, -1000m, 200m, 1200m); // Invalid Id and BaseRate
|
||||
|
||||
Assert.That(() => _salaryStorageContract.AddElement(salary),
|
||||
Throws.TypeOf<ValidationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_ValidSalary_Test()
|
||||
{
|
||||
var originalSalary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
var updatedSalary = CreateSalaryModel(originalSalary.Id, DateTime.UtcNow.AddMonths(1), 1500m, 300m, 1800m);
|
||||
|
||||
_salaryStorageContract.UpdateElement(updatedSalary);
|
||||
var dbSalary = GetSalaryFromDatabaseById(updatedSalary.Id);
|
||||
|
||||
Assert.That(dbSalary, Is.Not.Null);
|
||||
AssertSalary(dbSalary, updatedSalary);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_UpdateElement_NonExistentSalary_Test()
|
||||
{
|
||||
var salary = CreateSalaryModel(Guid.NewGuid().ToString(), DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
|
||||
Assert.That(() => _salaryStorageContract.UpdateElement(salary),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_ValidSalary_Test()
|
||||
{
|
||||
var salary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
|
||||
|
||||
_salaryStorageContract.DeleteElement(salary.Id);
|
||||
var dbSalary = GetSalaryFromDatabaseById(salary.Id);
|
||||
|
||||
Assert.That(dbSalary, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_DeleteElement_NonExistentSalary_Test()
|
||||
{
|
||||
Assert.That(() => _salaryStorageContract.DeleteElement(Guid.NewGuid().ToString()),
|
||||
Throws.TypeOf<ElementNotFoundException>());
|
||||
}
|
||||
|
||||
// Helper Methods
|
||||
private Salary InsertSalaryToDatabaseAndReturn(DateTime period, decimal baseRate, decimal bonusRate,
|
||||
decimal totalSalary)
|
||||
{
|
||||
var salary = new Salary
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = _pekarId,
|
||||
Period = period,
|
||||
BaseRate = baseRate,
|
||||
BonusRate = bonusRate,
|
||||
TotalSalary = totalSalary
|
||||
};
|
||||
CandyHouseDbContext.Salaries.Add(salary);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return salary;
|
||||
}
|
||||
|
||||
private Pekar InsertPekarToDatabaseAndReturn(string positionId)
|
||||
{
|
||||
var pekar = new Pekar
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
FIO = "Test Pekar",
|
||||
PositionId = positionId,
|
||||
BonusCoefficient = 1.0m
|
||||
};
|
||||
CandyHouseDbContext.Pekars.Add(pekar);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return pekar;
|
||||
}
|
||||
|
||||
private Position InsertPositionToDatabaseAndReturn(string? positionId = null)
|
||||
{
|
||||
var position = new Position
|
||||
{
|
||||
Id = positionId ?? Guid.NewGuid().ToString(),
|
||||
PositionId = positionId ?? Guid.NewGuid().ToString(),
|
||||
Type = PositionType.Cool,
|
||||
Title = "TestPosition",
|
||||
IsActual = true,
|
||||
ChangeDate = DateTime.UtcNow
|
||||
};
|
||||
CandyHouseDbContext.Positions.Add(position);
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
return position;
|
||||
}
|
||||
|
||||
private Salary GetSalaryFromDatabaseById(string id)
|
||||
{
|
||||
return CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
private SalaryDataModel CreateSalaryModel(string id, DateTime period, decimal baseRate, decimal bonusRate,
|
||||
decimal totalSalary)
|
||||
{
|
||||
return new SalaryDataModel(id, _pekarId, period, baseRate, bonusRate, totalSalary);
|
||||
}
|
||||
|
||||
private static void AssertSalary(SalaryDataModel actual, Salary expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
|
||||
Assert.That(actual.Period, Is.EqualTo(expected.Period));
|
||||
Assert.That(actual.BaseRate, Is.EqualTo(expected.BaseRate));
|
||||
Assert.That(actual.BonusRate, Is.EqualTo(expected.BonusRate));
|
||||
Assert.That(actual.TotalSalary, Is.EqualTo(expected.TotalSalary));
|
||||
});
|
||||
}
|
||||
|
||||
private static void AssertSalary(Salary actual, SalaryDataModel expected)
|
||||
{
|
||||
Assert.That(actual, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(actual.Id, Is.EqualTo(expected.Id));
|
||||
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
|
||||
Assert.That(actual.Period, Is.EqualTo(expected.Period));
|
||||
Assert.That(actual.BaseRate, Is.EqualTo(expected.BaseRate));
|
||||
Assert.That(actual.BonusRate, Is.EqualTo(expected.BonusRate));
|
||||
Assert.That(actual.TotalSalary, Is.EqualTo(expected.TotalSalary));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="Microsoft.Extensions.Options" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="Moq" version="4.20.72" targetFramework="net471" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net471" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="Microsoft.Extensions.Primitives" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="Microsoft.TestPlatform.ObjectModel" version="17.12.0" targetFramework="net471" />
|
||||
@@ -21,10 +22,13 @@
|
||||
<package id="NUnit3TestAdapter" version="5.0.0" targetFramework="net471" />
|
||||
<package id="System.Buffers" version="4.6.0" targetFramework="net471" />
|
||||
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net471" />
|
||||
<package id="System.IO.Pipelines" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="System.Memory" version="4.6.0" targetFramework="net471" />
|
||||
<package id="System.Numerics.Vectors" version="4.6.0" targetFramework="net471" />
|
||||
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net471" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.0" targetFramework="net471" />
|
||||
<package id="System.Text.Encodings.Web" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="System.Text.Json" version="10.0.0-preview.1.25080.5" targetFramework="net471" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.6.0" targetFramework="net471" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net471" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user