mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-04 13:42:14 +00:00
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:
parent
0ddc43210a
commit
dd2a805c24
2 changed files with 111 additions and 3 deletions
101
Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs
Normal file
101
Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -120,9 +120,16 @@ namespace Api.SeaHavenIndustries.Controllers
|
||||||
[HttpGet("board/search")]
|
[HttpGet("board/search")]
|
||||||
public async Task<IActionResult> SearchBoard([FromQuery] WorkOrderAdvancedSearchQueryDto query)
|
public async Task<IActionResult> SearchBoard([FromQuery] WorkOrderAdvancedSearchQueryDto query)
|
||||||
{
|
{
|
||||||
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
try
|
||||||
var result = await _advancedSearchService.SearchAsync(query, userId);
|
{
|
||||||
return Ok(result);
|
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")]
|
[HttpGet("lookups/dispatchers")]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue