using System.Security.Claims; using Api.SeaHavenIndustries.Controllers; using Api.SeaHavenIndustries.DTOs; using Data.SeaHavenIndustries; using Data.SeaHavenIndustries.Enums; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging.Abstractions; using SeaHaven.DataServices.Implementation; using SeaHaven.DataServices.Models; using SeaHaven.Services.Implementation; using SeaHaven.Services.Validation; namespace SeaHavenIndustries.Tests; public sealed class WorkOrderEditAddonRescheduleTests { [Fact] public async Task EditWorkorder_RescheduleIntoEarlierWeek_EnablesAndAuditsAddOn() { await using var context = CreateContext(); context.workOrders.Add(new WorkOrder { Id = 1, CreatedDate = new DateTime(2026, 6, 21, 0, 0, 0, DateTimeKind.Utc), ScheduledDate = new DateTime(2026, 6, 29), IsAddOn = false }); await context.SaveChangesAsync(); var result = await CreateController(context).Editworkorder(new EditWorkorder_DTO { Id = 1, ScheduledDate = new DateTime(2026, 6, 25) }); Assert.IsType(result); var persisted = await context.workOrders.SingleAsync(x => x.Id == 1); Assert.Equal(new DateTime(2026, 6, 25), persisted.ScheduledDate); Assert.True(persisted.IsAddOn); Assert.Equal(1, persisted.RescheduleCount); var audit = await context.WorkOrderAuditLogs .Where(x => x.WorkOrderId == 1) .ToListAsync(); Assert.Single(audit); Assert.Contains(audit, x => x.FieldName?.Contains("Schedule On", StringComparison.Ordinal) == true); Assert.Contains(audit, x => x.FieldName?.Contains("IsAddOn", StringComparison.Ordinal) == true); Assert.Contains(audit, x => x.FieldName?.Contains("RescheduleCount: 0 → 1", StringComparison.Ordinal) == true); } [Fact] public async Task EditWorkorder_FirstSchedule_SetsOriginalWeekAndPromotesIncomplete() { await using var context = CreateContext(); context.workOrders.Add(new WorkOrder { Id = 1, CreatedDate = new DateTime(2026, 6, 21, 0, 0, 0, DateTimeKind.Utc), LifecycleStatus = LifecycleStatus.Incomplete }); await context.SaveChangesAsync(); var result = await CreateController(context).Editworkorder(new EditWorkorder_DTO { Id = 1, ScheduledDate = new DateTime(2026, 7, 1) }); Assert.IsType(result); var persisted = await context.workOrders.SingleAsync(x => x.Id == 1); Assert.Equal(new DateOnly(2026, 7, 1), persisted.OriginalDate); Assert.Equal(new DateOnly(2026, 6, 29), persisted.OriginalWeek); Assert.Equal(0, persisted.RescheduleCount); Assert.Equal(LifecycleStatus.Scheduled, persisted.LifecycleStatus); } private static ApplicationDbContext CreateContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; return new ApplicationDbContext(options); } private static WorkOrderController CreateController(ApplicationDbContext context) { var accountResolver = WorkOrderAccountTestHelpers.Resolver(context); var workOrderService = new WorkOrderService( new WorkOrderDataService(context), new CommentDataService(context), new UserDataService(context), new QuotesDataService(context), fileStorage: null!, new CreateWorkOrderValidation(), new UpdateWorkOrderValidation(), accountResolver); return new WorkOrderController( workOrderService, accountResolver, NullLogger.Instance) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal(new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, "dispatcher-1") }, authenticationType: "test")) } } }; } }