mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 16:33:12 +00:00
106 lines
4.3 KiB
C#
106 lines
4.3 KiB
C#
using Api.SeaHavenIndustries.Controllers;
|
|
using Data.SeaHavenIndustries;
|
|
using FluentAssertions;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
using SeaHaven.DataServices.Models;
|
|
using SeaHaven.Services.Interfaces;
|
|
using Xunit;
|
|
|
|
namespace Api.SeaHavenIndustries.Tests;
|
|
|
|
/// <summary>
|
|
/// SH-374: GET api/WorkOrder/GetWorkorderById?id= must read the id from the query string, while
|
|
/// GET api/WorkOrder/{id} keeps reading it from the route. Both must return the same work order,
|
|
/// and an unknown id keeps the existing "ID not found!" response.
|
|
/// </summary>
|
|
public class WorkOrderGetByIdBindingTests
|
|
{
|
|
private const int ExistingId = 374;
|
|
private const int UnknownId = 999_999;
|
|
|
|
private static ControllerActionDescriptor ActionForTemplate(string relativeTemplate)
|
|
{
|
|
var services = new ServiceCollection();
|
|
services.AddLogging();
|
|
services.AddMvcCore().AddApplicationPart(typeof(WorkOrderController).Assembly);
|
|
|
|
using var provider = services.BuildServiceProvider();
|
|
return provider.GetRequiredService<IActionDescriptorCollectionProvider>().ActionDescriptors.Items
|
|
.OfType<ControllerActionDescriptor>()
|
|
.Where(cad => cad.ControllerTypeInfo == typeof(WorkOrderController))
|
|
.Where(cad => cad.ActionConstraints!
|
|
.OfType<Microsoft.AspNetCore.Mvc.ActionConstraints.HttpMethodActionConstraint>()
|
|
.Any(c => c.HttpMethods.Contains("GET")))
|
|
.Single(cad => string.Equals(
|
|
cad.AttributeRouteInfo?.Template?.Trim('/'),
|
|
$"api/WorkOrder/{relativeTemplate}",
|
|
StringComparison.Ordinal));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("GetWorkorderById", "Query")]
|
|
[InlineData("{id:int}", "Path")]
|
|
public void Id_binds_from_the_source_its_route_provides(string relativeTemplate, string expectedSource)
|
|
{
|
|
var action = ActionForTemplate(relativeTemplate);
|
|
|
|
var id = action.Parameters.Single(p => p.Name == "id");
|
|
id.BindingInfo.Should().NotBeNull();
|
|
id.BindingInfo!.BindingSource!.Id.Should().Be(expectedSource);
|
|
}
|
|
|
|
private static (WorkOrderController Controller, WorkOrderDetailReadModel Existing) NewController()
|
|
{
|
|
var existing = new WorkOrderDetailReadModel { Id = ExistingId, Title = "Leaking roof" };
|
|
var service = new Mock<IWorkOrderService>();
|
|
service.Setup(s => s.GetWorkOrderDetailAsync(ExistingId, It.IsAny<int?>())).ReturnsAsync(existing);
|
|
service.Setup(s => s.GetWorkOrderDetailAsync(UnknownId, It.IsAny<int?>()))
|
|
.ReturnsAsync((WorkOrderDetailReadModel?)null);
|
|
|
|
var controller = new WorkOrderController(
|
|
service.Object,
|
|
Mock.Of<IWorkOrderAccountResolver>(),
|
|
Mock.Of<ILogger<WorkOrderController>>())
|
|
{
|
|
ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() }
|
|
};
|
|
return (controller, existing);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Existing_id_returns_the_same_work_order_through_both_routes()
|
|
{
|
|
var (controller, existing) = NewController();
|
|
|
|
var byQuery = await controller.GetWorkorderById(ExistingId);
|
|
var byRoute = await controller.GetWorkorderByRouteId(ExistingId);
|
|
|
|
byQuery.Should().BeOfType<OkObjectResult>().Which.Value.Should().BeSameAs(existing);
|
|
byRoute.Should().BeOfType<OkObjectResult>().Which.Value.Should().BeSameAs(existing);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Unknown_id_keeps_the_not_found_response_through_both_routes()
|
|
{
|
|
var (controller, _) = NewController();
|
|
|
|
foreach (var result in new[]
|
|
{
|
|
await controller.GetWorkorderById(UnknownId),
|
|
await controller.GetWorkorderByRouteId(UnknownId),
|
|
})
|
|
{
|
|
var body = result.Should().BeOfType<BadRequestObjectResult>().Which.Value
|
|
.Should().BeOfType<Response>().Subject;
|
|
body.Status.Should().Be("Error");
|
|
body.Message.Should().Be("ID not found!");
|
|
}
|
|
}
|
|
}
|