diff --git a/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs b/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs index 231613b..fe3d37d 100644 --- a/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs +++ b/SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs @@ -260,6 +260,163 @@ public class WorkOrderAdvancedSearchServiceTests Assert.Equal(200, result.PageSize); } + [Theory] + [InlineData(25)] + [InlineData(50)] + [InlineData(200)] + public async Task SearchAsync_UnassignedDispatcher_AcceptsBoardPagerPageSizes(int pageSize) + { + await using var context = CreateContext(); + var dataService = new WorkOrderAdvancedSearchDataService(context); + var service = new SeaHaven.Services.Implementation.WorkOrderAdvancedSearchService( + dataService, + WorkOrderAccountTestHelpers.Resolver(context)); + + var result = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = new DateOnly(2000, 1, 1), + DateTo = new DateOnly(2099, 12, 31), + Dispatchers = new List { "__unassigned__" }, + Page = 0, + PageSize = pageSize + }, WorkOrderAccountTestHelpers.OrgWideAdmin(), null); + + Assert.Equal(pageSize, result.PageSize); + Assert.Equal(0, result.Page); + Assert.Equal(0, result.PageBase); + } + + [Fact] + public async Task SearchAsync_UnassignedDispatcher_WideCustomRange_IncludesDatedOutsideWeekAndUndated() + { + await using var context = CreateContext(); + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + InternalWONumber = "10000000001", + AssignTo = null, + ScheduledDate = new DateTime(2026, 6, 23), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 2, + InternalWONumber = "10000000002", + AssignTo = null, + ScheduledDate = new DateTime(2026, 8, 4), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 3, + InternalWONumber = "10000000003", + AssignTo = "", + ScheduledDate = null, + LifecycleStatus = LifecycleStatus.Incomplete + }, + new WorkOrder + { + Id = 4, + InternalWONumber = "10000000004", + AssignTo = "user-a", + ScheduledDate = new DateTime(2026, 6, 24), + LifecycleStatus = LifecycleStatus.Scheduled + }); + + await context.SaveChangesAsync(); + + var dataService = new WorkOrderAdvancedSearchDataService(context); + var service = new SeaHaven.Services.Implementation.WorkOrderAdvancedSearchService( + dataService, + WorkOrderAccountTestHelpers.Resolver(context)); + + var result = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = new DateOnly(2000, 1, 1), + DateTo = new DateOnly(2099, 12, 31), + Dispatchers = new List { "__unassigned__" }, + Page = 0, + PageSize = 50 + }, WorkOrderAccountTestHelpers.OrgWideAdmin(), null); + + Assert.Equal(3, result.TotalCount); + Assert.Equal(50, result.PageSize); + Assert.Contains(result.Items, i => i.Id == 1 && i.DispatcherId == null); + Assert.Contains(result.Items, i => i.Id == 2 && i.DispatcherId == null); + Assert.Contains(result.Items, i => i.Id == 3); + Assert.DoesNotContain(result.Items, i => i.Id == 4); + } + + [Fact] + public async Task SearchAsync_UnassignedDispatcher_PaginatesWideCustomRange() + { + await using var context = CreateContext(); + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + InternalWONumber = "10000000001", + AssignTo = null, + ScheduledDate = new DateTime(2026, 6, 23), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 2, + InternalWONumber = "10000000002", + AssignTo = null, + ScheduledDate = new DateTime(2026, 8, 4), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 3, + InternalWONumber = "10000000003", + AssignTo = null, + ScheduledDate = null, + LifecycleStatus = LifecycleStatus.Incomplete + }); + + await context.SaveChangesAsync(); + + var dataService = new WorkOrderAdvancedSearchDataService(context); + var service = new SeaHaven.Services.Implementation.WorkOrderAdvancedSearchService( + dataService, + WorkOrderAccountTestHelpers.Resolver(context)); + + var page0 = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = new DateOnly(2000, 1, 1), + DateTo = new DateOnly(2099, 12, 31), + Dispatchers = new List { "__unassigned__" }, + Page = 0, + PageSize = 2 + }, WorkOrderAccountTestHelpers.OrgWideAdmin(), null); + + var page1 = await service.SearchAsync(new SeaHaven.Services.DTOs.WorkOrderAdvancedSearchQueryDto + { + DatePreset = SeaHaven.Services.Helpers.WorkOrderAdvancedSearchDatePreset.Custom, + DateFrom = new DateOnly(2000, 1, 1), + DateTo = new DateOnly(2099, 12, 31), + Dispatchers = new List { "__unassigned__" }, + Page = 1, + PageSize = 2 + }, WorkOrderAccountTestHelpers.OrgWideAdmin(), null); + + Assert.Equal(3, page0.TotalCount); + Assert.Equal(2, page0.PageSize); + Assert.Equal(2, page0.Items.Count()); + Assert.Equal(3, page1.TotalCount); + Assert.Single(page1.Items); + Assert.Empty(page0.Items.Select(i => i.Id).Intersect(page1.Items.Select(i => i.Id))); + } + [Fact] public async Task SearchAsync_PageZero_ReturnsFirstPage() { diff --git a/SeaHavenIndustries.Tests/WorkOrderBoardServiceTests.cs b/SeaHavenIndustries.Tests/WorkOrderBoardServiceTests.cs index 517c70e..b9fe3a4 100644 --- a/SeaHavenIndustries.Tests/WorkOrderBoardServiceTests.cs +++ b/SeaHavenIndustries.Tests/WorkOrderBoardServiceTests.cs @@ -163,6 +163,121 @@ public class WorkOrderBoardDataServiceTests Assert.Equal("user-a", result.ScheduledRows[0].AssignTo); } + [Fact] + public async Task GetBoardRows_DatedUnassigned_AppearsInScheduledNotUnscheduled() + { + await using var context = CreateContext(); + var weekStart = new DateOnly(2026, 6, 22); + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + InternalWONumber = "10000000001", + AssignTo = null, + ScheduledDate = new DateTime(2026, 6, 23), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 2, + InternalWONumber = "10000000002", + AssignTo = "user-a", + ScheduledDate = new DateTime(2026, 6, 24), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 3, + InternalWONumber = "10000000003", + AssignTo = null, + ScheduledDate = null, + LifecycleStatus = LifecycleStatus.Incomplete + }); + + await context.SaveChangesAsync(); + + var service = new WorkOrderBoardDataService(context); + var result = await service.GetBoardRowsAsync(new WorkOrderBoardQuery( + weekStart, + weekStart.AddDays(4), + null, + false, + null, + false, + null, + null)); + + Assert.Equal(2, result.ScheduledRows.Count); + Assert.Contains(result.ScheduledRows, r => r.Id == 1 && r.AssignTo == null); + Assert.Contains(result.ScheduledRows, r => r.Id == 2 && r.AssignTo == "user-a"); + Assert.DoesNotContain(result.ScheduledRows, r => r.Id == 3); + Assert.Empty(result.UnscheduledRows); + Assert.Equal(2, result.ScheduledTotalBeforeSearch); + } + + [Fact] + public async Task GetBoardRows_FiltersByUnassignedDispatcher_ReturnsOnlyUnassignedInWeek() + { + await using var context = CreateContext(); + var weekStart = new DateOnly(2026, 6, 22); + + context.workOrders.AddRange( + new WorkOrder + { + Id = 1, + InternalWONumber = "10000000001", + AssignTo = null, + ScheduledDate = new DateTime(2026, 6, 23), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 2, + InternalWONumber = "10000000002", + AssignTo = "user-a", + ScheduledDate = new DateTime(2026, 6, 24), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 3, + InternalWONumber = "10000000003", + AssignTo = "", + ScheduledDate = new DateTime(2026, 6, 25), + LifecycleStatus = LifecycleStatus.Scheduled + }, + new WorkOrder + { + Id = 4, + InternalWONumber = "10000000004", + AssignTo = null, + ScheduledDate = null, + LifecycleStatus = LifecycleStatus.Incomplete + }); + + await context.SaveChangesAsync(); + + var service = new WorkOrderBoardDataService(context); + var result = await service.GetBoardRowsAsync(new WorkOrderBoardQuery( + weekStart, + weekStart.AddDays(4), + new[] { "__unassigned__" }, + false, + null, + false, + null, + null)); + + Assert.Equal(2, result.ScheduledRows.Count); + Assert.Contains(result.ScheduledRows, r => r.Id == 1); + Assert.Contains(result.ScheduledRows, r => r.Id == 3); + Assert.DoesNotContain(result.ScheduledRows, r => r.Id == 2); + Assert.DoesNotContain(result.ScheduledRows, r => r.Id == 4); + Assert.Empty(result.UnscheduledRows); + Assert.Equal(2, result.ScheduledTotalBeforeSearch); + } + [Fact] public async Task GetBoardRows_MyWorkOrders_FiltersCurrentUser() {