meal-order-manager/tests/test_close_form.py
Adam Moussa 5db992b0be Fix close-form weekday guard and SSM auth fail-open
- Close form guard: check weekday == 3 (Thursday), not 4 (Friday) — the
  crons fire at Thursday 11:59 PM ET, when weekday() is 3
- SSM fail-closed: separate _google_auth_configured() (checks env var) from
  _get_google_client_id() (fetches value). If auth is configured but the SSM
  fetch fails, return 503 instead of silently falling back to manual auth
- Update close_form tests to use Thursday dates
- Add test_ssm_failure_fails_closed
2026-05-13 13:50:48 -04:00

101 lines
3.6 KiB
Python

"""Unit tests for functions/close_form/handler.py — wall-clock guard."""
import os
import sys
from datetime import datetime
from unittest.mock import patch
from zoneinfo import ZoneInfo
os.environ.setdefault(
"AGGREGATE_FUNCTION_ARN",
"arn:aws:lambda:us-east-1:000000000000:function:test-aggregate",
)
import importlib.util
_handler_path = os.path.join(
os.path.dirname(__file__), os.pardir, "functions", "close_form", "handler.py"
)
_spec = importlib.util.spec_from_file_location(
"close_form_handler", os.path.abspath(_handler_path)
)
close_form_handler = importlib.util.module_from_spec(_spec)
sys.modules["close_form_handler"] = close_form_handler
_spec.loader.exec_module(close_form_handler)
ET = ZoneInfo("America/New_York")
def _make_datetime(year, month, day, hour, minute=0):
return datetime(year, month, day, hour, minute, tzinfo=ET)
class TestCloseFormGuard:
@patch("close_form_handler.datetime")
def test_skipped_on_wednesday(self, mock_dt):
"""Wednesday 11pm ET -> skipped (not Thursday)."""
mock_dt.now.return_value = _make_datetime(2026, 5, 13, 23) # Wednesday
result = close_form_handler.lambda_handler({}, None)
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
result = close_form_handler.lambda_handler({}, None)
assert result["status"] == "skipped"
@patch("close_form_handler.datetime")
def test_skipped_thursday_before_11pm(self, mock_dt):
"""Thursday 10pm ET -> skipped (too early)."""
mock_dt.now.return_value = _make_datetime(2026, 5, 14, 22) # Thursday 10pm
result = close_form_handler.lambda_handler({}, None)
assert result["status"] == "skipped"
@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_thursday_at_11pm(
self, mock_dt, mock_lam, mock_week, mock_status, mock_set
):
"""Thursday 11pm ET -> proceeds to close."""
mock_dt.now.return_value = _make_datetime(2026, 5, 14, 23) # Thursday 11pm
result = close_form_handler.lambda_handler({}, None)
assert result["status"] == "closed"
mock_set.assert_called_once()
@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_thursday_at_1159pm(
self, mock_dt, mock_lam, mock_week, mock_status, mock_set
):
"""Thursday 11:59pm ET -> proceeds to close."""
mock_dt.now.return_value = _make_datetime(2026, 5, 14, 23, 59)
result = close_form_handler.lambda_handler({}, None)
assert result["status"] == "closed"
@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")
def test_already_closed(self, mock_dt, mock_week, mock_status):
"""Thursday 11pm but already closed -> returns already_closed."""
mock_dt.now.return_value = _make_datetime(2026, 5, 14, 23)
result = close_form_handler.lambda_handler({}, None)
assert result["status"] == "already_closed"