fix(providers): honor start day for overnight peak windows (#11718)

Fixes overnight peak-hour windows so 'days' is interpreted as the UTC day the window STARTS, keeping the post-midnight segment protected until its exclusive end boundary — a Monday-only 22:00-02:00 window incorrectly returned inactive on Tuesday at 01:00Z. TDD RED demonstrated, 5/5 focused tests passing. Follow-up to #11622. Thanks!
This commit is contained in:
Paco Cartones
2026-08-28 16:14:33 +02:00
committed by GitHub
parent 808992a717
commit db87fb6207
3 changed files with 71 additions and 1 deletions

View File

@@ -0,0 +1 @@
- **fix(providers):** Keep overnight peak-hour protection active after midnight according to the window's configured start day ([#11718](https://github.com/diegosouzapw/OmniRoute/pull/11718)) — thanks @pacocartones

View File

@@ -109,11 +109,13 @@ function isDayAllowed(window: PeakHourWindow, date: Date): boolean {
}
function windowActiveAt(window: PeakHourWindow, date: Date): boolean {
if (!isDayAllowed(window, date)) return false;
const start = parseUtcTimeMinutes(window.startUtc);
const end = parseUtcTimeMinutes(window.endUtc);
if (start === null || end === null || start === end) return false;
const now = date.getUTCHours() * 60 + date.getUTCMinutes();
const effectiveDay =
start > end && now < end ? new Date(date.getTime() - MINUTES_PER_DAY * 60_000) : date;
if (!isDayAllowed(window, effectiveDay)) return false;
return start < end ? now >= start && now < end : now >= start || now < end;
}

View File

@@ -55,6 +55,73 @@ test("peak-hour protection honors weekdays and end boundary", () => {
);
});
test("overnight windows apply their start day after midnight", () => {
const mondayWindow = {
peakHourProtection: {
enabled: true,
mode: "block",
windows: [{ days: ["mon"], startUtc: "22:00", endUtc: "02:00" }],
},
};
const mondayNight = evaluatePeakHourProtection(
mondayWindow,
new Date("2026-08-24T23:00:00.000Z")
);
assert.equal(mondayNight.active, true);
assert.equal(mondayNight.retryAfter, "2026-08-25T02:00:00.000Z");
const tuesdayEarly = evaluatePeakHourProtection(
mondayWindow,
new Date("2026-08-25T01:00:00.000Z")
);
assert.equal(tuesdayEarly.active, true);
assert.equal(tuesdayEarly.retryAfter, "2026-08-25T02:00:00.000Z");
assert.deepEqual(evaluatePeakHourProtection(mondayWindow, new Date("2026-08-25T02:00:00.000Z")), {
active: false,
});
assert.deepEqual(evaluatePeakHourProtection(mondayWindow, new Date("2026-08-25T23:00:00.000Z")), {
active: false,
});
const tuesdayWindow = {
peakHourProtection: {
enabled: true,
mode: "block",
windows: [{ days: ["tue"], startUtc: "22:00", endUtc: "02:00" }],
},
};
assert.deepEqual(
evaluatePeakHourProtection(tuesdayWindow, new Date("2026-08-25T01:00:00.000Z")),
{ active: false }
);
const sundayWindow = {
peakHourProtection: {
enabled: true,
mode: "block",
windows: [{ days: ["sun"], startUtc: "22:00", endUtc: "02:00" }],
},
};
assert.equal(
evaluatePeakHourProtection(sundayWindow, new Date("2026-08-24T01:00:00.000Z")).active,
true
);
const dailyWindow = {
peakHourProtection: {
enabled: true,
mode: "block",
windows: [{ startUtc: "22:00", endUtc: "02:00" }],
},
};
assert.equal(
evaluatePeakHourProtection(dailyWindow, new Date("2026-08-25T01:00:00.000Z")).active,
true
);
});
test("peak-hour protection supports daily Z.ai-style windows", () => {
const state = evaluatePeakHourProtection(
{