mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-02 22:43:31 +00:00
A reschedule moves the work order into its new week at the moment of the reschedule, so Add-On now compares that moment with the new week's cutoff, matching the prototype. Moves within the same week keep the current value. Previously an older work order moved into a week already past its cutoff stayed off because it was created before that cutoff (SH-412).
192 lines
6.6 KiB
C#
192 lines
6.6 KiB
C#
using SeaHaven.Services.Helpers;
|
|
|
|
namespace SeaHavenIndustries.Tests;
|
|
|
|
public class WorkOrderAddonCutoffTests
|
|
{
|
|
// Schedule week Mon 2026-06-22 → cutoff Sat 2026-06-20 23:59:59 UTC
|
|
private static readonly DateTime ScheduleMonday = new(2026, 6, 22, 0, 0, 0, DateTimeKind.Utc);
|
|
private static readonly DateTime ExpectedCutoff = new(2026, 6, 20, 23, 59, 59, DateTimeKind.Utc);
|
|
|
|
[Fact]
|
|
public void GetAddonCutoffUtc_FromScheduledDate_IsPriorSaturdayEndOfDay()
|
|
{
|
|
// Wednesday in schedule week
|
|
var cutoff = WorkOrderAddonCutoff.GetAddonCutoffUtc(new DateTime(2026, 6, 24, 15, 0, 0, DateTimeKind.Utc));
|
|
Assert.Equal(ExpectedCutoff, cutoff);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetAddonCutoffUtc_FromTargetWeekMonday_IsPriorSaturdayEndOfDay()
|
|
{
|
|
var cutoff = WorkOrderAddonCutoff.GetAddonCutoffUtc(new DateOnly(2026, 6, 22));
|
|
Assert.Equal(ExpectedCutoff, cutoff);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetAddonCutoffUtc_FromMondayAnchor_MatchesGetWeekStartMondayMinusTwo()
|
|
{
|
|
var monday = WorkOrderBoardMutationRules.GetWeekStartMonday(ScheduleMonday);
|
|
Assert.Equal(ScheduleMonday.Date, monday.Date);
|
|
Assert.Equal(ExpectedCutoff, WorkOrderAddonCutoff.GetAddonCutoffUtc(ScheduleMonday));
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_AfterCutoff_ReturnsTrue_IgnoresManualFalse()
|
|
{
|
|
var created = new DateTime(2026, 6, 21, 0, 0, 0, DateTimeKind.Utc);
|
|
var result = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
created,
|
|
scheduledDate: new DateTime(2026, 6, 24),
|
|
targetWeek: null,
|
|
manualOverride: false);
|
|
|
|
Assert.True(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_BeforeCutoff_ReturnsFalse_IgnoresManualTrue()
|
|
{
|
|
var created = new DateTime(2026, 6, 20, 23, 59, 59, DateTimeKind.Utc);
|
|
var result = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
created,
|
|
scheduledDate: new DateTime(2026, 6, 24),
|
|
targetWeek: null,
|
|
manualOverride: true);
|
|
|
|
Assert.False(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_ExactlyAtCutoff_ReturnsFalse()
|
|
{
|
|
var result = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
ExpectedCutoff,
|
|
scheduledDate: ScheduleMonday,
|
|
targetWeek: null,
|
|
manualOverride: true);
|
|
|
|
Assert.False(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_TargetWeekOnly_UsesCutoff()
|
|
{
|
|
var after = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
new DateTime(2026, 6, 21, 12, 0, 0, DateTimeKind.Utc),
|
|
scheduledDate: null,
|
|
targetWeek: new DateOnly(2026, 6, 22),
|
|
manualOverride: false);
|
|
|
|
var before = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
new DateTime(2026, 6, 19, 12, 0, 0, DateTimeKind.Utc),
|
|
scheduledDate: null,
|
|
targetWeek: new DateOnly(2026, 6, 22),
|
|
manualOverride: true);
|
|
|
|
Assert.True(after);
|
|
Assert.False(before);
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_NoSchedule_UsesManualOverride()
|
|
{
|
|
Assert.True(WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
DateTime.UtcNow, null, null, manualOverride: true));
|
|
Assert.False(WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
DateTime.UtcNow, null, null, manualOverride: false));
|
|
Assert.False(WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
DateTime.UtcNow, null, null, manualOverride: null));
|
|
}
|
|
|
|
[Fact]
|
|
public void Compute_ScheduledDatePreferredOverTargetWeek()
|
|
{
|
|
// Target week far future (cutoff after created) would be false;
|
|
// scheduled date near past (cutoff before created) → true.
|
|
var created = new DateTime(2026, 7, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
var result = WorkOrderAddonCutoff.ComputeIsAddOnAtCreation(
|
|
created,
|
|
scheduledDate: new DateTime(2026, 6, 24),
|
|
targetWeek: new DateOnly(2099, 1, 5),
|
|
manualOverride: false);
|
|
|
|
Assert.True(result);
|
|
}
|
|
|
|
// Rescheduled on Wed 2026-06-24: the week of 06-22 is past its cutoff (Sat 06-20 23:59:59),
|
|
// the week of 06-29 is not (cutoff Sat 06-27 23:59:59).
|
|
private static readonly DateTime RescheduledAt = new(2026, 6, 24, 10, 0, 0, DateTimeKind.Utc);
|
|
|
|
[Fact]
|
|
public void RecalculateOnReschedule_NoSchedule_ReturnsFalse()
|
|
{
|
|
Assert.False(WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule(
|
|
currentIsAddOn: true,
|
|
previousScheduledDate: new DateTime(2026, 6, 24),
|
|
previousTargetWeek: null,
|
|
scheduledDate: null,
|
|
targetWeek: null,
|
|
RescheduledAt));
|
|
}
|
|
|
|
[Fact]
|
|
public void RecalculateOnReschedule_IntoWeekPastCutoff_TurnsOnForWorkOrderCreatedLongBefore()
|
|
{
|
|
// SH-412: the WO was created weeks earlier; it arrives in the current week at the
|
|
// moment of the reschedule, which is already past that week's cutoff.
|
|
var result = WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule(
|
|
currentIsAddOn: false,
|
|
previousScheduledDate: new DateTime(2026, 7, 8),
|
|
previousTargetWeek: null,
|
|
scheduledDate: new DateTime(2026, 6, 25),
|
|
targetWeek: null,
|
|
RescheduledAt);
|
|
|
|
Assert.True(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecalculateOnReschedule_IntoWeekBeforeCutoff_TurnsOff()
|
|
{
|
|
var result = WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule(
|
|
currentIsAddOn: true,
|
|
previousScheduledDate: new DateTime(2026, 6, 24),
|
|
previousTargetWeek: null,
|
|
scheduledDate: new DateTime(2026, 7, 1),
|
|
targetWeek: null,
|
|
RescheduledAt);
|
|
|
|
Assert.False(result);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void RecalculateOnReschedule_WithinSameWeek_KeepsCurrentValue(bool currentIsAddOn)
|
|
{
|
|
var result = WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule(
|
|
currentIsAddOn,
|
|
previousScheduledDate: new DateTime(2026, 6, 22),
|
|
previousTargetWeek: null,
|
|
scheduledDate: new DateTime(2026, 6, 26),
|
|
targetWeek: null,
|
|
RescheduledAt);
|
|
|
|
Assert.Equal(currentIsAddOn, result);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecalculateOnReschedule_FirstScheduleIntoWeekPastCutoff_TurnsOn()
|
|
{
|
|
var result = WorkOrderAddonCutoff.RecalculateIsAddOnOnReschedule(
|
|
currentIsAddOn: false,
|
|
previousScheduledDate: null,
|
|
previousTargetWeek: null,
|
|
scheduledDate: new DateTime(2026, 6, 26),
|
|
targetWeek: null,
|
|
RescheduledAt);
|
|
|
|
Assert.True(result);
|
|
}
|
|
}
|