using Data.SeaHavenIndustries; using Data.SeaHavenIndustries.Enums; using SeaHaven.Services.Helpers; namespace SeaHavenIndustries.Tests; public class WorkOrderDerivedFieldsTests { private static readonly DateOnly Today = DateOnly.FromDateTime(DateTime.UtcNow); private static readonly DateTime Past = DateTime.UtcNow.Date.AddDays(-2); private static readonly DateTime Future = DateTime.UtcNow.Date.AddDays(3); private static readonly DateTime TodayDate = DateTime.UtcNow.Date; [Fact] public void IsPastDue_WhenSchedulePastAndDueFuture_ReturnsTrue() { var wo = new WorkOrder { DueDate = Future, ScheduledDate = Past, LifecycleStatus = LifecycleStatus.Scheduled }; Assert.True(WorkOrderDerivedFields.IsPastDue(wo, Today)); Assert.True(WorkOrderDerivedFields.IsPastDue(wo.ScheduledDate, wo.LifecycleStatus)); } [Fact] public void IsPastDue_WhenScheduleFutureAndDuePast_ReturnsFalse() { var wo = new WorkOrder { DueDate = Past, ScheduledDate = Future, LifecycleStatus = LifecycleStatus.Scheduled }; Assert.False(WorkOrderDerivedFields.IsPastDue(wo, Today)); Assert.False(WorkOrderDerivedFields.IsPastDue(wo.ScheduledDate, wo.LifecycleStatus)); } [Fact] public void IsPastDue_WhenScheduledDateNull_ReturnsFalse() { var wo = new WorkOrder { DueDate = Past, ScheduledDate = null, LifecycleStatus = LifecycleStatus.Scheduled }; Assert.False(WorkOrderDerivedFields.IsPastDue(wo, Today)); Assert.False(WorkOrderDerivedFields.IsPastDue(null, LifecycleStatus.Scheduled)); } [Fact] public void IsPastDue_WhenScheduleEqualsToday_ReturnsFalse() { var wo = new WorkOrder { DueDate = Past, ScheduledDate = TodayDate, LifecycleStatus = LifecycleStatus.Scheduled }; Assert.False(WorkOrderDerivedFields.IsPastDue(wo, Today)); } [Theory] [InlineData(LifecycleStatus.Completed)] [InlineData(LifecycleStatus.Canceled)] public void IsPastDue_WhenTerminal_ReturnsFalse(LifecycleStatus status) { var wo = new WorkOrder { DueDate = Past, ScheduledDate = Past, LifecycleStatus = status }; Assert.False(WorkOrderDerivedFields.IsPastDue(wo, Today)); Assert.False(WorkOrderDerivedFields.IsPastDue(Past, status)); } [Fact] public void ApplyAutoSchedule_WhenDateWithoutAssignee_PromotesToScheduled() { var wo = new WorkOrder { LifecycleStatus = LifecycleStatus.Incomplete, ScheduledDate = new DateTime(2026, 6, 25) }; Assert.True(WorkOrderDerivedFields.ApplyAutoScheduleIfEligible(wo)); Assert.Equal(LifecycleStatus.Scheduled, wo.LifecycleStatus); } [Fact] public void ApplyLifecycleFromSchedule_PendingWithDate_PromotesToScheduled() { var wo = new WorkOrder { LifecycleStatus = LifecycleStatus.Pending, ScheduledDate = new DateTime(2026, 6, 25) }; var changes = WorkOrderDerivedFields.ApplyLifecycleFromSchedule(wo); Assert.Equal(LifecycleStatus.Scheduled, wo.LifecycleStatus); Assert.Single(changes); Assert.Equal(AuditActionType.StatusChanged, changes[0].Action); } [Fact] public void ApplyLifecycleFromSchedule_ScheduledWithoutDate_DemotesToPending() { var wo = new WorkOrder { LifecycleStatus = LifecycleStatus.Scheduled, ScheduledDate = null }; var changes = WorkOrderDerivedFields.ApplyLifecycleFromSchedule(wo); Assert.Equal(LifecycleStatus.Pending, wo.LifecycleStatus); Assert.Single(changes); Assert.Equal(LifecycleStatus.Pending.ToString(), changes[0].NewValue); } [Fact] public void ApplyAutoSchedule_WeekOnly_DoesNotPromote() { var wo = new WorkOrder { LifecycleStatus = LifecycleStatus.Incomplete, ScheduledDate = new DateTime(2026, 6, 25), ScheduleWeekOnly = true, TargetWeek = new DateOnly(2026, 6, 22) }; Assert.False(WorkOrderDerivedFields.ApplyAutoScheduleIfEligible(wo)); Assert.Equal(LifecycleStatus.Incomplete, wo.LifecycleStatus); } [Fact] public void ApplyLifecycleFromSchedule_InProgress_UnchangedWhenDateCleared() { var wo = new WorkOrder { LifecycleStatus = LifecycleStatus.InProgress, ScheduledDate = null }; Assert.Empty(WorkOrderDerivedFields.ApplyLifecycleFromSchedule(wo)); Assert.Equal(LifecycleStatus.InProgress, wo.LifecycleStatus); } [Fact] public void SetInitialLifecycleStatus_NewWo_StartsIncompleteThenAutoSchedules() { var wo = new WorkOrder { ScheduledDate = new DateTime(2026, 6, 25) }; WorkOrderDerivedFields.SetInitialLifecycleStatus(wo); Assert.Equal(LifecycleStatus.Scheduled, wo.LifecycleStatus); } }