mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 08:23:12 +00:00
Brings in dev's Phase 5 (PR #17) + vendor PRs (#25/#28/#29) atop the Phase 6/7 + flagColor base (PR #22). Preserves dev Phase 1-5 behavior and PR #22 Phase 6/7 + flagColor behavior. Conflict resolutions (16 files): - Migrations Phase4_SearchIndexes/.Designer + Phase5_DomainEvents/.Designer: take dev (Phase4 incl. SQL Server SiteCode/InternalWONumber index-compat shrink fix; Phase5 identical). ModelSnapshot union: Vendor CompanyId index + Phase7 ServiceNotes/ExternalWorkOrderId index. - ApplicationDbContext: keep dev SiteCode/InternalWONumber MaxLength (Phase1-5 + unguarded model test) + HEAD CompletionDocTemplate/ExternalWorkOrderId. - WorkOrderAuditService: unify on dev async staging API; convert Phase6 CompletionService 2 call sites to await StageFieldChangedAsync (drops HEAD sync duplicate; only callers, no test refs). - Hosted services: take HEAD (retry-on-failure, coherent with Phase7 WorkOrderJobRunStateAccessor/OpsHealth). Program.cs keeps dev vendor DI (ClamAV/VendorDocumentScanWorker/ArgumentExceptionFilter) + HEAD Phase7. - WorkOrderController: keep HEAD Phase6/7 service params + dev doc comment. - VendorController/WorkOrderBoardCreateService/QueryFilters/appsettings: union / dev-correct. - WorkOrderBoardUpdateServiceTests: union of HEAD (Phase6/7+flagColor) and dev (Phase1-5) test methods. Verified WorkOrderType.Other (enum 99) is a legit category, not an overdue sentinel; overdue uses dedicated OperationalFlags.PastDue + IsPastDue, and 'Overdue' is rejected as a WorkOrderType (no PR #23 import needed). Removed dev duplicate Api.Options.WorkOrderJobRunState (HEAD defines it in Services.Implementation alongside the Accessor; Services cannot reference Api).
106 lines
3.7 KiB
C#
106 lines
3.7 KiB
C#
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,
|
|
Mock.Of<IWorkOrderDetailService>(),
|
|
Mock.Of<IWorkOrderCommentService>(),
|
|
Mock.Of<IWorkOrderCompletionService>(),
|
|
Mock.Of<IWorkOrderMediaService>());
|
|
|
|
|
|
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");
|
|
}
|
|
}
|