Skip to content

Commit

Permalink
Merge pull request #8 from m-ruiz21/dev
Browse files Browse the repository at this point in the history
Adding Cutlery endpoints and service.
  • Loading branch information
m-ruiz21 committed Apr 17, 2023
2 parents 1a0be05 + 59daaff commit 2b34cf1
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 3 deletions.
7 changes: 7 additions & 0 deletions Project2Api.Contracts/Cutlery/CutleryRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Project2Api.Contracts.Cutlery
{
public record CutleryRequest(
string Name,
int Quantity
);
}
7 changes: 7 additions & 0 deletions Project2Api.Contracts/Cutlery/CutleryResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Project2Api.Contracts.Cutlery
{
public record CutleryResponse(
string Name,
int Quantity
);
}
115 changes: 115 additions & 0 deletions Project2Api/Controllers/CutleryController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using ErrorOr;
using Microsoft.AspNetCore.Mvc;
using Project2Api.Contracts.Cutlery;
using Project2Api.Models;
using Project2Api.Services.CutleryItems;

namespace Project2Api.Controllers
{
[ApiController]
[Route("cutlery")]
public class CutleryController : ApiController
{
private readonly ICutleryService _cutleryService;

public CutleryController(ICutleryService cutleryService)
{
_cutleryService = cutleryService;
}

/// <summary>
/// Creates cutlery item
/// </summary>
/// <param name="cutleryRequest"></param>
/// <returns>Cutlery item or error</returns>
[HttpPost()]
public async Task<IActionResult> CreateCutleryItem(CutleryRequest cutleryRequest)
{
ErrorOr<Cutlery> cutleryItem = Cutlery.From(cutleryRequest);

if (cutleryItem.IsError)
{
return Problem(cutleryItem.Errors);
}

ErrorOr<Cutlery> cutleryItemErrorOr = await _cutleryService.CreateCutleryAsync(cutleryItem.Value);

return cutleryItemErrorOr.Match(
value => Ok(value),
errors => Problem(errors)
);
}

/// <summary>
/// Gets all cutlery items
/// </summary>
/// <returns>List of cutlery items</returns>
[HttpGet()]
public async Task<IActionResult> GetAllCutleryItems()
{
// get all cutlery items
ErrorOr<List<Cutlery>> cutleryItemsErrorOr = await _cutleryService.GetAllCutleryAsync();

// return Ok(cutleryItems) if succcessful, otherwise return error
return cutleryItemsErrorOr.Match(
value => Ok(value),
errors => Problem(errors)
);
}

/// <summary>
/// Gets cutlery item by name
/// </summary>
/// <param name="name"></param>
/// <returns>Cutlery item or error</returns>
[HttpGet("{name}")]
public async Task<IActionResult> GetCutleryItemByName(string name)
{
ErrorOr<Cutlery> cutleryItemErrorOr = await _cutleryService.GetCutleryAsync(name);

return cutleryItemErrorOr.Match(
value => Ok(value),
errors => Problem(errors)
);
}

/// <summary>
/// Updates cutlery item
/// </summary>
/// <param name="cutleryRequest"></param>
/// <returns>Cutlery item or error</returns>
[HttpPut()]
public async Task<IActionResult> UpdateCutleryItem(CutleryRequest cutleryRequest)
{
ErrorOr<Cutlery> cutleryItem = Cutlery.From(cutleryRequest);

if (cutleryItem.IsError)
{
return Problem(cutleryItem.Errors);
}

ErrorOr<Cutlery> updatedCutleryItem = await _cutleryService.UpdateCutleryAsync(cutleryItem.Value);

return updatedCutleryItem.Match(
value => Ok(value),
errors => Problem(errors)
);
}

/// <summary>
/// Deletes cutlery item
/// </summary>
/// <param name="name"></param>
/// <returns>Success or error</returns>
[HttpDelete("{name}")]
public async Task<IActionResult> DeleteCutleryItem(string name)
{
ErrorOr<IActionResult> deletedCutleryItem = await _cutleryService.DeleteCutleryAsync(name);

return deletedCutleryItem.Match(
value => Ok(value),
errors => Problem(errors)
);
}
}
}
34 changes: 34 additions & 0 deletions Project2Api/Errors/Errors.Cutlery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using ErrorOr;

