test(workorders): cover technician-name search for cleared assignment

WorkOrderBoardSearchFilter now skips the vendor ContactName for work
orders whose TechnicianAssigned is explicitly false. Exercise the
predicate through SQLite so relational null semantics are covered:
legacy null and true rows still match a technician-name search, the
explicitly cleared row does not, and the vendor company name still
matches all three.
This commit is contained in:
Alexandre Brandizzi 2026-09-29 18:40:57 -03:00
parent 35adef5808
commit 2de65539a1

View file

@ -2,6 +2,7 @@ using Data.SeaHavenIndustries;
using Data.SeaHavenIndustries.Enums;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using SeaHaven.DataServices.Helpers;
using SeaHaven.DataServices.Implementation;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Helpers;
@ -116,6 +117,78 @@ public class WorkOrderTechnicianAssignmentRelationalTests
Assert.Equal(5, workOrderB.VendorId);
}
[Fact]
public async Task TechnicianNameSearch_MatchesLegacyAndAssignedRows_ButNotExplicitlyClearedRow()
{
await using var connection = new SqliteConnection("Data Source=:memory:;Foreign Keys=True");
await connection.OpenAsync();
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlite(connection)
.Options;
await using (var seed = new SqliteBoardTestDbContext(options))
{
await seed.Database.EnsureCreatedAsync();
await WorkOrderAccountTestHelpers.EnsureAccountAsync(seed);
seed.Vendors.Add(new Vendor
{
Id = 5,
CompanyName = "Acme HVAC",
ContactName = "Technician One",
CompanyPhone = "312-555-0100"
});
seed.Dispatches.AddRange(
new Dispatch { Id = 10, VendorId = 5, Status = "Sent", RowVersion = new byte[] { 1, 0, 0, 0, 0, 0, 0, 2 } },
new Dispatch { Id = 11, VendorId = 5, Status = "Sent", RowVersion = new byte[] { 2, 0, 0, 0, 0, 0, 0, 2 } },
new Dispatch { Id = 12, VendorId = 5, Status = "Sent", RowVersion = new byte[] { 3, 0, 0, 0, 0, 0, 0, 2 } });
seed.workOrders.AddRange(
new WorkOrder
{
Id = 1,
AccountId = 1,
LifecycleStatus = LifecycleStatus.Scheduled,
PrimaryDispatchId = 10,
TechnicianAssigned = null,
RowVersion = new byte[] { 1, 0, 0, 0, 0, 0, 0, 1 }
},
new WorkOrder
{
Id = 2,
AccountId = 1,
LifecycleStatus = LifecycleStatus.Scheduled,
PrimaryDispatchId = 11,
TechnicianAssigned = true,
RowVersion = new byte[] { 2, 0, 0, 0, 0, 0, 0, 1 }
},
new WorkOrder
{
Id = 3,
AccountId = 1,
LifecycleStatus = LifecycleStatus.Scheduled,
PrimaryDispatchId = 12,
TechnicianAssigned = false,
RowVersion = new byte[] { 3, 0, 0, 0, 0, 0, 0, 1 }
});
await seed.SaveChangesAsync();
}
await using var context = new SqliteBoardTestDbContext(options);
var technicianMatches = await WorkOrderBoardSearchFilter
.Apply(context.workOrders.AsQueryable(), "Technician One")
.Select(w => w.Id)
.OrderBy(id => id)
.ToListAsync();
Assert.Equal(new[] { 1, 2 }, technicianMatches);
var companyMatches = await WorkOrderBoardSearchFilter
.Apply(context.workOrders.AsQueryable(), "Acme HVAC")
.Select(w => w.Id)
.OrderBy(id => id)
.ToListAsync();
Assert.Equal(new[] { 1, 2, 3 }, companyMatches);
}
private sealed class SqliteBoardTestDbContext : ApplicationDbContext
{
public SqliteBoardTestDbContext(DbContextOptions<ApplicationDbContext> options)