using Data.SeaHavenIndustries; using Data.SeaHavenIndustries.Enums; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Implementation; using SeaHaven.Services.DTOs; using SeaHaven.Services.Implementation; using SeaHaven.Services.Interfaces; using SeaHaven.Services.Validation; namespace SeaHavenIndustries.Tests; public class WorkOrderBoardCreateSyncLockTests { [Fact] public async Task AfterShocCreate_SyncRejectsLockedSiteCode() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; await using var context = new ApplicationDbContext(options); WorkOrderAccountTestHelpers.SeedBoardCreateScope(context); var boardData = new WorkOrderBoardDataService(context); var mutationData = new WorkOrderBoardMutationDataService(context); var resolver = WorkOrderAccountTestHelpers.Resolver(context); var boardService = new WorkOrderBoardService(boardData, resolver); var fieldLocks = new WorkOrderFieldLockService(new WorkOrderFieldLockDataService(context)); var audit = new WorkOrderAuditService(new WorkOrderAuditDataService(context), fieldLocks); var createService = new WorkOrderBoardCreateService( boardData, mutationData, boardService, audit, new WorkOrderBoardCreateValidation(), resolver, new WorkOrderPocDataService(context)); var policy = new SyncFieldMergePolicy(fieldLocks); await createService.CreateAsync(new WorkOrderBoardCreateRequestDto { WorkOrderType = WorkOrderType.PM, SiteCode = "BK5", LocationId = 1 }, WorkOrderAccountTestHelpers.AccountUser("dispatcher-1"), "dispatcher-1"); var wo = await context.workOrders.SingleAsync(); var syncContext = new WorkOrderSyncContext { WorkOrder = wo, FieldLocks = fieldLocks, Audit = audit }; var applied = await policy.TryApplyAsync(syncContext, "SiteCode", "SYNC-SITE"); Assert.False(applied); Assert.Equal("BK5", wo.SiteCode); var rejected = await context.WorkOrderAuditLogs .SingleAsync(l => l.Action == "SyncRejected" && l.FieldName == "SiteCode"); Assert.Equal("SYNC-SITE", rejected.NewValue); } [Fact] public async Task AfterShocCreate_SyncCanUpdateUnlockedField_NotInShocSet() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; await using var context = new ApplicationDbContext(options); WorkOrderAccountTestHelpers.SeedBoardCreateScope(context); var boardData = new WorkOrderBoardDataService(context); var mutationData = new WorkOrderBoardMutationDataService(context); var resolver = WorkOrderAccountTestHelpers.Resolver(context); var boardService = new WorkOrderBoardService(boardData, resolver); var fieldLocks = new WorkOrderFieldLockService(new WorkOrderFieldLockDataService(context)); var audit = new WorkOrderAuditService(new WorkOrderAuditDataService(context), fieldLocks); var createService = new WorkOrderBoardCreateService( boardData, mutationData, boardService, audit, new WorkOrderBoardCreateValidation(), resolver, new WorkOrderPocDataService(context)); var policy = new SyncFieldMergePolicy(fieldLocks); await createService.CreateAsync(new WorkOrderBoardCreateRequestDto { WorkOrderType = WorkOrderType.PM, SiteCode = "BK5", LocationId = 1 }, WorkOrderAccountTestHelpers.AccountUser("dispatcher-1"), "dispatcher-1"); var wo = await context.workOrders.SingleAsync(); wo.Customer = "Original"; await context.SaveChangesAsync(); var syncContext = new WorkOrderSyncContext { WorkOrder = wo, FieldLocks = fieldLocks, Audit = audit }; // Customer is not in SyncFieldMergePolicy apply switch — use Description which wasn't set on create var applied = await policy.TryApplyAsync(syncContext, "Description", "From sync"); Assert.True(applied); Assert.Equal("From sync", wo.Description); } }