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
This commit is contained in:
Alexandre Brandizzi 2026-07-24 13:58:35 -03:00
parent f6c7c1ec7f
commit 6697c1394a

View file

@ -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> { 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()
{