"""Tests for meal periods, responses, and changed-mind logic.""" from datetime import date, datetime import pytest from models import ( init_db, get_db, ensure_meal_periods, get_dashboard_data, upsert_response, get_user_by_username, ) class TestMealPeriods: def test_ensure_creates_periods(self, app): with app.app_context(): periods = ensure_meal_periods(date(2025, 6, 15)) assert len(periods) == 2 types = {p["meal_type"] for p in periods} assert types == {"lunch", "dinner"} for p in periods: assert p["date"] == "2025-06-15" def test_ensure_is_idempotent(self, app): with app.app_context(): p1 = ensure_meal_periods(date(2025, 6, 15)) p2 = ensure_meal_periods(date(2025, 6, 15)) assert p1[0]["id"] == p2[0]["id"] assert p1[1]["id"] == p2[1]["id"] class TestResponses: def test_first_response_no_changed_at(self, app): with app.app_context(): from models import create_user user = create_user("test", "hash", is_admin=False) periods = ensure_meal_periods(date.today()) lunch = periods[0] resp = upsert_response(user["id"], lunch["id"], "yes") assert resp["status"] == "yes" assert resp["changed_at"] is None def test_flip_yes_to_no_sets_changed_at(self, app): with app.app_context(): from models import create_user user = create_user("flipper", "hash", is_admin=False) periods = ensure_meal_periods(date.today()) lunch = periods[0] upsert_response(user["id"], lunch["id"], "yes") resp = upsert_response(user["id"], lunch["id"], "no") assert resp["status"] == "no" assert resp["changed_at"] is not None def test_flip_twice_updates_changed_at(self, app): with app.app_context(): from models import create_user user = create_user("flipper2", "hash", is_admin=False) periods = ensure_meal_periods(date.today()) lunch = periods[0] upsert_response(user["id"], lunch["id"], "yes") r1 = upsert_response(user["id"], lunch["id"], "no") r2 = upsert_response(user["id"], lunch["id"], "yes") # changed_at should reflect the latest flip assert r2["changed_at"] is not None # The second flip should have a different timestamp (or at least not earlier) assert r2["changed_at"] >= r1["changed_at"] def test_same_status_no_change(self, app): with app.app_context(): from models import create_user user = create_user("same", "hash", is_admin=False) periods = ensure_meal_periods(date.today()) lunch = periods[0] r1 = upsert_response(user["id"], lunch["id"], "yes") r2 = upsert_response(user["id"], lunch["id"], "yes") assert r1["status"] == r2["status"] assert r1["changed_at"] == r2["changed_at"] class TestDashboardData: def test_dashboard_includes_all_users(self, app): with app.app_context(): from models import create_user create_user("u1", "h1", is_admin=True) create_user("u2", "h2", is_admin=False) data = get_dashboard_data(date.today()) assert len(data["users"]) == 2 assert data["users"][0]["username"] == "u1" assert data["users"][1]["username"] == "u2" def test_dashboard_shows_responses(self, app): with app.app_context(): from models import create_user user = create_user("responder", "h", is_admin=True) periods = ensure_meal_periods(date.today()) lunch = next(p for p in periods if p["meal_type"] == "lunch") upsert_response(user["id"], lunch["id"], "yes") data = get_dashboard_data(date.today()) resp = data["users"][0]["responses"]["lunch"] assert resp["status"] == "yes" def test_dashboard_defaults_not_answered(self, app): with app.app_context(): from models import create_user create_user("silent", "h", is_admin=False) data = get_dashboard_data(date.today()) resp = data["users"][0]["responses"]["dinner"] assert resp["status"] == "not_answered" assert resp["changed_at"] is None