namespace Project2Api.ServiceErrors;

public static partial class Errors
{
/// <summary>
/// Cutlery errors
/// </summary>
public static class Cutlery
{
public static Error NotFound => Error.NotFound(
code: "Cutlery.NotFound",
description: "Cutlery Item not found"
);

public static Error UnexpectedError => Error.Unexpected(
code: "Cutlery.UnexpectedError",
description: "Unexpected error occurred when getting cutlery item"
);

public static Error DbError => Error.Custom(
type: (int)CustomErrorType.Database,
code: "Cutlery.DbError",
description: "Error occurred when getting cutlery item from database"
);

public static Error InvalidCutlery => Error.Custom(
type: (int)CustomErrorType.InvalidParams,
code: "Cutlery.InvalidMenuItem",
description: "Given cutlery item is invalid"
);
}
}
33 changes: 33 additions & 0 deletions Project2Api/Models/Cutlery.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
using ErrorOr;
using Project2Api.Contracts.Cutlery;
using Project2Api.ServiceErrors;

namespace Project2Api.Models;

public class Cutlery
Expand All @@ -18,4 +22,33 @@ public class Cutlery
this.Name = name;
this.Quantity = quantity;
}

public static ErrorOr<Cutlery> Create(
string name,
int quantity
)
{
if (String.IsNullOrEmpty(name) || quantity < 0)
{
return Errors.Cutlery.InvalidCutlery;
}

return new Cutlery(
name,
quantity
);
}

/// <summary>
/// Creates cutlery From cutleryRequest
/// </summary>
/// <param name="name"></param>
/// <returns>Created cutlery</returns>
public static ErrorOr<Cutlery> From(CutleryRequest cutleryRequest)
{
return Create(
cutleryRequest.Name,
cutleryRequest.Quantity
);
}
}
2 changes: 1 addition & 1 deletion Project2Api/Repositories/Cutlery/CutleryRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public CutleryRepository(IDbConnection connection)
}
}

