lab4-preready
This commit is contained in:
@@ -9,6 +9,29 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="Contracts\BindingModels\IngredientBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\OrderBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\PekarBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\PekarHistoryBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\PositionBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\ProductBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\RecipeBindingModel.cs" />
|
||||
<Compile Include="Contracts\BindingModels\SalaryBindingModel.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\IngredientOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\OrderOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\PekarHistoryOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\PekarOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\PositionOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\ProductOperationResponse.cs" />
|
||||
<Compile Include="Contracts\OperationResponses\SalaryOperationResponse.cs" />
|
||||
<Compile Include="Contracts\ViewModels\IngredientViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\OrderViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\PekarHistoryViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\PekarViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\PositionViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\ProductViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\RecipeViewModel.cs" />
|
||||
<Compile Include="Contracts\ViewModels\SalaryViewModel.cs" />
|
||||
<Compile Include="DataModels\IngredientDataModel.cs" />
|
||||
<Compile Include="DataModels\OrderDataModel.cs" />
|
||||
<Compile Include="DataModels\PekarDataModel.cs" />
|
||||
@@ -36,6 +59,14 @@
|
||||
<Compile Include="Implementations\SalaryBusinessLogicContract.cs" />
|
||||
<Compile Include="Infrastructure\Infrastructure.cs" />
|
||||
<Compile Include="Infrastructure\IValidation.cs" />
|
||||
<Compile Include="Infrastructure\OperationResponse.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IIngredientAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IOrderAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IPekarAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IPekarHistoryAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IPositionAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\IProductAdapter.cs" />
|
||||
<Compile Include="Interfaces\Adapters\ISalaryAdapter.cs" />
|
||||
<Compile Include="Interfaces\BusinessLogicsContracts\IIngredientBusinessLogicContact.cs" />
|
||||
<Compile Include="Interfaces\BusinessLogicsContracts\IOrderBusinessLogicContact.cs" />
|
||||
<Compile Include="Interfaces\BusinessLogicsContracts\IPekarBusinessLogicContact.cs" />
|
||||
@@ -51,6 +82,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="CatHasPawsTests" />
|
||||
<InternalsVisibleTo Include="CandyHouseWebApi" />
|
||||
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -66,7 +98,10 @@
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.3.0" />
|
||||
<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>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class IngredientBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Unit { get; set; }
|
||||
public double Cost { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class OrderBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? ProductId { get; set; }
|
||||
public object Count { get; set; }
|
||||
public object Status { get; set; }
|
||||
public object DateCreate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class PekarBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public object FIO { get; set; }
|
||||
public object PhoneNumber { get; set; }
|
||||
public object Login { get; set; }
|
||||
public object Password { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class PekarHistoryBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? PekarId { get; set; }
|
||||
public string? PositionId { get; set; }
|
||||
public object DateStart { get; set; }
|
||||
public object DateEnd { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class PositionBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public object Name { get; set; }
|
||||
public object SalaryRate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class ProductBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public object Name { get; set; }
|
||||
public object Price { get; set; }
|
||||
public object StorageCount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class RecipeBindingModel
|
||||
{
|
||||
public string? ProductId { get; set; }
|
||||
public string? IngredientId { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace CandyHouseBase.Contracts.BindingModels;
|
||||
|
||||
public class SalaryBindingModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? PekarId { get; set; }
|
||||
public object Amount { get; set; }
|
||||
public object DateIssue { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class IngredientOperationResponse : OperationResponse
|
||||
{
|
||||
public static IngredientOperationResponse OK(List<IngredientViewModel> data) =>
|
||||
OK<IngredientOperationResponse, List<IngredientViewModel>>(data);
|
||||
|
||||
public static IngredientOperationResponse OK(IngredientViewModel data) =>
|
||||
OK<IngredientOperationResponse, IngredientViewModel>(data);
|
||||
|
||||
public static IngredientOperationResponse NoContent() =>
|
||||
NoContent<IngredientOperationResponse>();
|
||||
|
||||
public static IngredientOperationResponse NotFound(string message) =>
|
||||
NotFound<IngredientOperationResponse>(message);
|
||||
|
||||
public static IngredientOperationResponse BadRequest(string message) =>
|
||||
BadRequest<IngredientOperationResponse>(message);
|
||||
|
||||
public static IngredientOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<IngredientOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class OrderOperationResponse : OperationResponse
|
||||
{
|
||||
public static OrderOperationResponse OK(List<OrderViewModel> data) =>
|
||||
OK<OrderOperationResponse, List<OrderViewModel>>(data);
|
||||
|
||||
public static OrderOperationResponse OK(OrderViewModel data) =>
|
||||
OK<OrderOperationResponse, OrderViewModel>(data);
|
||||
|
||||
public static OrderOperationResponse NoContent() =>
|
||||
NoContent<OrderOperationResponse>();
|
||||
|
||||
public static OrderOperationResponse NotFound(string message) =>
|
||||
NotFound<OrderOperationResponse>(message);
|
||||
|
||||
public static OrderOperationResponse BadRequest(string message) =>
|
||||
BadRequest<OrderOperationResponse>(message);
|
||||
|
||||
public static OrderOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<OrderOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class PekarHistoryOperationResponse : OperationResponse
|
||||
{
|
||||
public static PekarHistoryOperationResponse OK(List<PekarHistoryViewModel> data) =>
|
||||
OK<PekarHistoryOperationResponse, List<PekarHistoryViewModel>>(data);
|
||||
|
||||
public static PekarHistoryOperationResponse OK(PekarHistoryViewModel data) =>
|
||||
OK<PekarHistoryOperationResponse, PekarHistoryViewModel>(data);
|
||||
|
||||
public static PekarHistoryOperationResponse NoContent() =>
|
||||
NoContent<PekarHistoryOperationResponse>();
|
||||
|
||||
public static PekarHistoryOperationResponse NotFound(string message) =>
|
||||
NotFound<PekarHistoryOperationResponse>(message);
|
||||
|
||||
public static PekarHistoryOperationResponse BadRequest(string message) =>
|
||||
BadRequest<PekarHistoryOperationResponse>(message);
|
||||
|
||||
public static PekarHistoryOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<PekarHistoryOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class PekarOperationResponse : OperationResponse
|
||||
{
|
||||
public static PekarOperationResponse OK(List<PekarViewModel> data) =>
|
||||
OK<PekarOperationResponse, List<PekarViewModel>>(data);
|
||||
|
||||
public static PekarOperationResponse OK(PekarViewModel data) =>
|
||||
OK<PekarOperationResponse, PekarViewModel>(data);
|
||||
|
||||
public static PekarOperationResponse NoContent() =>
|
||||
NoContent<PekarOperationResponse>();
|
||||
|
||||
public static PekarOperationResponse NotFound(string message) =>
|
||||
NotFound<PekarOperationResponse>(message);
|
||||
|
||||
public static PekarOperationResponse BadRequest(string message) =>
|
||||
BadRequest<PekarOperationResponse>(message);
|
||||
|
||||
public static PekarOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<PekarOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class PositionOperationResponse : OperationResponse
|
||||
{
|
||||
public static PositionOperationResponse OK(List<PositionViewModel> data) =>
|
||||
OK<PositionOperationResponse, List<PositionViewModel>>(data);
|
||||
|
||||
public static PositionOperationResponse OK(PositionViewModel data) =>
|
||||
OK<PositionOperationResponse, PositionViewModel>(data);
|
||||
|
||||
public static PositionOperationResponse NoContent() =>
|
||||
NoContent<PositionOperationResponse>();
|
||||
|
||||
public static PositionOperationResponse NotFound(string message) =>
|
||||
NotFound<PositionOperationResponse>(message);
|
||||
|
||||
public static PositionOperationResponse BadRequest(string message) =>
|
||||
BadRequest<PositionOperationResponse>(message);
|
||||
|
||||
public static PositionOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<PositionOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class ProductOperationResponse : OperationResponse
|
||||
{
|
||||
public static ProductOperationResponse OK(List<ProductViewModel> data) =>
|
||||
OK<ProductOperationResponse, List<ProductViewModel>>(data);
|
||||
|
||||
public static ProductOperationResponse OK(ProductViewModel data) =>
|
||||
OK<ProductOperationResponse, ProductViewModel>(data);
|
||||
|
||||
public static ProductOperationResponse NoContent() =>
|
||||
NoContent<ProductOperationResponse>();
|
||||
|
||||
public static ProductOperationResponse NotFound(string message) =>
|
||||
NotFound<ProductOperationResponse>(message);
|
||||
|
||||
public static ProductOperationResponse BadRequest(string message) =>
|
||||
BadRequest<ProductOperationResponse>(message);
|
||||
|
||||
public static ProductOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<ProductOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
public class SalaryOperationResponse : OperationResponse
|
||||
{
|
||||
public static SalaryOperationResponse OK(List<SalaryViewModel> data) =>
|
||||
OK<SalaryOperationResponse, List<SalaryViewModel>>(data);
|
||||
|
||||
public static SalaryOperationResponse OK(SalaryViewModel data) =>
|
||||
OK<SalaryOperationResponse, SalaryViewModel>(data);
|
||||
|
||||
public static SalaryOperationResponse NoContent() =>
|
||||
NoContent<SalaryOperationResponse>();
|
||||
|
||||
public static SalaryOperationResponse NotFound(string message) =>
|
||||
NotFound<SalaryOperationResponse>(message);
|
||||
|
||||
public static SalaryOperationResponse BadRequest(string message) =>
|
||||
BadRequest<SalaryOperationResponse>(message);
|
||||
|
||||
public static SalaryOperationResponse InternalServerError(string message) =>
|
||||
InternalServerError<SalaryOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class IngredientViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public required string Unit { get; set; }
|
||||
public double Cost { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class OrderViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public required string ProductId { get; set; }
|
||||
public object Count { get; set; }
|
||||
public object Status { get; set; }
|
||||
public object DateCreate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class PekarHistoryViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public required string PekarId { get; set; }
|
||||
public required string PositionId { get; set; }
|
||||
public object DateStart { get; set; }
|
||||
public object DateEnd { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class PekarViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public object FIO { get; set; }
|
||||
public object PhoneNumber { get; set; }
|
||||
public object Login { get; set; }
|
||||
public object Password { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class PositionViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public object Name { get; set; }
|
||||
public object SalaryRate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class ProductViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public object Name { get; set; }
|
||||
public object Price { get; set; }
|
||||
public object StorageCount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class RecipeViewModel
|
||||
{
|
||||
public string? ProductId { get; set; }
|
||||
public string? ProductName { get; set; }
|
||||
public string? IngredientId { get; set; }
|
||||
public string? IngredientName { get; set; }
|
||||
public string? Unit { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
public decimal Cost { get; set; }
|
||||
public decimal TotalCost { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace CandyHouseBase.Contracts.ViewModels;
|
||||
|
||||
public class SalaryViewModel
|
||||
{
|
||||
public required string Id { get; set; }
|
||||
public required string PekarId { get; set; }
|
||||
public string? PekarFIO { get; set; }
|
||||
public object Amount { get; set; }
|
||||
public object DateIssue { get; set; }
|
||||
}
|
||||
@@ -4,20 +4,13 @@ using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseBase.DataModels
|
||||
{
|
||||
public class IngredientDataModel : IValidation
|
||||
public class IngredientDataModel(string id, string name, string unit, decimal cost)
|
||||
: IValidation
|
||||
{
|
||||
public string Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Unit { get; private set; }
|
||||
public decimal Cost { get; private set; }
|
||||
|
||||
public IngredientDataModel(string id, string name, string unit, decimal cost)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Unit = unit;
|
||||
Cost = cost;
|
||||
}
|
||||
public string Id { get; private set; } = id;
|
||||
public string Name { get; private set; } = name;
|
||||
public string Unit { get; private set; } = unit;
|
||||
public decimal Cost { get; private set; } = cost;
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IIngredientAdapter
|
||||
{
|
||||
IngredientOperationResponse GetList();
|
||||
IngredientOperationResponse GetElement(string data);
|
||||
IngredientOperationResponse Register(IngredientBindingModel model);
|
||||
IngredientOperationResponse Update(IngredientBindingModel model);
|
||||
IngredientOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IOrderAdapter
|
||||
{
|
||||
OrderOperationResponse GetList();
|
||||
OrderOperationResponse GetElement(string data);
|
||||
OrderOperationResponse Register(OrderBindingModel model);
|
||||
OrderOperationResponse Update(OrderBindingModel model);
|
||||
OrderOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IPekarAdapter
|
||||
{
|
||||
PekarOperationResponse GetList();
|
||||
PekarOperationResponse GetElement(string data);
|
||||
PekarOperationResponse Register(PekarBindingModel model);
|
||||
PekarOperationResponse Update(PekarBindingModel model);
|
||||
PekarOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IPekarHistoryAdapter
|
||||
{
|
||||
PekarHistoryOperationResponse GetList();
|
||||
PekarHistoryOperationResponse GetElement(string data);
|
||||
PekarHistoryOperationResponse Register(PekarHistoryBindingModel model);
|
||||
PekarHistoryOperationResponse Update(PekarHistoryBindingModel model);
|
||||
PekarHistoryOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IPositionAdapter
|
||||
{
|
||||
PositionOperationResponse GetList();
|
||||
PositionOperationResponse GetElement(string data);
|
||||
PositionOperationResponse Register(PositionBindingModel model);
|
||||
PositionOperationResponse Update(PositionBindingModel model);
|
||||
PositionOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface IProductAdapter
|
||||
{
|
||||
ProductOperationResponse GetList();
|
||||
ProductOperationResponse GetElement(string data);
|
||||
ProductOperationResponse Register(ProductBindingModel model);
|
||||
ProductOperationResponse Update(ProductBindingModel model);
|
||||
ProductOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
public interface ISalaryAdapter
|
||||
{
|
||||
SalaryOperationResponse GetList();
|
||||
SalaryOperationResponse GetElement(string data);
|
||||
SalaryOperationResponse Register(SalaryBindingModel model);
|
||||
SalaryOperationResponse Update(SalaryBindingModel model);
|
||||
SalaryOperationResponse Delete(string id);
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using CandyHouseBase.DataModels;
|
||||
|
||||
namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
|
||||
|
||||
@@ -4,10 +4,15 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CandyHouseDataBase;
|
||||
|
||||
public class CandyHouseDbContext(IConfigurationDatabase configurationDatabase) : DbContext
|
||||
public class CandyHouseDbContext : DbContext
|
||||
{
|
||||
private readonly IConfigurationDatabase? _configurationDatabase = configurationDatabase;
|
||||
|
||||
private readonly IConfigurationDatabase? _configurationDatabase;
|
||||
public CandyHouseDbContext(IConfigurationDatabase configurationDatabase)
|
||||
{
|
||||
_configurationDatabase = configurationDatabase;
|
||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
|
||||
}
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseNpgsql(_configurationDatabase?.ConnectionString);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<InternalsVisibleTo Include="CandyHouseWebApi" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
|
||||
@@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseTests", "CandyHou
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseDataBase", "CandyHouseDataBase\CandyHouseDataBase.csproj", "{54F7ED2D-9E96-4546-BA6B-B65140E1F602}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyHouseWebApi", "CandyHouseWebApi\CandyHouseWebApi.csproj", "{4D0A5083-2F58-470C-8591-11EC2CE3B71B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -24,5 +26,9 @@ Global
|
||||
{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
|
||||
{4D0A5083-2F58-470C-8591-11EC2CE3B71B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4D0A5083-2F58-470C-8591-11EC2CE3B71B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D0A5083-2F58-470C-8591-11EC2CE3B71B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D0A5083-2F58-470C-8591-11EC2CE3B71B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
@@ -9,25 +9,30 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<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="coverlet.collector" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<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 -->
|
||||
<PackageReference Include="NUnit" Version="4.2.2" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.3.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
|
||||
<PackageReference Include="Serilog" Version="4.2.1-dev-02352" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
</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="..\CandyHouseBase\CandyHouseBase.csproj"/>
|
||||
<ProjectReference Include="..\CandyHouseDataBase\CandyHouseDataBase.csproj" />
|
||||
<ProjectReference Include="..\CandyHouseWebApi\CandyHouseWebApi.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="NUnit.Framework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.json">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CandyHouseTests.DataModelsTests
|
||||
{
|
||||
@@ -18,10 +18,10 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var ingredient = new IngredientDataModel(id, name, unit, cost);
|
||||
|
||||
Assert.AreEqual(id, ingredient.Id);
|
||||
Assert.AreEqual(name, ingredient.Name);
|
||||
Assert.AreEqual(unit, ingredient.Unit);
|
||||
Assert.AreEqual(cost, ingredient.Cost);
|
||||
Assert.That(id, Is.EqualTo(ingredient.Id));
|
||||
Assert.That(name, Is.EqualTo(ingredient.Name));
|
||||
Assert.That(unit, Is.EqualTo(ingredient.Unit));
|
||||
Assert.That(cost, Is.EqualTo(ingredient.Cost));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace CandyHouseTests.DataModelsTests
|
||||
var order = new OrderDataModel(id, customerName, orderDate, totalAmount, discountAmount, productId, pekarId,
|
||||
statusType);
|
||||
|
||||
Assert.AreEqual(id, order.Id);
|
||||
Assert.AreEqual(customerName, order.CustomerName);
|
||||
Assert.AreEqual(orderDate, order.OrderDate);
|
||||
Assert.AreEqual(totalAmount, order.TotalAmount);
|
||||
Assert.AreEqual(discountAmount, order.DiscountAmount);
|
||||
Assert.AreEqual(productId, order.ProductId);
|
||||
Assert.AreEqual(pekarId, order.PekarId);
|
||||
Assert.AreEqual(statusType, order.StatusType);
|
||||
Assert.That(id, Is.EqualTo(order.Id));
|
||||
Assert.That(customerName, Is.EqualTo(order.CustomerName));
|
||||
Assert.That(orderDate, Is.EqualTo(order.OrderDate));
|
||||
Assert.That(totalAmount, Is.EqualTo(order.TotalAmount));
|
||||
Assert.That(discountAmount, Is.EqualTo(order.DiscountAmount));
|
||||
Assert.That(productId, Is.EqualTo(order.ProductId));
|
||||
Assert.That(pekarId, Is.EqualTo(order.PekarId));
|
||||
Assert.That(statusType, Is.EqualTo(order.StatusType));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var pekar = new PekarDataModel(id, name, experience, 0, new List<ProductDataModel>());
|
||||
|
||||
Assert.AreEqual(id, pekar.Id);
|
||||
Assert.AreEqual(name, pekar.FIO);
|
||||
Assert.AreEqual(experience, pekar.Position);
|
||||
Assert.That(id, Is.EqualTo(pekar.Id));
|
||||
Assert.That(name, Is.EqualTo(pekar.FIO));
|
||||
Assert.That(experience, Is.EqualTo(pekar.Position));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var peKarHistory = new PekarHistoryDataModel(peKarId, fio, positionId, bonusCoefficient, dateTime);
|
||||
|
||||
Assert.AreEqual(peKarId, peKarHistory.PekarId);
|
||||
Assert.AreEqual(fio, peKarHistory.FIO);
|
||||
Assert.AreEqual(positionId, peKarHistory.PositionId);
|
||||
Assert.AreEqual(bonusCoefficient, peKarHistory.BonusCoefficient);
|
||||
Assert.AreEqual(dateTime, peKarHistory.Date);
|
||||
Assert.That(peKarId, Is.EqualTo(peKarHistory.PekarId));
|
||||
Assert.That(fio, Is.EqualTo(peKarHistory.FIO));
|
||||
Assert.That(positionId, Is.EqualTo(peKarHistory.PositionId));
|
||||
Assert.That(bonusCoefficient, Is.EqualTo(peKarHistory.BonusCoefficient));
|
||||
Assert.That(dateTime, Is.EqualTo(peKarHistory.Date));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,9 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var position = new PositionDataModel(id, type, title);
|
||||
|
||||
Assert.AreEqual(id, position.Id);
|
||||
Assert.AreEqual(type, position.Type);
|
||||
Assert.AreEqual(title, position.Title);
|
||||
Assert.That(id, Is.EqualTo(position.Id));
|
||||
Assert.That(type, Is.EqualTo(position.Type));
|
||||
Assert.That(title, Is.EqualTo(position.Title));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -19,10 +19,10 @@ namespace CandyHouseTests.DataModelsTests
|
||||
{ new IngredientDataModel(Guid.NewGuid().ToString(), "sugar", "Sugar", 10) };
|
||||
var product = new ProductDataModel(id, name, description, ingredients);
|
||||
|
||||
Assert.AreEqual(id, product.Id);
|
||||
Assert.AreEqual(name, product.Name);
|
||||
Assert.AreEqual(description, product.Description);
|
||||
Assert.AreEqual(ingredients, product.IngredientsItems);
|
||||
Assert.That(id, Is.EqualTo(product.Id));
|
||||
Assert.That(name, Is.EqualTo(product.Name));
|
||||
Assert.That(description, Is.EqualTo(product.Description));
|
||||
Assert.That(ingredients, Is.EqualTo(product.IngredientsItems));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var recipe = new RecipeDataModel(productId, ingredientId, quantity);
|
||||
|
||||
Assert.AreEqual(productId, recipe.ProductId);
|
||||
Assert.AreEqual(ingredientId, recipe.IngredientId);
|
||||
Assert.AreEqual(quantity, recipe.Quantity);
|
||||
Assert.That(productId, Is.EqualTo(recipe.ProductId));
|
||||
Assert.That(ingredientId, Is.EqualTo(recipe.IngredientId));
|
||||
Assert.That(quantity, Is.EqualTo(recipe.Quantity));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace CandyHouseTests.DataModelsTests
|
||||
|
||||
var salaryData = new SalaryDataModel(id, pekarId, period, baseRate, bonusRate, totalSalary);
|
||||
|
||||
Assert.AreEqual(id, salaryData.Id);
|
||||
Assert.AreEqual(pekarId, salaryData.PekarId);
|
||||
Assert.AreEqual(period, salaryData.Period);
|
||||
Assert.AreEqual(baseRate, salaryData.BaseRate);
|
||||
Assert.AreEqual(bonusRate, salaryData.BonusRate);
|
||||
Assert.AreEqual(totalSalary, salaryData.TotalSalary);
|
||||
Assert.That(id, Is.EqualTo(salaryData.Id));
|
||||
Assert.That(pekarId, Is.EqualTo(salaryData.PekarId));
|
||||
Assert.That(period, Is.EqualTo(salaryData.Period));
|
||||
Assert.That(baseRate, Is.EqualTo(salaryData.BaseRate));
|
||||
Assert.That(bonusRate, Is.EqualTo(salaryData.BonusRate));
|
||||
Assert.That(totalSalary, Is.EqualTo(salaryData.TotalSalary));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using CandyHouseDataBase;
|
||||
using CandyHouseDataBase.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CandyHouseTests.Infrastructure;
|
||||
|
||||
internal static class CandyHouseDbContextExtensions
|
||||
{
|
||||
public static Ingredient InsertIngredientToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string name = "Flour", string unit = "kg", decimal cost = 1.0m)
|
||||
{
|
||||
var model = new Ingredient { Id = id ?? Guid.NewGuid().ToString(), Name = name, Unit = unit, Cost = cost };
|
||||
db.Ingredients.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Order InsertOrderToDatabaseAndReturn(this CandyHouseDbContext db, string productId, string pekarId, string? id = null)
|
||||
{
|
||||
var model = new Order
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
ProductId = productId,
|
||||
PekarId = pekarId,
|
||||
OrderDate = DateTime.UtcNow,
|
||||
TotalAmount = 100,
|
||||
DiscountAmount = 10,
|
||||
StatusType = CandyHouseBase.Enums.StatusType.Pending
|
||||
};
|
||||
db.Orders.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Pekar InsertPekarToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string fio = "Pekar", string positionId = "default", decimal bonus = 1)
|
||||
{
|
||||
var model = new Pekar { Id = id ?? Guid.NewGuid().ToString(), FIO = fio, PositionId = positionId, BonusCoefficient = bonus };
|
||||
db.Pekars.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Position InsertPositionToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string title = "Baker")
|
||||
{
|
||||
var model = new Position { Id = id ?? Guid.NewGuid().ToString(), Title = title, IsActual = true };
|
||||
db.Positions.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Product InsertProductToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string name = "Cake")
|
||||
{
|
||||
var model = new Product { Id = id ?? Guid.NewGuid().ToString(), Name = name, Description = "Delicious cake" };
|
||||
db.Products.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Salary InsertSalaryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId, DateTime? period = null)
|
||||
{
|
||||
var model = new Salary
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = pekarId,
|
||||
Period = period ?? DateTime.UtcNow,
|
||||
BaseRate = 1000,
|
||||
BonusRate = 200,
|
||||
TotalSalary = 1200
|
||||
};
|
||||
db.Salaries.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static PekarHistory InsertPekarHistoryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId, string positionId)
|
||||
{
|
||||
var model = new PekarHistory
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = pekarId,
|
||||
PositionId = positionId,
|
||||
FIO = "Pekar Hist",
|
||||
Date = DateTime.UtcNow,
|
||||
BonusCoefficient = 1.2m
|
||||
};
|
||||
db.PekarHistories.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Recipe InsertRecipeToDatabaseAndReturn(this CandyHouseDbContext db, string productId, string ingredientId)
|
||||
{
|
||||
var model = new Recipe { ProductId = productId, IngredientId = ingredientId, Quantity = 1 };
|
||||
db.Recipes.Add(model);
|
||||
db.SaveChanges();
|
||||
return model;
|
||||
}
|
||||
|
||||
public static void RemoveIngredientsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Ingredients\" CASCADE;");
|
||||
public static void RemoveOrdersFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Orders\" CASCADE;");
|
||||
public static void RemovePekarsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
|
||||
public static void RemovePositionsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
|
||||
public static void RemoveProductsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Products\" CASCADE;");
|
||||
public static void RemoveSalariesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Salaries\" CASCADE;");
|
||||
public static void RemovePekarHistoriesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"PekarHistories\" CASCADE;");
|
||||
public static void RemoveRecipesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Recipes\" CASCADE;");
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using CandyHouseBase.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using CandyHouseWebApi;
|
||||
|
||||
namespace CandyHouseTests.Infrastructure;
|
||||
|
||||
internal class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram>
|
||||
where TProgram : class
|
||||
{
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
// Replace database configuration for tests
|
||||
var databaseConfig = services.SingleOrDefault(x => x.ServiceType == typeof(IConfigurationDatabase));
|
||||
if (databaseConfig is not null)
|
||||
services.Remove(databaseConfig);
|
||||
|
||||
services.AddSingleton<IConfigurationDatabase, ConfigurationDatabaseTest>();
|
||||
|
||||
// Replace logger if needed
|
||||
var loggerFactory = services.SingleOrDefault(x => x.ServiceType == typeof(LoggerFactory));
|
||||
if (loggerFactory is not null)
|
||||
services.Remove(loggerFactory);
|
||||
|
||||
// IMPORTANT: Don't remove or replace authentication services
|
||||
// Just configure them for testing
|
||||
|
||||
// Configure JWT for testing
|
||||
services.PostConfigure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
|
||||
{
|
||||
// For testing purposes, make validation less strict
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = AuthOptions.ISSUER,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = AuthOptions.AUDIENCE,
|
||||
ValidateLifetime = false, // Don't validate lifetime for tests
|
||||
IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
|
||||
ValidateIssuerSigningKey = true,
|
||||
RequireExpirationTime = false,
|
||||
ClockSkew = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
|
||||
// Log authentication events
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
Console.WriteLine("Token validated successfully!");
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
Console.WriteLine($"Authentication failed: {context.Exception}");
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
},
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
var token = context.Token;
|
||||
Console.WriteLine($"Token received: {token?.Substring(0, Math.Min(50, token?.Length ?? 0))}...");
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
},
|
||||
OnChallenge = context =>
|
||||
{
|
||||
Console.WriteLine($"Challenge: {context.Error}, {context.ErrorDescription}");
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Use Development environment for testing
|
||||
builder.UseEnvironment("Development");
|
||||
|
||||
base.ConfigureWebHost(builder);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ public class BaseStorageContractTest
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
|
||||
CandyHouseDbContext.Database.EnsureDeleted();
|
||||
CandyHouseDbContext.Dispose();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using CandyHouseDataBase;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using CandyHouseBase.Infrastructure;
|
||||
using System.Net.Http.Headers;
|
||||
using CandyHouseWebApi;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
internal class BaseWebApiControllerTest
|
||||
{
|
||||
private WebApplicationFactory<Program> _webApplication;
|
||||
|
||||
protected HttpClient HttpClient { get; private set; }
|
||||
|
||||
protected CandyHouseDbContext CandyHouseDbContext { get; private set; }
|
||||
|
||||
protected static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetUp()
|
||||
{
|
||||
_webApplication = new CustomWebApplicationFactory<Program>();
|
||||
HttpClient = _webApplication
|
||||
.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureTestServices(services =>
|
||||
{
|
||||
using var loggerFactory = new LoggerFactory();
|
||||
loggerFactory.AddSerilog(new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build())
|
||||
.CreateLogger());
|
||||
services.AddSingleton(loggerFactory);
|
||||
});
|
||||
})
|
||||
.CreateClient(new WebApplicationFactoryClientOptions
|
||||
{
|
||||
AllowAutoRedirect = false
|
||||
});
|
||||
|
||||
// Initialize database first
|
||||
CandyHouseDbContext = _webApplication.Services.GetRequiredService<CandyHouseDbContext>();
|
||||
CandyHouseDbContext.Database.EnsureDeleted();
|
||||
CandyHouseDbContext.Database.EnsureCreated();
|
||||
|
||||
// IMPORTANT: Don't use the login endpoint - generate a token directly
|
||||
// The error suggests there's an issue with the token format from the endpoint
|
||||
var token = GenerateTestToken("user");
|
||||
Console.WriteLine($"Generated token manually: {token.Substring(0, Math.Min(50, token.Length))}...");
|
||||
|
||||
// Set the token with proper Bearer format - using AuthenticationHeaderValue
|
||||
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
// Let's make sure our auth header looks correct
|
||||
var authHeader = HttpClient.DefaultRequestHeaders.Authorization;
|
||||
Console.WriteLine($"Authorization header set: {authHeader?.Scheme} {authHeader?.Parameter?.Substring(0, Math.Min(50, authHeader?.Parameter?.Length ?? 0))}...");
|
||||
|
||||
// OPTIONAL: Add a delay to ensure any async setup completes
|
||||
// System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
// Generate a token manually to avoid any issues with the login endpoint
|
||||
private string GenerateTestToken(string username)
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, username),
|
||||
new Claim(JwtRegisteredClaimNames.Sub, username),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
||||
};
|
||||
|
||||
var key = AuthOptions.GetSymmetricSecurityKey();
|
||||
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
var token = new JwtSecurityToken(
|
||||
issuer: AuthOptions.ISSUER,
|
||||
audience: AuthOptions.AUDIENCE,
|
||||
claims: claims,
|
||||
expires: DateTime.UtcNow.AddHours(1),
|
||||
signingCredentials: creds
|
||||
);
|
||||
|
||||
return new JwtSecurityTokenHandler().WriteToken(token);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
CandyHouseDbContext?.Database.EnsureDeleted();
|
||||
CandyHouseDbContext?.Dispose();
|
||||
HttpClient?.Dispose();
|
||||
_webApplication?.Dispose();
|
||||
}
|
||||
|
||||
protected static async Task<T?> GetModelFromResponseAsync<T>(HttpResponseMessage response) =>
|
||||
JsonSerializer.Deserialize<T>(await response.Content.ReadAsStringAsync(), JsonSerializerOptions);
|
||||
|
||||
protected static StringContent MakeContent(object model) =>
|
||||
new(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json");
|
||||
|
||||
protected static void AssertElement(object actual, object expected)
|
||||
{
|
||||
foreach (var property in expected.GetType().GetProperties())
|
||||
{
|
||||
var actualValue = actual.GetType().GetProperty(property.Name)?.GetValue(actual);
|
||||
var expectedValue = property.GetValue(expected);
|
||||
|
||||
if (property.PropertyType.IsClass && property.PropertyType != typeof(string))
|
||||
continue;
|
||||
|
||||
Assert.That(actualValue, Is.EqualTo(expectedValue), $"Property {property.Name} does not match. Expected: {expectedValue}, Actual: {actualValue}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class IngredientControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemoveIngredientsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var ingredient = CandyHouseDbContext.InsertIngredientToDatabaseAndReturn(name: "Sugar");
|
||||
CandyHouseDbContext.InsertIngredientToDatabaseAndReturn(name: "Salt");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/ingredients");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<IngredientViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
AssertElement(data.First(x => x.Id == ingredient.Id), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
var response = await HttpClient.GetAsync("/api/ingredients");
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<IngredientViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
var ingredient = CandyHouseDbContext.InsertIngredientToDatabaseAndReturn();
|
||||
var response = await HttpClient.GetAsync($"/api/ingredients/{ingredient.Id}");
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
AssertElement(await GetModelFromResponseAsync<IngredientViewModel>(response), ingredient);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
CandyHouseDbContext.InsertIngredientToDatabaseAndReturn();
|
||||
var response = await HttpClient.GetAsync($"/api/ingredients/{Guid.NewGuid()}");
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
var model = new IngredientBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Cocoa",
|
||||
Unit = "g",
|
||||
Cost = 100
|
||||
};
|
||||
var response = await HttpClient.PostAsync("/api/ingredients", MakeContent(model));
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
AssertElement(CandyHouseDbContext.Ingredients.First(x => x.Id == model.Id), model);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
var modelWithEmptyName = new IngredientBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "",
|
||||
Unit = "g",
|
||||
Cost = 1
|
||||
};
|
||||
|
||||
var modelWithNegativeCost = new IngredientBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = "Invalid",
|
||||
Unit = "g",
|
||||
Cost = -10
|
||||
};
|
||||
|
||||
var response1 = await HttpClient.PostAsync("/api/ingredients", MakeContent(modelWithEmptyName));
|
||||
var response2 = await HttpClient.PostAsync("/api/ingredients", MakeContent(modelWithNegativeCost));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response1.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
Assert.That(response2.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test()
|
||||
{
|
||||
var response = await HttpClient.PostAsync("/api/ingredients", MakeContent(string.Empty));
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Enums;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class OrderControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
private string _pekarId;
|
||||
private string _productId;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: position.Id);
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
|
||||
_pekarId = pekar.Id;
|
||||
_productId = product.Id;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemoveOrdersFromDatabase();
|
||||
CandyHouseDbContext.RemovePekarsFromDatabase();
|
||||
CandyHouseDbContext.RemovePositionsFromDatabase();
|
||||
CandyHouseDbContext.RemoveProductsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var order = CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders?fromDate={DateTime.UtcNow.AddDays(-1):yyyy-MM-dd}&toDate={DateTime.UtcNow.AddDays(1):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<OrderViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
AssertElement(data.First(x => x.Id == order.Id), order);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders?fromDate={DateTime.UtcNow.AddDays(-1):yyyy-MM-dd}&toDate={DateTime.UtcNow.AddDays(1):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<OrderViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByDateRange_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var yesterday = DateTime.UtcNow.AddDays(-1);
|
||||
var tomorrow = DateTime.UtcNow.AddDays(1);
|
||||
|
||||
// Orders outside the range we'll query
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
var pastOrder = CandyHouseDbContext.Orders.First();
|
||||
pastOrder.OrderDate = yesterday.AddDays(-1);
|
||||
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
var futureOrder = CandyHouseDbContext.Orders.Skip(1).First();
|
||||
futureOrder.OrderDate = tomorrow.AddDays(1);
|
||||
|
||||
// Orders within the range
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
var inRangeOrder = CandyHouseDbContext.Orders.Skip(2).First();
|
||||
inRangeOrder.OrderDate = yesterday.AddHours(12);
|
||||
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders?fromDate={yesterday:yyyy-MM-dd}&toDate={tomorrow:yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<OrderViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPekarId_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var anotherPekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Another Baker");
|
||||
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, anotherPekar.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders/pekar/{_pekarId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<OrderViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(1));
|
||||
Assert.That(data[0].ProductId, Is.EqualTo(_productId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var order = CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders/{order.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<OrderViewModel>(response);
|
||||
AssertElement(result, order);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/orders/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var orderModel = CreateModel(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/orders", MakeContent(orderModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedOrder = CandyHouseDbContext.Orders.FirstOrDefault(x => x.Id == orderModel.Id);
|
||||
Assert.That(savedOrder, Is.Not.Null);
|
||||
Assert.That(savedOrder.ProductId, Is.EqualTo(orderModel.ProductId));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var orderModel = CreateModel(_productId, _pekarId);
|
||||
CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId, orderModel.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/orders", MakeContent(orderModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var order = CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
var orderModel = new OrderBindingModel
|
||||
{
|
||||
Id = order.Id,
|
||||
ProductId = _productId,
|
||||
Count = 5,
|
||||
Status = StatusType.Completed,
|
||||
DateCreate = DateTime.UtcNow
|
||||
};
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/orders", MakeContent(orderModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedOrder = CandyHouseDbContext.Orders.FirstOrDefault(x => x.Id == order.Id);
|
||||
Assert.That(updatedOrder, Is.Not.Null);
|
||||
Assert.That(updatedOrder.StatusType, Is.EqualTo(StatusType.Completed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var orderModel = CreateModel(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/orders", MakeContent(orderModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var order = CandyHouseDbContext.InsertOrderToDatabaseAndReturn(_productId, _pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/orders/{order.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedOrder = CandyHouseDbContext.Orders.FirstOrDefault(x => x.Id == order.Id);
|
||||
// Check that the order is completely deleted or marked as canceled in some way
|
||||
Assert.That(deletedOrder, Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/orders/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static OrderBindingModel CreateModel(string productId, string pekarId, string? id = null)
|
||||
{
|
||||
return new OrderBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
ProductId = productId,
|
||||
Count = 1,
|
||||
Status = StatusType.Pending,
|
||||
DateCreate = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class PekarControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
private Position _position;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemovePekarsFromDatabase();
|
||||
CandyHouseDbContext.RemovePositionsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Ivan Petrov", positionId: _position.Id);
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Maria Ivanova", positionId: _position.Id);
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Alex Smith", positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/pekars");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
});
|
||||
AssertElement(data.First(x => x.Id == pekar.Id), pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/pekars");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_OnlyActive_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Inactive Baker", positionId: _position.Id);
|
||||
var inactivePekar = CandyHouseDbContext.Pekars.First(x => x.FIO == "Inactive Baker");
|
||||
inactivePekar.IsDeleted = true;
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Active Baker", positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/pekars?onlyActive=true");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(1));
|
||||
Assert.That(data[0].FIO, Is.EqualTo("Active Baker"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekars/{pekar.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<PekarViewModel>(response);
|
||||
AssertElement(result, pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekars/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: _position.Id);
|
||||
pekar.IsDeleted = true;
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekars/{pekar.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ByFIO_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Unique Baker", positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekars/fio/{pekar.FIO}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<PekarViewModel>(response);
|
||||
AssertElement(result, pekar);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekarModel = CreateModel(_position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/pekars", MakeContent(pekarModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedPekar = CandyHouseDbContext.Pekars.FirstOrDefault(x => x.Id == pekarModel.Id);
|
||||
Assert.That(savedPekar, Is.Not.Null);
|
||||
Assert.That(savedPekar.FIO, Is.EqualTo(pekarModel.FIO.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekarModel = CreateModel(_position.Id);
|
||||
CandyHouseDbContext.InsertPekarToDatabaseAndReturn(pekarModel.Id, positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/pekars", MakeContent(pekarModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekarModelWithInvalidFIO = new PekarBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(), FIO = "", PhoneNumber = "+7-123-456-7890", Login = "baker1",
|
||||
Password = "password"
|
||||
};
|
||||
var pekarModelWithInvalidPhone = new PekarBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(), FIO = "Valid Name", PhoneNumber = "invalid", Login = "baker1",
|
||||
Password = "password"
|
||||
};
|
||||
//Act
|
||||
var responseWithInvalidFIO = await HttpClient.PostAsync($"/api/pekars", MakeContent(pekarModelWithInvalidFIO));
|
||||
var responseWithInvalidPhone =
|
||||
await HttpClient.PostAsync($"/api/pekars", MakeContent(pekarModelWithInvalidPhone));
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(responseWithInvalidFIO.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "FIO is invalid");
|
||||
Assert.That(responseWithInvalidPhone.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest),
|
||||
"Phone number is invalid");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: _position.Id);
|
||||
var pekarModel = new PekarBindingModel
|
||||
{
|
||||
Id = pekar.Id,
|
||||
FIO = "Updated Baker",
|
||||
PhoneNumber = "+7-999-888-7777",
|
||||
Login = "updated_login",
|
||||
Password = "updated_password"
|
||||
};
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/pekars", MakeContent(pekarModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedPekar = CandyHouseDbContext.Pekars.FirstOrDefault(x => x.Id == pekar.Id);
|
||||
Assert.That(updatedPekar, Is.Not.Null);
|
||||
Assert.That(updatedPekar.FIO, Is.EqualTo(pekarModel.FIO.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekarModel = CreateModel(_position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/pekars", MakeContent(pekarModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: _position.Id);
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/pekars/{pekar.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedPekar = CandyHouseDbContext.Pekars.FirstOrDefault(x => x.Id == pekar.Id);
|
||||
Assert.That(deletedPekar.IsDeleted, Is.True);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/pekars/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static PekarBindingModel CreateModel(string positionId, string? id = null, string fio = "Test Baker")
|
||||
{
|
||||
return new PekarBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
FIO = fio,
|
||||
PhoneNumber = "+7-123-456-7890",
|
||||
Login = "baker1",
|
||||
Password = "password"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class PekarHistoryControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
private string _pekarId;
|
||||
private string _positionId;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: position.Id);
|
||||
_pekarId = pekar.Id;
|
||||
_positionId = position.Id;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemovePekarHistoriesFromDatabase();
|
||||
CandyHouseDbContext.RemovePekarsFromDatabase();
|
||||
CandyHouseDbContext.RemovePositionsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var history = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/pekarhistory");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarHistoryViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
Assert.That(data.Any(x => x.Id == history.Id));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/pekarhistory");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarHistoryViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPekarId_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var anotherPekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Another Baker");
|
||||
|
||||
CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(anotherPekar.Id, _positionId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekarhistory/pekar/{_pekarId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarHistoryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.All(x => x.PekarId == _pekarId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var yesterday = DateTime.UtcNow.AddDays(-1);
|
||||
var tomorrow = DateTime.UtcNow.AddDays(1);
|
||||
var lastWeek = DateTime.UtcNow.AddDays(-7);
|
||||
var nextWeek = DateTime.UtcNow.AddDays(7);
|
||||
|
||||
var h1 = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
h1.Date = yesterday;
|
||||
|
||||
var h2 = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
h2.Date = lastWeek;
|
||||
|
||||
var h3 = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
h3.Date = nextWeek;
|
||||
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekarhistory/period?fromDate={yesterday.AddHours(-1):yyyy-MM-dd HH:mm:ss}&toDate={tomorrow:yyyy-MM-dd HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PekarHistoryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(1));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var history = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekarhistory/{history.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<PekarHistoryViewModel>(response);
|
||||
AssertElement(result, history);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/pekarhistory/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var historyModel = CreateModel(_pekarId, _positionId);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/pekarhistory", MakeContent(historyModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedHistory = CandyHouseDbContext.PekarHistories.FirstOrDefault(x => x.Id == historyModel.Id);
|
||||
Assert.That(savedHistory, Is.Not.Null);
|
||||
Assert.That(savedHistory.PekarId, Is.EqualTo(historyModel.PekarId));
|
||||
Assert.That(savedHistory.PositionId, Is.EqualTo(historyModel.PositionId));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var historyModel = CreateModel(_pekarId, _positionId);
|
||||
var existingHistory = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
historyModel.Id = existingHistory.Id;
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/pekarhistory", MakeContent(historyModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var history = CandyHouseDbContext.InsertPekarHistoryToDatabaseAndReturn(_pekarId, _positionId);
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/pekarhistory/{history.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedHistory = CandyHouseDbContext.PekarHistories.FirstOrDefault(x => x.Id == history.Id);
|
||||
Assert.That(deletedHistory, Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/pekarhistory/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static PekarHistoryBindingModel CreateModel(string pekarId, string positionId, string? id = null)
|
||||
{
|
||||
return new PekarHistoryBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
PekarId = pekarId,
|
||||
PositionId = positionId,
|
||||
DateStart = DateTime.UtcNow.AddDays(-30),
|
||||
DateEnd = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class PositionControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemovePekarsFromDatabase();
|
||||
CandyHouseDbContext.RemovePositionsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Head Baker");
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Pastry Chef");
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Assistant");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/positions");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PositionViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
});
|
||||
AssertElement(data.First(x => x.Id == position.Id), position);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/positions");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PositionViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_OnlyActual_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Obsolete Position");
|
||||
var positionToUpdate = CandyHouseDbContext.Positions.First(x => x.Title == "Obsolete Position");
|
||||
positionToUpdate.IsActual = false;
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Current Position");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/positions?onlyActual=true");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<PositionViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(1));
|
||||
Assert.That(data[0].Name, Is.EqualTo("Current Position"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/positions/{position.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<PositionViewModel>(response);
|
||||
AssertElement(result, position);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/positions/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
position.IsActual = false;
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/positions/{position.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ByTitle_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: "Master Baker");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/positions/title/{position.Title}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<PositionViewModel>(response);
|
||||
AssertElement(result, position);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var positionModel = CreateModel();
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/positions", MakeContent(positionModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedPosition = CandyHouseDbContext.Positions.FirstOrDefault(x => x.Id == positionModel.Id);
|
||||
Assert.That(savedPosition, Is.Not.Null);
|
||||
Assert.That(savedPosition.Title, Is.EqualTo(positionModel.Name.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var positionModel = CreateModel();
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(positionModel.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/positions", MakeContent(positionModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameTitle_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var positionModel = CreateModel(name: "Unique Position");
|
||||
CandyHouseDbContext.InsertPositionToDatabaseAndReturn(title: positionModel.Name.ToString());
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/positions", MakeContent(positionModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var positionModelWithInvalidName = new PositionBindingModel { Id = Guid.NewGuid().ToString(), Name = "", SalaryRate = 1000 };
|
||||
var positionModelWithInvalidSalary = new PositionBindingModel { Id = Guid.NewGuid().ToString(), Name = "Valid Name", SalaryRate = -100 };
|
||||
//Act
|
||||
var responseWithInvalidName = await HttpClient.PostAsync($"/api/positions", MakeContent(positionModelWithInvalidName));
|
||||
var responseWithInvalidSalary = await HttpClient.PostAsync($"/api/positions", MakeContent(positionModelWithInvalidSalary));
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(responseWithInvalidName.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is invalid");
|
||||
Assert.That(responseWithInvalidSalary.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Salary is invalid");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
var positionModel = new PositionBindingModel
|
||||
{
|
||||
Id = position.Id,
|
||||
Name = "Updated Position",
|
||||
SalaryRate = 2500
|
||||
};
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/positions", MakeContent(positionModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedPosition = CandyHouseDbContext.Positions.FirstOrDefault(x => x.Id == position.Id);
|
||||
Assert.That(updatedPosition, Is.Not.Null);
|
||||
Assert.That(updatedPosition.Title, Is.EqualTo(positionModel.Name.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var positionModel = CreateModel();
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/positions", MakeContent(positionModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/positions/{position.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedPosition = CandyHouseDbContext.Positions.FirstOrDefault(x => x.Id == position.Id);
|
||||
Assert.That(deletedPosition.IsActual, Is.False);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/positions/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static PositionBindingModel CreateModel(string? id = null, string name = "Baker Position")
|
||||
{
|
||||
return new PositionBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
Name = name,
|
||||
SalaryRate = 2000
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class ProductControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemoveRecipesFromDatabase();
|
||||
CandyHouseDbContext.RemoveProductsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: "Donut");
|
||||
CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: "Cupcake");
|
||||
CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: "Cookie");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/products");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
});
|
||||
AssertElement(data.First(x => x.Id == product.Id), product);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/products");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/products/{product.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<ProductViewModel>(response);
|
||||
AssertElement(result, product);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/products/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
product.IsDeleted = true;
|
||||
CandyHouseDbContext.SaveChanges();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/products/{product.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ByName_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/products/name/{product.Name}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<ProductViewModel>(response);
|
||||
AssertElement(result, product);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ByName_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/products/name/NonExistentProduct");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var productModel = CreateModel();
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedProduct = CandyHouseDbContext.Products.FirstOrDefault(x => x.Id == productModel.Id);
|
||||
Assert.That(savedProduct, Is.Not.Null);
|
||||
Assert.That(savedProduct.Name, Is.EqualTo(productModel.Name.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var productModel = CreateModel();
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn(productModel.Id);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameName_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var productModel = CreateModel();
|
||||
CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: productModel.Name.ToString());
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var productModelWithInvalidName = new ProductBindingModel { Id = Guid.NewGuid().ToString(), Name = "", Price = 10, StorageCount = 5 };
|
||||
var productModelWithInvalidPrice = new ProductBindingModel { Id = Guid.NewGuid().ToString(), Name = "Valid Name", Price = -10, StorageCount = 5 };
|
||||
//Act
|
||||
var responseWithInvalidName = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithInvalidName));
|
||||
var responseWithInvalidPrice = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithInvalidPrice));
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(responseWithInvalidName.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is invalid");
|
||||
Assert.That(responseWithInvalidPrice.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is invalid");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
var productModel = new ProductBindingModel
|
||||
{
|
||||
Id = product.Id,
|
||||
Name = "Updated Product",
|
||||
Price = 15.99,
|
||||
StorageCount = 50
|
||||
};
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedProduct = CandyHouseDbContext.Products.FirstOrDefault(x => x.Id == product.Id);
|
||||
Assert.That(updatedProduct, Is.Not.Null);
|
||||
Assert.That(updatedProduct.Name, Is.EqualTo(productModel.Name.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var productModel = CreateModel();
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/products/{product.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedProduct = CandyHouseDbContext.Products.FirstOrDefault(x => x.Id == product.Id);
|
||||
Assert.That(deletedProduct.IsDeleted, Is.True);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/products/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static ProductBindingModel CreateModel(string? id = null, string name = "Test Product")
|
||||
{
|
||||
return new ProductBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
Name = name,
|
||||
Price = 9.99,
|
||||
StorageCount = 10
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class RecipeControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
private string _productId;
|
||||
private string _ingredientId;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
var product = CandyHouseDbContext.InsertProductToDatabaseAndReturn();
|
||||
var ingredient = CandyHouseDbContext.InsertIngredientToDatabaseAndReturn();
|
||||
|
||||
_productId = product.Id;
|
||||
_ingredientId = ingredient.Id;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemoveRecipesFromDatabase();
|
||||
CandyHouseDbContext.RemoveProductsFromDatabase();
|
||||
CandyHouseDbContext.RemoveIngredientsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByProduct_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var recipe = CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
var secondIngredient = CandyHouseDbContext.InsertIngredientToDatabaseAndReturn(name: "Sugar");
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, secondIngredient.Id);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/recipes/product/{_productId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<RecipeViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.All(x => x.ProductId == _productId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByProduct_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var anotherProduct = CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: "Another Product");
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(anotherProduct.Id, _ingredientId);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/recipes/product/{_productId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<RecipeViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByIngredient_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var recipe = CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
var secondProduct = CandyHouseDbContext.InsertProductToDatabaseAndReturn(name: "Muffin");
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(secondProduct.Id, _ingredientId);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/recipes/ingredient/{_ingredientId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<RecipeViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.All(x => x.IngredientId == _ingredientId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/recipes/{_productId}/{_ingredientId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<RecipeViewModel>(response);
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.ProductId, Is.EqualTo(_productId));
|
||||
Assert.That(result.IngredientId, Is.EqualTo(_ingredientId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/recipes/{_productId}/{_ingredientId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var recipeModel = CreateModel(_productId, _ingredientId);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/recipes", MakeContent(recipeModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedRecipe = CandyHouseDbContext.Recipes.FirstOrDefault(x =>
|
||||
x.ProductId == recipeModel.ProductId && x.IngredientId == recipeModel.IngredientId);
|
||||
Assert.That(savedRecipe, Is.Not.Null);
|
||||
Assert.That(savedRecipe.Quantity, Is.EqualTo(recipeModel.Quantity));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenRecordAlreadyExists_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
var recipeModel = CreateModel(_productId, _ingredientId);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/recipes", MakeContent(recipeModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
var recipeModel = CreateModel(_productId, _ingredientId, 5);
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/recipes", MakeContent(recipeModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedRecipe = CandyHouseDbContext.Recipes.FirstOrDefault(x =>
|
||||
x.ProductId == recipeModel.ProductId && x.IngredientId == recipeModel.IngredientId);
|
||||
Assert.That(updatedRecipe, Is.Not.Null);
|
||||
Assert.That(updatedRecipe.Quantity, Is.EqualTo(recipeModel.Quantity));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var recipeModel = CreateModel(_productId, _ingredientId);
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/recipes", MakeContent(recipeModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
CandyHouseDbContext.InsertRecipeToDatabaseAndReturn(_productId, _ingredientId);
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/recipes/{_productId}/{_ingredientId}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedRecipe = CandyHouseDbContext.Recipes.FirstOrDefault(x =>
|
||||
x.ProductId == _productId && x.IngredientId == _ingredientId);
|
||||
Assert.That(deletedRecipe, Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/recipes/{_productId}/{_ingredientId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static RecipeBindingModel CreateModel(string productId, string ingredientId, int quantity = 2)
|
||||
{
|
||||
return new RecipeBindingModel
|
||||
{
|
||||
ProductId = productId,
|
||||
IngredientId = ingredientId,
|
||||
Quantity = quantity
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseDataBase.Models;
|
||||
using CandyHouseTests.Infrastructure;
|
||||
using System.Net;
|
||||
|
||||
namespace CandyHouseTests.WebApiControllersTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class SalaryControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
private string _pekarId;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
var position = CandyHouseDbContext.InsertPositionToDatabaseAndReturn();
|
||||
var pekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(positionId: position.Id);
|
||||
_pekarId = pekar.Id;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
CandyHouseDbContext.RemoveSalariesFromDatabase();
|
||||
CandyHouseDbContext.RemovePekarsFromDatabase();
|
||||
CandyHouseDbContext.RemovePositionsFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, DateTime.UtcNow.AddMonths(-1));
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/salaries");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
Assert.That(data.Any(x => x.Id == salary.Id));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/salaries");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPekarId_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var anotherPekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Another Baker");
|
||||
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, DateTime.UtcNow.AddMonths(-1));
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(anotherPekar.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/salaries/pekar/{_pekarId}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.All(x => x.PekarId == _pekarId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var currentMonth = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1);
|
||||
var lastMonth = currentMonth.AddMonths(-1);
|
||||
var twoMonthsAgo = currentMonth.AddMonths(-2);
|
||||
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, currentMonth);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, lastMonth);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, twoMonthsAgo);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/salaries/period?fromDate={lastMonth:yyyy-MM-dd}&toDate={currentMonth.AddDays(28):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetList_ByPekarIdAndPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var anotherPekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(fio: "Another Baker");
|
||||
var currentMonth = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1);
|
||||
var lastMonth = currentMonth.AddMonths(-1);
|
||||
|
||||
// Create salary records for both pekars in different periods
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, currentMonth);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, lastMonth);
|
||||
CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(anotherPekar.Id, currentMonth);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/salaries/pekar/{_pekarId}/period?fromDate={lastMonth:yyyy-MM-dd}&toDate={currentMonth.AddDays(28):yyyy-MM-dd}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.That(data.All(x => x.PekarId == _pekarId));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/salaries/{salary.Id}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var result = await GetModelFromResponseAsync<SalaryViewModel>(response);
|
||||
AssertElement(result, salary);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/salaries/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salaryModel = CreateModel(_pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
var savedSalary = CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == salaryModel.Id);
|
||||
Assert.That(savedSalary, Is.Not.Null);
|
||||
Assert.That(savedSalary.PekarId, Is.EqualTo(salaryModel.PekarId));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salaryModel = CreateModel(_pekarId);
|
||||
var existingSalary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
salaryModel.Id = existingSalary.Id;
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModel));
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WhenPekarDoesNotExist_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salaryModel = new SalaryBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = Guid.NewGuid().ToString(), // Non-existent pekar ID
|
||||
Amount = 1000,
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModel));
|
||||
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_WithInvalidData_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salaryModelWithNegativeAmount = new SalaryBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = _pekarId,
|
||||
Amount = -500,
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
|
||||
var salaryModelWithoutPekarId = new SalaryBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = null,
|
||||
Amount = 500,
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
|
||||
var salaryModelWithFutureDate = new SalaryBindingModel
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
PekarId = _pekarId,
|
||||
Amount = 500,
|
||||
DateIssue = DateTime.UtcNow.AddMonths(1) // Future date
|
||||
};
|
||||
|
||||
//Act
|
||||
var responseWithNegativeAmount = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModelWithNegativeAmount));
|
||||
var responseWithoutPekarId = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModelWithoutPekarId));
|
||||
var responseWithFutureDate = await HttpClient.PostAsync($"/api/salaries", MakeContent(salaryModelWithFutureDate));
|
||||
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(responseWithNegativeAmount.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Amount is negative");
|
||||
Assert.That(responseWithoutPekarId.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "PekarId is missing");
|
||||
Assert.That(responseWithFutureDate.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Date is in the future");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
var salaryModel = new SalaryBindingModel
|
||||
{
|
||||
Id = salary.Id,
|
||||
PekarId = _pekarId,
|
||||
Amount = 1500, // Updated amount
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/salaries", MakeContent(salaryModel));
|
||||
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var updatedSalary = CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == salary.Id);
|
||||
Assert.That(updatedSalary, Is.Not.Null);
|
||||
Assert.That(updatedSalary.TotalSalary, Is.EqualTo(1500));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salaryModel = CreateModel(_pekarId);
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.PutAsync($"/api/salaries", MakeContent(salaryModel));
|
||||
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Put_WithInvalidData_ShouldBadRequest_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
|
||||
var salaryModelWithNegativeAmount = new SalaryBindingModel
|
||||
{
|
||||
Id = salary.Id,
|
||||
PekarId = _pekarId,
|
||||
Amount = -500,
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
|
||||
//Act
|
||||
var responseWithNegativeAmount = await HttpClient.PutAsync($"/api/salaries", MakeContent(salaryModelWithNegativeAmount));
|
||||
|
||||
//Assert
|
||||
Assert.That(responseWithNegativeAmount.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Amount is negative");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/salaries/{salary.Id}");
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
var deletedSalary = CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == salary.Id);
|
||||
Assert.That(deletedSalary, Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/salaries/{Guid.NewGuid()}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Delete_ShouldUpdateRelatedEntities_Test()
|
||||
{
|
||||
//Arrange
|
||||
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
|
||||
|
||||
// Create a reference to this salary in another entity if needed
|
||||
// For example, if there's a bonus record linked to this salary
|
||||
|
||||
//Act
|
||||
var response = await HttpClient.DeleteAsync($"/api/salaries/{salary.Id}");
|
||||
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
CandyHouseDbContext.ChangeTracker.Clear();
|
||||
|
||||
// Check that the salary was deleted
|
||||
var deletedSalary = CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == salary.Id);
|
||||
Assert.That(deletedSalary, Is.Null);
|
||||
|
||||
// Check that the pekar still exists and is not affected
|
||||
var pekar = CandyHouseDbContext.Pekars.FirstOrDefault(x => x.Id == _pekarId);
|
||||
Assert.That(pekar, Is.Not.Null);
|
||||
});
|
||||
}
|
||||
|
||||
private static SalaryBindingModel CreateModel(string pekarId, string? id = null)
|
||||
{
|
||||
return new SalaryBindingModel
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
PekarId = pekarId,
|
||||
Amount = 1000,
|
||||
DateIssue = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
28
CandyHouseSolution/CandyHouseTests/appsettings.json
Normal file
28
CandyHouseSolution/CandyHouseTests/appsettings.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"Using": [ "Serilog.Sinks.File" ],
|
||||
"MinimumLevel": {
|
||||
"Default": "Information"
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "File",
|
||||
"Args": {
|
||||
"path": "../logs/cathaspaws-.log",
|
||||
"rollingInterval": "Day",
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3} {Username} {Message:lj}{Exception}{NewLine}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"DataBaseSettings": {
|
||||
"ConnectionString": "Host=127.0.0.1;Port=5432;Database=CandyHouseTest;Username=postgres;Password=postgres;"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class IngredientAdapter : IIngredientAdapter
|
||||
{
|
||||
private readonly IIngredientBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public IngredientAdapter(IIngredientBusinessLogicContact logic, ILogger<IngredientAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<IngredientBindingModel, IngredientDataModel>();
|
||||
cfg.CreateMap<IngredientDataModel, IngredientViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public IngredientOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return IngredientOperationResponse.OK(_logic.GetAllIngredients().Select(x => _mapper.Map<IngredientViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return IngredientOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return IngredientOperationResponse.OK(_mapper.Map<IngredientViewModel>(_logic.GetIngredientByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return IngredientOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return IngredientOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientOperationResponse Register(IngredientBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertIngredient(_mapper.Map<IngredientDataModel>(model));
|
||||
return IngredientOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return IngredientOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientOperationResponse Update(IngredientBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdateIngredient(_mapper.Map<IngredientDataModel>(model));
|
||||
return IngredientOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return IngredientOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public IngredientOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeleteIngredient(id);
|
||||
return IngredientOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return IngredientOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
CandyHouseSolution/CandyHouseWebApi/Adapters/OrderAdapter.cs
Normal file
105
CandyHouseSolution/CandyHouseWebApi/Adapters/OrderAdapter.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class OrderAdapter : IOrderAdapter
|
||||
{
|
||||
private readonly IOrderBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public OrderAdapter(IOrderBusinessLogicContact logic, ILogger<OrderAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<OrderBindingModel, OrderDataModel>();
|
||||
cfg.CreateMap<OrderDataModel, OrderViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public OrderOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return OrderOperationResponse.OK(_logic.GetAllOrders().Select(x => _mapper.Map<OrderViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return OrderOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public OrderOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return OrderOperationResponse.OK(_mapper.Map<OrderViewModel>(_logic.GetOrderByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return OrderOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return OrderOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public OrderOperationResponse Register(OrderBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertOrder(_mapper.Map<OrderDataModel>(model));
|
||||
return OrderOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return OrderOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public OrderOperationResponse Update(OrderBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdateOrder(_mapper.Map<OrderDataModel>(model));
|
||||
return OrderOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return OrderOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public OrderOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeleteOrder(id);
|
||||
return OrderOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return OrderOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
CandyHouseSolution/CandyHouseWebApi/Adapters/PekarAdapter.cs
Normal file
107
CandyHouseSolution/CandyHouseWebApi/Adapters/PekarAdapter.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class PekarAdapter : IPekarAdapter
|
||||
{
|
||||
private readonly IPekarBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public PekarAdapter(IPekarBusinessLogicContact logic, ILogger<PekarAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<PekarBindingModel, PekarDataModel>();
|
||||
cfg.CreateMap<PekarDataModel, PekarViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public PekarOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return PekarOperationResponse.OK(_logic.GetAllPekars().Select(x => _mapper.Map<PekarViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return PekarOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PekarOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return PekarOperationResponse.OK(_mapper.Map<PekarViewModel>(_logic.GetPekarByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return PekarOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return PekarOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PekarOperationResponse Register(PekarBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertPekar(_mapper.Map<PekarDataModel>(model));
|
||||
return PekarOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return PekarOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PekarOperationResponse Update(PekarBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdatePekar(_mapper.Map<PekarDataModel>(model));
|
||||
return PekarOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return PekarOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PekarOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeletePekar(id);
|
||||
return PekarOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return PekarOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
CandyHouseSolution/CandyHouseWebApi/Adapters/PositionAdapter.cs
Normal file
107
CandyHouseSolution/CandyHouseWebApi/Adapters/PositionAdapter.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class PositionAdapter : IPositionAdapter
|
||||
{
|
||||
private readonly IPositionBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public PositionAdapter(IPositionBusinessLogicContact logic, ILogger<PositionAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<PositionBindingModel, PositionDataModel>();
|
||||
cfg.CreateMap<PositionDataModel, PositionViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public PositionOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return PositionOperationResponse.OK(_logic.GetAllPositions().Select(x => _mapper.Map<PositionViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return PositionOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PositionOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return PositionOperationResponse.OK(_mapper.Map<PositionViewModel>(_logic.GetPositionByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return PositionOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return PositionOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PositionOperationResponse Register(PositionBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertPosition(_mapper.Map<PositionDataModel>(model));
|
||||
return PositionOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return PositionOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PositionOperationResponse Update(PositionBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdatePosition(_mapper.Map<PositionDataModel>(model));
|
||||
return PositionOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return PositionOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public PositionOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeletePosition(id);
|
||||
return PositionOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return PositionOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
CandyHouseSolution/CandyHouseWebApi/Adapters/ProductAdapter.cs
Normal file
107
CandyHouseSolution/CandyHouseWebApi/Adapters/ProductAdapter.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class ProductAdapter : IProductAdapter
|
||||
{
|
||||
private readonly IProductBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public ProductAdapter(IProductBusinessLogicContact logic, ILogger<ProductAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<ProductBindingModel, ProductDataModel>();
|
||||
cfg.CreateMap<ProductDataModel, ProductViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public ProductOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return ProductOperationResponse.OK(_logic.GetAllProducts().Select(x => _mapper.Map<ProductViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return ProductOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ProductOperationResponse.OK(_mapper.Map<ProductViewModel>(_logic.GetProductByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return ProductOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return ProductOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductOperationResponse Register(ProductBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertProduct(_mapper.Map<ProductDataModel>(model));
|
||||
return ProductOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return ProductOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductOperationResponse Update(ProductBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdateProduct(_mapper.Map<ProductDataModel>(model));
|
||||
return ProductOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return ProductOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public ProductOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeleteProduct(id);
|
||||
return ProductOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return ProductOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
CandyHouseSolution/CandyHouseWebApi/Adapters/SalaryAdapter.cs
Normal file
107
CandyHouseSolution/CandyHouseWebApi/Adapters/SalaryAdapter.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using AutoMapper;
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Contracts.OperationResponses;
|
||||
using CandyHouseBase.Contracts.ViewModels;
|
||||
using CandyHouseBase.DataModels;
|
||||
using CandyHouseBase.Exceptions;
|
||||
using CandyHouseBase.Interfaces;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CandyHouseWebApi.Adapters;
|
||||
|
||||
public class SalaryAdapter : ISalaryAdapter
|
||||
{
|
||||
private readonly ISalaryBusinessLogicContact _logic;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public SalaryAdapter(ISalaryBusinessLogicContact logic, ILogger<SalaryAdapter> logger)
|
||||
{
|
||||
_logic = logic;
|
||||
_logger = logger;
|
||||
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<SalaryBindingModel, SalaryDataModel>();
|
||||
cfg.CreateMap<SalaryDataModel, SalaryViewModel>();
|
||||
});
|
||||
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public SalaryOperationResponse GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return SalaryOperationResponse.OK(_logic.GetAllSalaries().Select(x => _mapper.Map<SalaryViewModel>(x)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "GetList failed");
|
||||
return SalaryOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public SalaryOperationResponse GetElement(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SalaryOperationResponse.OK(_mapper.Map<SalaryViewModel>(_logic.GetSalaryByData(data)));
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Not found");
|
||||
return SalaryOperationResponse.NotFound(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error");
|
||||
return SalaryOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public SalaryOperationResponse Register(SalaryBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.InsertSalary(_mapper.Map<SalaryDataModel>(model));
|
||||
return SalaryOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Register error");
|
||||
return SalaryOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public SalaryOperationResponse Update(SalaryBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.UpdateSalary(_mapper.Map<SalaryDataModel>(model));
|
||||
return SalaryOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Update error");
|
||||
return SalaryOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public SalaryOperationResponse Delete(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logic.DeleteSalary(id);
|
||||
return SalaryOperationResponse.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Delete error");
|
||||
return SalaryOperationResponse.BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
CandyHouseSolution/CandyHouseWebApi/AuthOptions.cs
Normal file
19
CandyHouseSolution/CandyHouseWebApi/AuthOptions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Text;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace CandyHouseWebApi
|
||||
{
|
||||
// Make sure this class is public and accessible to your tests
|
||||
public class AuthOptions
|
||||
{
|
||||
public const string ISSUER = "CandyHouseWebApi";
|
||||
public const string AUDIENCE = "CandyHouseClient";
|
||||
const string KEY = "candy_house_secret_key_for_jwt_auth_please_change_in_production";
|
||||
|
||||
public static SymmetricSecurityKey GetSymmetricSecurityKey() =>
|
||||
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(KEY));
|
||||
}
|
||||
}
|
||||
|
||||
// In your test project, if you need a reference to this
|
||||
// Make sure you're using the exact same values in both places!
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class IngredientsController(IIngredientAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IIngredientAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] IngredientBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] IngredientBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class OrdersController(IOrderAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IOrderAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] OrderBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] OrderBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class PekarsController(IPekarAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IPekarAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] PekarBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] PekarBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class PositionsController(IPositionAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IPositionAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] PositionBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] PositionBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class ProductsController(IProductAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IProductAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] ProductBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] ProductBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CandyHouseBase.Contracts;
|
||||
using CandyHouseBase.Contracts.BindingModels;
|
||||
using CandyHouseBase.Interfaces.Adapters;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CandyHouseWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
public class SalarysController(ISalaryAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly ISalaryAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
|
||||
|
||||
[HttpGet("{data}")]
|
||||
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Post([FromBody] SalaryBindingModel model) =>
|
||||
_adapter.Register(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpPut]
|
||||
public IActionResult Put([FromBody] SalaryBindingModel model) =>
|
||||
_adapter.Update(model).GetResponse(Request, Response);
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(string id) =>
|
||||
_adapter.Delete(id).GetResponse(Request, Response);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using CandyHouseBase.Infrastructure;
|
||||
|
||||
namespace CandyHouseWebApi.Infrastructure;
|
||||
|
||||
internal class ConfigurationDatabase(IConfiguration configuration) : IConfigurationDatabase
|
||||
{
|
||||
private readonly Lazy<DataBaseSettings> _dataBaseSettings = new(() =>
|
||||
{
|
||||
return configuration.GetValue<DataBaseSettings>("DataBaseSettings") ?? throw new InvalidDataException(nameof(DataBaseSettings));
|
||||
});
|
||||
|
||||
public string ConnectionString => _dataBaseSettings.Value.ConnectionString;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace CandyHouseWebApi.Infrastructure;
|
||||
|
||||
public class DataBaseSettings
|
||||
{
|
||||
public required string ConnectionString { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user