Skip to content
This repository has been archived by the owner on Aug 24, 2023. It is now read-only.

Beleza na web api project #99

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Domain/BelezaNaWeb.Domain.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Reference Include="Microsoft.Net.Http.Headers">
<HintPath>C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\6.0.4\ref\net6.0\Microsoft.Net.Http.Headers.dll</HintPath>
</Reference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace BelezaNaWeb.Domain.Constants
{
public static class WareHouseTypeConstants
{
public const string ECOMMERCE = "ECOMMERCE";
public const string PHYSICAL_STORE = "PHYSICAL_STORE";
}
}
16 changes: 16 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Domain/Entities/Inventory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace BelezaNaWeb.Domain.Entities
{
public class Inventory
{
public int Quantity { get; }
public List<Warehouse> Warehouses { get; }

public Inventory(List<Warehouse> warehouses)
{
this.Warehouses = warehouses;
Quantity = SetQuantity(this.Warehouses);
}

private static int SetQuantity(IEnumerable<Warehouse> wh) => wh.Sum(item => item.Quantity);
}
}
18 changes: 18 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Domain/Entities/Product.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace BelezaNaWeb.Domain.Entities
{
public class Product
{
public int Sku { get; set; }
public string Name { get; set; }
public Inventory Inventory { get; }
public bool IsMarketable { get; }

public Product(Inventory inventory)
{
Inventory = inventory;
IsMarketable = SetMarketable(inventory);
}

private static bool SetMarketable(Inventory inventory) => inventory.Quantity > 0;
}
}
9 changes: 9 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Domain/Entities/Warehouse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace BelezaNaWeb.Domain.Entities
{
public class Warehouse
{
public string Locality { get; set; }
public int Quantity { get; set; }
public string Type { get; set; }
}
}
16 changes: 16 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Domain/Response/BaseResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Net;

