using GmRelay.Web.Services; namespace GmRelay.Bot.Tests.Web; public sealed class BatchSchedulePlannerTests { [Fact] public void BuildFixedIntervalSchedule_OrdersSessionsAndAppliesInterval() { var firstScheduledAt = new DateTime(2026, 5, 4, 16, 0, 0, DateTimeKind.Utc); var currentSchedule = new[] { new DateTime(2026, 4, 28, 16, 0, 0, DateTimeKind.Utc), new DateTime(2026, 4, 21, 16, 0, 0, DateTimeKind.Utc), new DateTime(2026, 5, 5, 16, 0, 0, DateTimeKind.Utc) }; var result = BatchSchedulePlanner.BuildFixedIntervalSchedule(currentSchedule, firstScheduledAt, intervalDays: 7); Assert.Equal( [ firstScheduledAt, firstScheduledAt.AddDays(7), firstScheduledAt.AddDays(14) ], result); } [Fact] public void BuildFixedIntervalSchedule_RejectsNonPositiveInterval() { var currentSchedule = new[] { new DateTime(2026, 4, 28, 16, 0, 0, DateTimeKind.Utc) }; var firstScheduledAt = new DateTime(2026, 5, 4, 16, 0, 0, DateTimeKind.Utc); var action = () => BatchSchedulePlanner.BuildFixedIntervalSchedule(currentSchedule, firstScheduledAt, intervalDays: 0); Assert.Throws(action); } [Theory] [InlineData(BatchCloneInterval.NextWeek, 2026, 5, 8)] [InlineData(BatchCloneInterval.NextMonth, 2026, 6, 1)] public void ShiftForClone_AppliesRequestedCalendarShift(BatchCloneInterval interval, int expectedYear, int expectedMonth, int expectedDay) { var scheduledAt = new DateTime(2026, 5, 1, 16, 30, 0, DateTimeKind.Utc); var result = BatchSchedulePlanner.ShiftForClone(scheduledAt, interval); Assert.Equal(new DateTime(expectedYear, expectedMonth, expectedDay, 16, 30, 0, DateTimeKind.Utc), result); } }