From 0e26bda83c6d510bb27ac971eb4524b63063f366 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 13 May 2026 19:11:32 +0000 Subject: [PATCH] =?UTF-8?q?fix(close-form):=20accept=20Fri=2000=E2=80=9303?= =?UTF-8?q?=20ET=20catch-up=20after=20Thu=20close=20cron?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EventBridge can deliver past midnight ET; widen the wall-clock guard so a delayed Thursday 23:59 UTC cron still closes the form. Idempotent when already closed. Adds test for early Friday; past-window skip now starts Fri 04:00 ET. Co-authored-by: Adam Moussa --- functions/close_form/handler.py | 9 +++++++-- tests/test_close_form.py | 22 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/functions/close_form/handler.py b/functions/close_form/handler.py index a5df745..2a509d9 100644 --- a/functions/close_form/handler.py +++ b/functions/close_form/handler.py @@ -13,10 +13,15 @@ EASTERN = ZoneInfo("America/New_York") def lambda_handler(event, context): now_et = datetime.now(EASTERN) - if not (now_et.weekday() == 3 and now_et.hour >= 23): + # EventBridge can fire slightly after midnight ET; accept Thu 23:xx or Fri 00–03 + # ET so a delayed cron still closes the form. Idempotency: already-closed is a no-op. + in_close_window = (now_et.weekday() == 3 and now_et.hour == 23) or ( + now_et.weekday() == 4 and now_et.hour < 4 + ) + if not in_close_window: return { "status": "skipped", - "reason": "outside close window (must be Thursday >= 11 PM ET)", + "reason": "outside close window (must be Thu 23:xx or Fri 00–03 ET)", } week = event.get("week", current_week()) diff --git a/tests/test_close_form.py b/tests/test_close_form.py index e293834..791e64b 100644 --- a/tests/test_close_form.py +++ b/tests/test_close_form.py @@ -41,9 +41,9 @@ class TestCloseFormGuard: assert result["status"] == "skipped" @patch("close_form_handler.datetime") - def test_skipped_on_friday(self, mock_dt): - """Friday 3am ET (wrong-tz EDT cron during EST) -> skipped.""" - mock_dt.now.return_value = _make_datetime(2026, 5, 15, 3) # Friday 3am + def test_skipped_on_friday_after_catchup_window(self, mock_dt): + """Friday 4am ET -> skipped (past Thu 23 / Fri 00–03 catch-up window).""" + mock_dt.now.return_value = _make_datetime(2026, 5, 15, 4) # Friday 4am result = close_form_handler.lambda_handler({}, None) @@ -89,6 +89,22 @@ class TestCloseFormGuard: assert result["status"] == "closed" + @patch("close_form_handler.set_form_status") + @patch("close_form_handler.get_form_status", return_value="open") + @patch("close_form_handler.current_week", return_value="2026-W19") + @patch("close_form_handler._lambda") + @patch("close_form_handler.datetime") + def test_runs_friday_just_after_midnight( + self, mock_dt, mock_lam, mock_week, mock_status, mock_set + ): + """Friday 12:30am ET -> proceeds (delayed EventBridge past Thu 23:59).""" + mock_dt.now.return_value = _make_datetime(2026, 5, 15, 0, 30) + + result = close_form_handler.lambda_handler({}, None) + + assert result["status"] == "closed" + mock_set.assert_called_once() + @patch("close_form_handler.get_form_status", return_value="closed") @patch("close_form_handler.current_week", return_value="2026-W19") @patch("close_form_handler.datetime")