"""Synthetic exhaustive scoring and calendar/diary boundary checks.""" from datetime import date, timedelta from itertools import product import pytest from app.core.intake_runtime import diary_flags, due_scales, load_runtime, month_before from app.core.questionnaire import IntakePolicy, alcohol_expansion, load_policy, score_alcohol from app.core.scales import score def test_release_is_closed(): assert not load_runtime().released assert load_policy().approval is None def test_all_tsq_patterns(): for answers in product((0, 1), repeat=10): result = score("tsq", {f"tsq_{i + 1}": v for i, v in enumerate(answers)}) assert result.complete and result.total == sum(answers) assert (result.severity_code == "positive") == (sum(answers) >= 6) @pytest.mark.parametrize( "day,expected", [ (date(2024, 3, 31), date(2024, 2, 29)), (date(2025, 3, 31), date(2025, 2, 28)), (date(2026, 1, 1), date(2025, 12, 1)), ], ) def test_calendar_month(day, expected): assert month_before(day) == expected def test_medication_schedule_overlapping_and_delayed_completion(): start = date(2026, 1, 1) last = {} for day in (6, 7, 13, 14, 27, 28, 55, 56): due = due_scales( today=start + timedelta(days=day), enrolled=start, last=last, route="self_help", medication_changed=start ) assert ("phq9" in due) == (day in (7, 14, 28, 56)) if "phq9" in due: last.update(phq9=start + timedelta(days=day), pcl5=start + timedelta(days=day)) # A missed tick yields one form, not each historical milestone. assert ( due_scales( today=start + timedelta(days=80), enrolled=start, last={}, route="self_help", medication_changed=start ).count("phq9") == 1 ) assert "phq9" in due_scales( today=start + timedelta(days=7), enrolled=start, last={}, route="specialist", after_crisis=start ) def test_diary_consecutive_days_and_baseline_do_not_include_bad_window(): today = date(2026, 10, 3) history = {today - timedelta(days=i): {"mood": 8} for i in range(3, 10)} for i in range(3): history[today - timedelta(days=i)] = {"mood": 5, "sleep_hours": 3.9, "medication": "none"} assert set(diary_flags(history, today)) == {"phq9_due_mood", "sleep_review", "medication_contact"} history[today - timedelta(days=1)] = {} assert diary_flags(history, today) == () history[today]["death_thoughts"] = 1 assert diary_flags(history, today) == ("suicide_assessment_now",) def test_sleep_alternation_counts_but_threshold_is_strict(): today = date(2026, 10, 3) h = { today: {"nightmares": 3}, today - timedelta(days=1): {"sleep_hours": 3.5}, today - timedelta(days=2): {"sleep_hours": 3.5}, } assert "sleep_review" in diary_flags(h, today) h[today - timedelta(days=1)]["sleep_hours"] = 4 assert "sleep_review" not in diary_flags(h, today) def test_total_threshold_and_zone_are_separate_decisions(): data = load_policy().model_dump() data.update(cssrs_positive_policy="graded", rus_audit_s_expand_at=1) data["approval"] = dict( reviewer="Synthetic fixture", decision_reference="test", approved_at="2026-10-03T00:00:00Z", policy_version=data["version"], ) policy = IntakePolicy.model_validate(data) r = score_alcohol({"rus_audit_3": 1, "rus_audit_9": 0, "rus_audit_10": 0}, short=True, sex="m") assert r.zone == 1 and alcohol_expansion(r, policy) with pytest.raises(ValueError): IntakePolicy.model_validate({**data, "rus_audit_s_expand_from_zone": 2}) def test_module_rotation_never_drops_suicide_question(): from app.core.intake_questions import diary_questions first = { q.id for q in diary_questions(["veteran", "depression"], suicide_monitoring=False, weekday=0, day_index=100) } second = { q.id for q in diary_questions(["veteran", "depression"], suicide_monitoring=False, weekday=1, day_index=101) } assert "death_thoughts" in first & second assert "nightmares" in first and "nightmares" not in second assert "burden" in first and "burden" not in second