diff --git a/backend/app/services/orchestrator/steps.py b/backend/app/services/orchestrator/steps.py index b936c60..75728a9 100644 --- a/backend/app/services/orchestrator/steps.py +++ b/backend/app/services/orchestrator/steps.py @@ -145,7 +145,7 @@ def step_email(run: "WeeklyRun", db: "Session") -> None: email_html = ( f"
Hi {member.name}, please vote on this week's meals by Fri 17:00 PT:
" + f"Hi {html.escape(member.name)}, please vote on this week's meals by Fri 17:00 PT:
" f"Silence = approved. Any denial removes that meal.
" ) diff --git a/backend/tests/test_orchestrator.py b/backend/tests/test_orchestrator.py index 08fff3f..badc139 100644 --- a/backend/tests/test_orchestrator.py +++ b/backend/tests/test_orchestrator.py @@ -417,6 +417,36 @@ def test_step_reminder_skips_voter( assert weekly_run_emailed.reminded_at is not None +def test_step_reminder_no_sends_when_all_voted( + db, weekly_run_emailed, meal_plan, pending_item, member, monkeypatch +): + from app.models import MealPlanVote + # Member has voted on the only pending item + vote = MealPlanVote( + meal_plan_item_id=pending_item.id, + family_member_id=member.id, + vote=True, + ) + db.add(vote) + db.flush() + + sent = [] + + class FakeBackend: + def send(self, **kwargs): + sent.append(kwargs) + + monkeypatch.setattr( + "app.services.orchestrator.steps.get_email_backend", + lambda: FakeBackend(), + ) + from app.services.orchestrator.steps import step_reminder + step_reminder(weekly_run_emailed, db) + # All items voted on — no emails sent, but reminded_at still stamped + assert len(sent) == 0 + assert weekly_run_emailed.reminded_at is not None + + # --------------------------------------------------------------------------- # step_deadline tests # ---------------------------------------------------------------------------