From 6697c1394af25965bba0e6644d24d727de61081b Mon Sep 17 00:00:00 2001 From: Alexandre Brandizzi Date: Fri, 24 Jul 2026 13:58:35 -0300 Subject: [PATCH] test(work-orders): cover overdue date/status boundary and Other type-filter Lock the PR #23 overdue regression boundary through the public advanced search service. Prove overdue filtering is driven by past-due date plus non-terminal status, not by the WorkOrderType.Other sentinel: - Other + future/not-completed excluded from overdue - past-due + Scheduled included; past-due + Completed/Canceled excluded - types=[PM, Other] keeps real Other rows and does not pull past-due rows - assert 0-based paging (Page=0) is preserved alongside overdue/type filters --- .../WorkOrderBoardSearchTests.cs | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs b/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs index f2d37a9..0f4dd34 100644 --- a/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs +++ b/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs @@ -433,6 +433,124 @@ public class WorkOrderAdvancedSearchServiceTests Assert.DoesNotContain(result.Items, i => i.Id == 3); } + [Fact] + public async Task SearchAsync_OverdueDerivesFromDateAndStatus_NotWorkOrderType() + { + await using var context = CreateContext(); + var today = DateTime.UtcNow.Date; + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + WorkOrderType = WorkOrderType.Other, + ScheduledDate = today.AddDays(5), + LifecycleStatus = LifecycleStatus.Scheduled, + InternalWONumber = "10000000001" + }, + new WorkOrder + { + Id = 2, + WorkOrderType = WorkOrderType.PM, + ScheduledDate = today.AddDays(-3), + LifecycleStatus = LifecycleStatus.Scheduled, + InternalWONumber = "10000000002" + }, + new WorkOrder + { + Id = 3, + WorkOrderType = WorkOrderType.Reactive, + ScheduledDate = today.AddDays(-2), + LifecycleStatus = LifecycleStatus.Completed, + InternalWONumber = "10000000003" + }, + new WorkOrder + { + Id = 4, + WorkOrderType = WorkOrderType.Reactive, + ScheduledDate = today.AddDays(-1), + LifecycleStatus = LifecycleStatus.Canceled, + InternalWONumber = "10000000004" + }); + + await context.SaveChangesAsync(); + + var dataService = new WorkOrderAdvancedSearchDataService(context); + var service = new SeaHaven.Services.Implementation.WorkOrderAdvancedSearchService(dataService); + + var result = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = DateOnly.FromDateTime(today.AddMonths(-1)), + DateTo = DateOnly.FromDateTime(today.AddMonths(1)), + Overdue = true, + Page = 0, + PageSize = 50 + }, null); + + var overdue = Assert.Single(result.Items); + Assert.Equal(0, result.Page); + Assert.Equal(2, overdue.Id); + Assert.True(overdue.IsPastDue); + Assert.DoesNotContain(result.Items, i => i.Id == 1); + Assert.DoesNotContain(result.Items, i => i.Id == 3); + Assert.DoesNotContain(result.Items, i => i.Id == 4); + } + + [Fact] + public async Task SearchAsync_TreatsOtherAsRealTypeFilter_NotOverdueSentinel() + { + await using var context = CreateContext(); + var today = DateTime.UtcNow.Date; + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + WorkOrderType = WorkOrderType.PM, + ScheduledDate = today.AddDays(2), + LifecycleStatus = LifecycleStatus.Scheduled, + InternalWONumber = "10000000001" + }, + new WorkOrder + { + Id = 2, + WorkOrderType = WorkOrderType.Other, + ScheduledDate = today.AddDays(2), + LifecycleStatus = LifecycleStatus.Scheduled, + InternalWONumber = "10000000002" + }, + new WorkOrder + { + Id = 3, + WorkOrderType = WorkOrderType.Reactive, + ScheduledDate = today.AddDays(-3), + LifecycleStatus = LifecycleStatus.Scheduled, + InternalWONumber = "10000000003" + }); + + await context.SaveChangesAsync(); + + var dataService = new WorkOrderAdvancedSearchDataService(context); + var service = new SeaHaven.Services.Implementation.WorkOrderAdvancedSearchService(dataService); + + var result = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = DateOnly.FromDateTime(today.AddMonths(-1)), + DateTo = DateOnly.FromDateTime(today.AddMonths(1)), + Types = new List { WorkOrderType.PM, WorkOrderType.Other }, + Page = 0, + PageSize = 50 + }, null); + + Assert.Equal(2, result.TotalCount); + Assert.Equal(0, result.Page); + Assert.Contains(result.Items, i => i.Id == 1 && i.WorkOrderType == WorkOrderType.PM); + Assert.Contains(result.Items, i => i.Id == 2 && i.WorkOrderType == WorkOrderType.Other); + Assert.DoesNotContain(result.Items, i => i.Id == 3); + } + [Fact] public async Task SearchAsync_IncludesUnscheduledRows() {