namespace BelezaNaWeb.Domain.Response
{
public class BaseResponse<TEntity>
{
public HttpStatusCode HttpStatusCode { get; set; }
public string Message { get; set; }
public List<TEntity> Data { get; set; }

public BaseResponse()
{
Data = new List<TEntity>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
13 changes: 13 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Repository/BelezaNaWeb.Repository.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\BelezaNaWeb.Domain\BelezaNaWeb.Domain.csproj" />
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Repository/IProductRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using BelezaNaWeb.Domain.Entities;

namespace BelezaNaWeb.Repository
{
public interface IProductRepository
{
Product? GetBySku(int sku);
List<Product> GetProducts();
Product Create(Product product);
void UpdateBySku(int sku, Product product);
void DeleteBySku(int sku);
}
}
34 changes: 34 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Repository/ProductRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using BelezaNaWeb.Domain.Entities;

namespace BelezaNaWeb.Repository
{
public class ProductRepository : IProductRepository
{
private static readonly List<Product> Products = new();

public Product? GetBySku(int sku) => Products.FirstOrDefault(p => p.Sku == sku);

public List<Product> GetProducts() => Products.ToList();

public Product Create(Product? product)
{
if (Products.All(p => p.Sku != product.Sku))
Products.Add(product);
return product;
}

public void UpdateBySku(int sku, Product newProduct)
{
var currentProduct = GetBySku(sku);
if (currentProduct is not null) return;
if (newProduct != null && sku != newProduct.Sku) return;
DeleteBySku(sku);
Products.Add(newProduct);
}

public void DeleteBySku(int sku)
{
Products.RemoveAll(p => p.Sku == sku);
}
}
}
14 changes: 14 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Services/BelezaNaWeb.Services.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\BelezaNaWeb.Domain\BelezaNaWeb.Domain.csproj" />
<ProjectReference Include="..\BelezaNaWeb.Repository\BelezaNaWeb.Repository.csproj" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Services/IProductService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using BelezaNaWeb.Domain.Entities;
using BelezaNaWeb.Domain.Response;

namespace BelezaNaWeb.Services
{
public interface IProductService
{
Task<BaseResponse<Product>> CreateProduct(Product? product);
Task<BaseResponse<bool>> DeleteProductBySku(int sku);
Task<BaseResponse<Product>> GetAllProducts();
Task<BaseResponse<Product>> GetBySku(int sku);
Task<BaseResponse<bool>> UpdateBySku(int sku, Product? product);
}
}
109 changes: 109 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Services/ProductService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Net;
using BelezaNaWeb.Domain.Entities;
using BelezaNaWeb.Domain.Response;
using BelezaNaWeb.Repository;

namespace BelezaNaWeb.Services
{
public class ProductService : IProductService
{
private readonly IProductRepository _productRepository;

public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}

public async Task<BaseResponse<Product>> CreateProduct(Product? product)
{
var response = new BaseResponse<Product>();

if (product is not null && _productRepository.GetBySku(product.Sku) is null)
{
response.Data.Add(_productRepository.Create(product));
response.Message = "Product has been created";
response.HttpStatusCode = HttpStatusCode.OK;
}
else
{
throw new Exception($"Product already exist with this sku: {product.Sku}");
}

return response;
}

public async Task<BaseResponse<bool>> DeleteProductBySku(int sku)
{
var response = new BaseResponse<bool>();

if (_productRepository.GetBySku(sku) is not null)
{
_productRepository.DeleteBySku(sku);
response.HttpStatusCode = HttpStatusCode.OK;
response.Message = "Product has been deleted";
response.Data.Add(true);
}
else
{
response.HttpStatusCode = HttpStatusCode.NotFound;
response.Data.Add(false);
response.Message = "Product not found";
}

return response;
}

public async Task<BaseResponse<Product>> GetAllProducts()
{
var response = new BaseResponse<Product>();
var helper = _productRepository.GetProducts();
if (helper is not null)
{
response.Data.AddRange(helper);
}
response.HttpStatusCode = HttpStatusCode.OK;
response.Message = "Products has been retrieved";

return response;
}

public async Task<BaseResponse<Product>> GetBySku(int sku)
{
var response = new BaseResponse<Product>();
var helper = _productRepository.GetBySku(sku);
if (helper is not null)
{
response.Data.Add(helper);
response.HttpStatusCode = HttpStatusCode.OK;
response.Message = "Product has been retrieved";
}
else
{
response.HttpStatusCode = HttpStatusCode.NotFound;
response.Message = "Product not found";
}


return response;
}
public async Task<BaseResponse<bool>> UpdateBySku(int sku, Product? product)
{
var response = new BaseResponse<bool>();
var helper = _productRepository.GetBySku(sku);
if (helper is not null && product is not null)
{
_productRepository.UpdateBySku(sku, product);
response.Data.Add(true);
response.HttpStatusCode = HttpStatusCode.OK;
response.Message = "Product updated";
}
else
{
response.HttpStatusCode = HttpStatusCode.NotFound;
response.Message = "Product Not Fount";
}

return response;
}
}
}
27 changes: 27 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Tests/BelezaNaWeb.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BelezaNaWeb.Repository\BelezaNaWeb.Repository.csproj" />
</ItemGroup>

</Project>
55 changes: 55 additions & 0 deletions BelezaNaWeb/BelezaNaWeb.Tests/UnitTests/Product/ProductTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Linq;
using BelezaNaWeb.Domain.Constants;
using BelezaNaWeb.Domain.Entities;
using BelezaNaWeb.Repository;
using Xunit;

namespace BelezaNaWeb.Tests.UnitTests.Product
{
public class ProductTest
{
private readonly ProductRepository _productRepository;
private Domain.Entities.Product _product;

public ProductTest()
{
_productRepository = new ProductRepository();

var warehouse1 = new Warehouse { Locality = "SP", Quantity = 10, Type = WareHouseTypeConstants.ECOMMERCE };
var warehouse2 = new Warehouse { Locality = "RJ", Quantity = 12, Type = WareHouseTypeConstants.PHYSICAL_STORE };
_product = _productRepository.Create(new Domain.Entities.Product(new Inventory(new List<Warehouse> { warehouse1, warehouse2 })) { Name = "L'Oréal Professionnel Exp...", Sku = 43264 });
}

[Fact]
public void Get_Product_By_Valid_Sku()
{
Assert.True(_productRepository.GetBySku(43264) is not null);
}

[Fact]
public void Get_Product_By_Invalid_Sku()
{
Assert.False(_productRepository.GetBySku(33) is not null);
}

[Fact]
public void Delete_Product_By_Valid_Sku_And_Verify_Deleted_Product()
{
_productRepository.DeleteBySku(43264);
var product = _productRepository.GetBySku(43264);

Assert.True(product is null);
}

[Fact]
public void Verify_Inventory_Quantity_Is_Calculated_Correctly()
{
var product = _productRepository.GetBySku(43264);
var inventoryQuantity = product.Inventory.Quantity;
var wareHousesQuantity = product.Inventory.Warehouses.Sum(inventoryWarehouse => inventoryWarehouse.Quantity);

Assert.Equal(inventoryQuantity, wareHousesQuantity);
}
}
}
Loading