public Task<IEnumerable<Cutlery>?> GetCutleryAsync()
public Task<IEnumerable<Cutlery>?> GetAllCutleryAsync()
{
using (UnitOfWork uow = new UnitOfWork(_connection))
{
Expand Down
2 changes: 1 addition & 1 deletion Project2Api/Repositories/Cutlery/ICutleryRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface ICutleryRepository
/// Gets all cutlery.
/// </summary>
/// <returns>A list of cutlery.</returns>
Task<IEnumerable<Cutlery>?> GetCutleryAsync();
Task<IEnumerable<Cutlery>?> GetAllCutleryAsync();

/// <summary>
/// Gets a cutlery by name.
Expand Down
81 changes: 81 additions & 0 deletions Project2Api/Services/Cutlery/CutleryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Data;
using ErrorOr;
using Microsoft.AspNetCore.Mvc;
using Project2Api.Models;
using Project2Api.Repositories;
using Project2Api.ServiceErrors;

namespace Project2Api.Services.CutleryItems;

public class CutleryService : ICutleryService
{
private readonly ICutleryRepository _cutleryRepository;

public CutleryService(ICutleryRepository cutleryRepository)
{
_cutleryRepository = cutleryRepository;
}

public async Task<ErrorOr<Cutlery>> CreateCutleryAsync(Cutlery cutlery)
{
int? rowsAffected = await _cutleryRepository.CreateCutleryAsync(cutlery);

if (rowsAffected == null || rowsAffected == 0)
{
return Errors.Cutlery.DbError;
}

return cutlery;
}

public async Task<ErrorOr<List<Cutlery>>> GetAllCutleryAsync()
{
IEnumerable<Cutlery>? cutlery = await _cutleryRepository.GetAllCutleryAsync();

if (cutlery == null)
{
return Errors.Cutlery.DbError;
}

return cutlery.ToList();
}

public async Task<ErrorOr<Cutlery>> GetCutleryAsync(string name)
{
if (String.IsNullOrEmpty(name))
{
return Errors.Cutlery.InvalidCutlery;
}

Cutlery? cutlery = await _cutleryRepository.GetCutleryByNameAsync(name);

if (cutlery == null)
{
return Errors.Cutlery.NotFound;
}

return cutlery;
}

public async Task<ErrorOr<Cutlery>> UpdateCutleryAsync(Cutlery cutlery)
{
int? rowsAffected = await _cutleryRepository.UpdateCutleryAsync(cutlery);
if (rowsAffected == null || rowsAffected == 0)
{
return Errors.Cutlery.NotFound;
}

return cutlery;
}

public async Task<ErrorOr<IActionResult>> DeleteCutleryAsync(string name)
{
bool success = await _cutleryRepository.DeleteCutleryAsync(name);
if (!success)
{
return Errors.Cutlery.NotFound;
}

return new NoContentResult();
}
}
14 changes: 14 additions & 0 deletions Project2Api/Services/Cutlery/ICutleryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using ErrorOr;
using Microsoft.AspNetCore.Mvc;
using Project2Api.Models;

namespace Project2Api.Services.CutleryItems;

public interface ICutleryService
{
Task<ErrorOr<Cutlery>> CreateCutleryAsync(Cutlery cutlery);
Task<ErrorOr<Cutlery>> GetCutleryAsync(string name);
Task<ErrorOr<List<Cutlery>>> GetAllCutleryAsync();
Task<ErrorOr<Cutlery>> UpdateCutleryAsync(Cutlery cutlery);
Task<ErrorOr<IActionResult>> DeleteCutleryAsync(string name);
}
2 changes: 1 addition & 1 deletion Project2Api/Services/Inventory/InventoryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task<ErrorOr<IActionResult>> DeleteInventoryItem(InventoryItem inve

public async Task<ErrorOr<List<InventoryItem>>> GetAllInventoryItems()
{
IEnumerable<Cutlery>? allCutlery = await _cutleryRepository.GetCutleryAsync();
IEnumerable<Cutlery>? allCutlery = await _cutleryRepository.GetAllCutleryAsync();
IEnumerable<MenuItem>? allMenuItems = await _menuItemRepository.GetMenuItemsAsync();
if (allCutlery == null || allMenuItems == null)
{
Expand Down
43 changes: 43 additions & 0 deletions Tests/Models/Cutlery/FromRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using ErrorOr;
using Project2Api.Contracts.Cutlery;
using Project2Api.Models;
using Project2Api.ServiceErrors;

namespace Tests.Models.CutleryTests
{
// tests for order model
[TestFixture]
internal class FromRequest
{
// test for valid order request
[Test]
public void FromRequest_ValidCutleryRequest_ReturnsCutlery()
{
// Arrange
CutleryRequest cutleryRequest = new CutleryRequest("bowl", 12);

// Act
ErrorOr<Cutlery> errorOrCutlery = Cutlery.From(cutleryRequest);

// Assert
Assert.That(! errorOrCutlery.IsError);
Assert.That(errorOrCutlery.Value.Name, Is.EqualTo("bowl"));
Assert.That(errorOrCutlery.Value.Quantity, Is.EqualTo(12));
}

// test for invalid order request
[Test]
public void FromRequest_InvalidOrderRequest_ReturnsError()
{
// Arrange
CutleryRequest cutleryRequest = new CutleryRequest("", -1);

// Act
ErrorOr<Cutlery> errorOrCutlery = Cutlery.From(cutleryRequest);

// Assert
Assert.That(errorOrCutlery.IsError);
Assert.That(Errors.Cutlery.InvalidCutlery, Is.EqualTo(errorOrCutlery.FirstError));
}
}
}

0 comments on commit 2b34cf1

Please sign in to comment.