from goodnews.scoring import score_article def test_constructive_story_is_accepted(): s = score_article("Community volunteers restore creek habitat", "A hopeful recovery effort", 3) assert s["accepted"] == 1 assert s["constructive_score"] >= 5 assert s["reason_code"] == "heuristic_constructive_candidate" def test_neutral_story_needs_review(): s = score_article("The weather report for tomorrow", None, 3) assert s["accepted"] == 0 assert s["reason_code"] == "heuristic_needs_review" def test_cortisol_heavy_is_rejected(): s = score_article("War and death as murder and attack escalate", None, 3) assert s["accepted"] == 0 assert s["cortisol_score"] > 5 assert s["reason_code"] == "heuristic_reject_cortisol_heavy" def test_ragebait_is_rejected_before_cortisol(): s = score_article("Senator slams rival and sparks backlash", None, 3) assert s["accepted"] == 0 assert s["ragebait_score"] > 3 assert s["reason_code"] == "heuristic_reject_ragebait_language" def test_pr_risk_from_source_and_terms_rejects(): s = score_article("Startup announces funding round and unveils brand", None, 6) assert s["pr_risk_score"] > 7 assert s["accepted"] == 0 def test_all_scores_within_bounds(): s = score_article("breakthrough cure restores hope " * 10, "progress " * 20, 3) for key in ( "constructive_score", "cortisol_score", "ragebait_score", "agency_score", "human_benefit_score", "novelty_score", "pr_risk_score", ): assert 0 <= s[key] <= 10, key