Durability pass: tests, clearer diversity/classify behavior, Calm Filters foundation
- Add pytest suite (34 tests) covering scoring thresholds, dedup clustering + representative selection + time window, brief source/category diversity, avoid-term phrase matching, and text canonicalization/truncation. - Rewrite _select_diverse with an explicit, tested contract (best-first, one per source, backfill, then inject a second category by evicting the lowest-ranked pick). - classify_articles now returns attempted/succeeded/skipped (ClassifyReport) so silent model failures are visible in both the cycle and classify output. - Fix clean_text truncation to stay within max_len (ellipsis no longer overshoots). - New filters.py: canonical FilterPrefs shape (include/mute topics+flavors, avoid_terms, pauses) and pure word/phrase-boundary matching engine seeding Calm Filters. Not yet wired into the API. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
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
|
||||
Reference in New Issue
Block a user