from goodnews.hero import lead_with_gentle, safe_to_lead


def art(title, desc="", cortisol=0, ragebait=0):
    return {"title": title, "description": desc, "cortisol_score": cortisol, "ragebait_score": ragebait}


def test_calm_story_is_safe_to_lead():
    assert safe_to_lead(art("Rare British plant returns from the brink"))


def test_medical_grief_terms_are_not_safe_to_lead():
    assert not safe_to_lead(art("Nanofiber implant doubles survival in glioblastoma mice", "brain cancer"))
    assert not safe_to_lead(art("New drug for a deadly disease"))
    assert not safe_to_lead(art("A community remembers those who died"))


def test_high_cortisol_or_ragebait_not_safe():
    assert not safe_to_lead(art("Calm-sounding title", cortisol=4))
    assert not safe_to_lead(art("Calm-sounding title", ragebait=3))


def test_substring_safe_words_not_falsely_flagged():
    # "scar" must not trip on "scared"? we don't list scar; ensure clean titles pass
    assert safe_to_lead(art("Volunteers restore a coastal wetland"))


def test_lead_with_gentle_promotes_first_safe_item():
    items = [
        art("Cancer breakthrough in mice", "kill cancer cells"),  # charged — must not lead
        art("Tiny blue octopus found off the Galapagos"),         # calm — should lead
        art("Solar exports hit a record"),
    ]
    out = lead_with_gentle(items)
    assert out[0]["title"].startswith("Tiny blue octopus")
    assert len(out) == 3
    assert any("Cancer" in a["title"] for a in out)  # still present, just not first


def test_lead_with_gentle_keeps_order_when_first_is_already_safe():
    items = [art("A gentle discovery"), art("Cancer news")]
    assert lead_with_gentle(items)[0]["title"] == "A gentle discovery"


def test_lead_with_gentle_unchanged_when_none_safe():
    items = [art("Cancer story"), art("War deaths reported", cortisol=8)]
    out = lead_with_gentle(items)
    assert out[0]["title"] == "Cancer story"  # unchanged; brief still needs a lead
