using Data.SeaHavenIndustries; using Data.SeaHavenIndustries.Enums; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Implementation; using SeaHaven.Services.DTOs; using SeaHaven.Services.Implementation; using SeaHaven.Services.Validation; namespace SeaHavenIndustries.Tests; public class WorkOrderBoardCreateRelationalTests { [Fact] public async Task Create_AuditAndFieldLocks_UseGeneratedWorkOrderId() { await using var connection = new SqliteConnection("DataSource=:memory:"); await connection.OpenAsync(); var options = new DbContextOptionsBuilder() .UseSqlite(connection) .Options; await using var context = new SqliteBoardTestDbContext(options); await context.Database.EnsureCreatedAsync(); const string actorId = "actor-1"; context.Users.Add(new ApplicationUser { Id = actorId, UserName = "actor-1", NormalizedUserName = "ACTOR-1", Email = "actor@test.local", NormalizedEmail = "ACTOR@TEST.LOCAL" }); await context.SaveChangesAsync(); var boardData = new WorkOrderBoardDataService(context); var boardService = new WorkOrderBoardService(boardData); var fieldLocks = new WorkOrderFieldLockService(context); var audit = new WorkOrderAuditService(context, fieldLocks); var service = new WorkOrderBoardCreateService( context, boardData, boardService, audit, new WorkOrderBoardCreateValidation()); var result = await service.CreateAsync(new WorkOrderBoardCreateRequestDto { WorkOrderType = WorkOrderType.PM, SiteCode = "BK5", Description = "Relational create" }, actorId); Assert.True(result.Id > 0); var logs = await context.WorkOrderAuditLogs.AsNoTracking().ToListAsync(); var locks = await context.WorkOrderFieldLocks.AsNoTracking().ToListAsync(); Assert.NotEmpty(logs); Assert.NotEmpty(locks); Assert.Contains(logs, l => l.Action == "Create"); Assert.All(logs, l => Assert.Equal(result.Id, l.WorkOrderId)); Assert.All(locks, l => Assert.Equal(result.Id, l.WorkOrderId)); Assert.DoesNotContain(logs, l => l.WorkOrderId == 0); Assert.DoesNotContain(locks, l => l.WorkOrderId == 0); } private sealed class SqliteBoardTestDbContext : ApplicationDbContext { public SqliteBoardTestDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // SQL Server filtered index syntax is invalid on SQLite. foreach (var index in builder.Model.GetEntityTypes().SelectMany(e => e.GetIndexes())) { if (index.GetFilter() != null) index.SetFilter(null); } // SQLite has no rowversion type; treat as plain nullable blobs. foreach (var entityType in new[] { typeof(WorkOrder), typeof(Dispatch) }) { var property = builder.Entity(entityType).Property("RowVersion").Metadata; property.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.Never; property.IsConcurrencyToken = false; } } } }