fix(work-orders): return 400 for invalid advanced-search custom date range

Map ArgumentException from datePreset=custom without dates to BadRequest so the endpoint matches the Phase 4 contract.
This commit is contained in:
Arthur Bassi 2026-07-10 10:56:18 -03:00
parent 0ddc43210a
commit dd2a805c24
2 changed files with 111 additions and 3 deletions

View file

@ -0,0 +1,101 @@
using Api.SeaHavenIndustries.Controllers;
using Api.SeaHavenIndustries.DTOs;
using Data.SeaHavenIndustries;
using FluentAssertions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Moq;
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Helpers;
using SeaHaven.Services.Implementation;
using SeaHaven.Services.Interfaces;
using Xunit;
namespace Api.SeaHavenIndustries.Tests;
public class WorkOrderControllerSearchTests
{
private static ApplicationDbContext NewContext()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
return new ApplicationDbContext(options);
}
private static UserManager<ApplicationUser> MockUserManager()
{
var store = new Mock<IUserStore<ApplicationUser>>();
return new Mock<UserManager<ApplicationUser>>(
store.Object, null!, null!, null!, null!, null!, null!, null!, null!).Object;
}
private static WorkOrderController NewController(
ApplicationDbContext ctx,
IWorkOrderAdvancedSearchService advancedSearch)
{
var controller = new WorkOrderController(
MockUserManager(),
Mock.Of<IWorkOrderService>(),
Mock.Of<IWorkOrderDataService>(),
Mock.Of<ICommentDataService>(),
Mock.Of<IQuotesDataService>(),
Mock.Of<IUserDataService>(),
Mock.Of<IDispatchDataService>(),
Mock.Of<IVendorDataService>(),
Mock.Of<ITaskListTemplateDataService>(),
ctx,
Mock.Of<IWebHostEnvironment>(),
Mock.Of<IHttpContextAccessor>(),
null!,
null!,
Mock.Of<IConfiguration>(),
Mock.Of<IWorkOrderBoardService>(),
Mock.Of<IWorkOrderBoardUpdateService>(),
Mock.Of<IWorkOrderBoardCreateService>(),
Mock.Of<IWorkOrderBoardCancelService>(),
advancedSearch);
controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext
{
User = new System.Security.Claims.ClaimsPrincipal(
new System.Security.Claims.ClaimsIdentity(
new[]
{
new System.Security.Claims.Claim(
System.Security.Claims.ClaimTypes.NameIdentifier,
"test-user")
},
"Test"))
}
};
return controller;
}
[Fact]
public async Task SearchBoard_WhenCustomPresetMissingDates_ReturnsBadRequest()
{
using var ctx = NewContext();
var advancedSearch = new WorkOrderAdvancedSearchService(
Mock.Of<IWorkOrderAdvancedSearchDataService>());
var controller = NewController(ctx, advancedSearch);
var result = await controller.SearchBoard(new WorkOrderAdvancedSearchQueryDto
{
DatePreset = WorkOrderAdvancedSearchDatePreset.Custom
});
var badRequest = result.Should().BeOfType<BadRequestObjectResult>().Subject;
var body = badRequest.Value.Should().BeOfType<Response>().Subject;
body.Status.Should().Be("Error");
body.Message.Should().Contain("dateFrom");
}
}

View file

@ -120,9 +120,16 @@ namespace Api.SeaHavenIndustries.Controllers
[HttpGet("board/search")]
public async Task<IActionResult> SearchBoard([FromQuery] WorkOrderAdvancedSearchQueryDto query)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var result = await _advancedSearchService.SearchAsync(query, userId);
return Ok(result);
try
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var result = await _advancedSearchService.SearchAsync(query, userId);
return Ok(result);
}
catch (ArgumentException ex)
{
return BadRequest(new Response { Status = "Error", Message = ex.Message });
}
}
[HttpGet("lookups/dispatchers")]