-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Add a sample on how to use data annotations with SimpleResults (#…
…57) * test: Add integration tests
- Loading branch information
1 parent
44d2ffe
commit c89101a
Showing
9 changed files
with
208 additions
and
6 deletions.
There are no files selected for viewing
44 changes: 44 additions & 0 deletions
44
samples/SimpleResults.Example.AspNetCore/Controllers/OrderController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
namespace SimpleResults.Example.AspNetCore.Controllers.ManualValidation | ||
{ | ||
[Route("Order-ManualValidation")] | ||
[Tags("Order ManualValidation")] | ||
public class OrderController : ControllerBase | ||
{ | ||
private readonly OrderService _orderService; | ||
|
||
public OrderController(OrderService orderService) | ||
{ | ||
_orderService = orderService; | ||
} | ||
|
||
[HttpPost] | ||
public Result<CreatedGuid> Create([FromBody]Order order) | ||
{ | ||
if (ModelState.IsFailed()) | ||
return ModelState.Invalid(); | ||
|
||
return _orderService.Create(order); | ||
} | ||
} | ||
} | ||
|
||
namespace SimpleResults.Example.AspNetCore.Controllers.AutomaticValidation | ||
{ | ||
// Allows automatic model validation. | ||
[ApiController] | ||
[Route("Order-AutomaticValidation")] | ||
[Tags("Order AutomaticValidation")] | ||
public class OrderController : ControllerBase | ||
{ | ||
private readonly OrderService _orderService; | ||
|
||
public OrderController(OrderService orderService) | ||
{ | ||
_orderService = orderService; | ||
} | ||
|
||
[HttpPost] | ||
public Result<CreatedGuid> Create([FromBody]Order order) | ||
=> _orderService.Create(order); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
samples/SimpleResults.Example.Web.Tests/Features/CreateOrderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
namespace SimpleResults.Example.Web.Tests.Features; | ||
|
||
public class CreateOrderTests | ||
{ | ||
[TestCase(Routes.Order.ManualValidation)] | ||
[TestCase(Routes.Order.AutomaticValidation)] | ||
public async Task Post_WhenOrderIsCreated_ShouldReturnsHttpStatusCodeCreated(string requestUri) | ||
{ | ||
// Arrange | ||
using var factory = new WebApplicationFactory<Program>(); | ||
var client = factory.CreateClient(); | ||
var orders = factory.Services.GetService<List<Order>>(); | ||
var order = new Order | ||
{ | ||
Description = "Description", | ||
DeliveryAddress = "DeliveryAddress", | ||
Details = new List<OrderDetail> | ||
{ | ||
new() | ||
{ | ||
Product = "Product.", | ||
Amount = 2, | ||
Price = 5600 | ||
} | ||
} | ||
}; | ||
|
||
// Act | ||
var httpResponse = await client.PostAsJsonAsync(requestUri, order); | ||
var result = await httpResponse | ||
.Content | ||
.ReadFromJsonAsync<Result<CreatedGuid>>(); | ||
var expectedId = orders[0].Id; | ||
|
||
// Asserts | ||
httpResponse.StatusCode.Should().Be(HttpStatusCode.Created); | ||
result.Data.Id.Should().Be(expectedId); | ||
result.IsSuccess.Should().BeTrue(); | ||
result.Message.Should().NotBeNullOrEmpty(); | ||
result.Errors.Should().BeEmpty(); | ||
} | ||
|
||
[TestCase(Routes.Order.ManualValidation)] | ||
[TestCase(Routes.Order.AutomaticValidation)] | ||
public async Task Post_WhenModelIsInvalid_ShouldReturnsHttpStatusCodeBadRequest(string requestUri) | ||
{ | ||
// Arrange | ||
using var factory = new WebApplicationFactory<Program>(); | ||
var client = factory.CreateClient(); | ||
var order = new Order | ||
{ | ||
Description = string.Empty, | ||
DeliveryAddress = string.Empty, | ||
Details = new List<OrderDetail> | ||
{ | ||
new() | ||
{ | ||
Product = string.Empty, | ||
Amount = default, | ||
Price = default | ||
}, | ||
new() | ||
{ | ||
Product = string.Empty, | ||
Amount = default, | ||
Price = default | ||
} | ||
} | ||
}; | ||
var expectedErrors = new[] | ||
{ | ||
"'Description' property failed validation. Error was: The Description field is required.", | ||
"'Description' property failed validation. Error was: The field Description must be a string or array type with a minimum length of '10'.", | ||
"'DeliveryAddress' property failed validation. Error was: The DeliveryAddress field is required.", | ||
"'DeliveryAddress' property failed validation. Error was: The field DeliveryAddress must be a string or array type with a minimum length of '10'.", | ||
"'Details[0].Price' property failed validation. Error was: The Price field is required.", | ||
"'Details[0].Amount' property failed validation. Error was: The Amount field is required.", | ||
"'Details[0].Product' property failed validation. Error was: The Product field is required.", | ||
"'Details[0].Product' property failed validation. Error was: The field Product must be a string or array type with a minimum length of '8'.", | ||
"'Details[1].Price' property failed validation. Error was: The Price field is required.", | ||
"'Details[1].Amount' property failed validation. Error was: The Amount field is required.", | ||
"'Details[1].Product' property failed validation. Error was: The Product field is required.", | ||
"'Details[1].Product' property failed validation. Error was: The field Product must be a string or array type with a minimum length of '8'." | ||
}; | ||
|
||
// Act | ||
var httpResponse = await client.PostAsJsonAsync(requestUri, order); | ||
var result = await httpResponse | ||
.Content | ||
.ReadFromJsonAsync<Result<CreatedGuid>>(); | ||
|
||
// Asserts | ||
httpResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest); | ||
result.Data.Should().BeNull(); | ||
result.IsSuccess.Should().BeFalse(); | ||
result.Message.Should().NotBeNullOrEmpty(); | ||
result.Errors.Should().BeEquivalentTo(expectedErrors); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace SimpleResults.Example.DataAnnotations; | ||
|
||
public class Order | ||
{ | ||
[JsonIgnore] | ||
public string Id { get; set; } | ||
[Required, MinLength(10)] | ||
public string Description { get; set; } | ||
[Required, MinLength(10)] | ||
public string DeliveryAddress { get; set; } | ||
[Required] | ||
public List<OrderDetail> Details { get; set; } | ||
} | ||
|
||
public class OrderDetail | ||
{ | ||
[Required, MinLength(8)] | ||
public string Product { get; set; } | ||
[Required] | ||
public int? Amount { get; set; } | ||
[Required] | ||
public double? Price { get; set; } | ||
} |
21 changes: 21 additions & 0 deletions
21
samples/SimpleResults.Example/DataAnnotations/OrderService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace SimpleResults.Example.DataAnnotations; | ||
|
||
public class OrderService | ||
{ | ||
private readonly List<Order> _orders; | ||
|
||
public OrderService(List<Order> orders) | ||
{ | ||
ArgumentNullException.ThrowIfNull(nameof(orders)); | ||
_orders = orders; | ||
} | ||
|
||
public Result<CreatedGuid> Create(Order order) | ||
{ | ||
ArgumentNullException.ThrowIfNull(nameof(order)); | ||
_orders.Add(order); | ||
var guid = Guid.NewGuid(); | ||
order.Id = guid.ToString(); | ||
return Result.CreatedResource(guid); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
global using FluentValidation; | ||
global using FluentValidation.Results; | ||
global using FluentValidation.Results; | ||
global using System.Text.Json.Serialization; |