"""Unit tests for the activation qualification predicate.""" from __future__ import annotations from types import SimpleNamespace from app.services.qualification import best_target_probability, setup_qualifies FULL_GATE = { "min_rr": 2.0, "min_confidence": 70.0, "min_target_probability": 60.0, "require_high_conviction": True, "exclude_conflicts": True, } def _setup(**kwargs): base = dict( rr_ratio=3.0, confidence_score=80.0, recommended_action="LONG_HIGH", risk_level="Low", targets=[{"probability": 65.0}], ) base.update(kwargs) return SimpleNamespace(**base) class TestSetupQualifies: def test_clean_high_conviction_setup_passes(self): assert setup_qualifies(_setup(), FULL_GATE) is True def test_low_rr_fails(self): assert setup_qualifies(_setup(rr_ratio=1.5), FULL_GATE) is False def test_low_confidence_fails(self): assert setup_qualifies(_setup(confidence_score=60.0), FULL_GATE) is False def test_moderate_action_fails_when_high_conviction_required(self): assert setup_qualifies(_setup(recommended_action="LONG_MODERATE"), FULL_GATE) is False def test_neutral_action_fails(self): assert setup_qualifies(_setup(recommended_action="NEUTRAL"), FULL_GATE) is False def test_short_high_passes(self): assert setup_qualifies(_setup(recommended_action="SHORT_HIGH"), FULL_GATE) is True def test_non_low_risk_fails_when_excluding_conflicts(self): assert setup_qualifies(_setup(risk_level="Medium"), FULL_GATE) is False assert setup_qualifies(_setup(risk_level="High"), FULL_GATE) is False def test_low_target_probability_fails(self): assert setup_qualifies(_setup(targets=[{"probability": 40.0}]), FULL_GATE) is False def test_no_targets_fails_when_probability_required(self): assert setup_qualifies(_setup(targets=[]), FULL_GATE) is False def test_conviction_filters_can_be_disabled(self): relaxed = { "min_rr": 2.0, "min_confidence": 70.0, "min_target_probability": 0.0, "require_high_conviction": False, "exclude_conflicts": False, } # Moderate action, medium risk, no targets — still passes on rr+confidence alone s = _setup(recommended_action="LONG_MODERATE", risk_level="Medium", targets=[]) assert setup_qualifies(s, relaxed) is True def test_missing_confidence_treated_as_zero(self): assert setup_qualifies(_setup(confidence_score=None), FULL_GATE) is False class TestBestTargetProbability: def test_returns_max(self): s = _setup(targets=[{"probability": 40.0}, {"probability": 72.0}, {"probability": 55.0}]) assert best_target_probability(s) == 72.0 def test_empty_is_zero(self): assert best_target_probability(_setup(targets=[])) == 0.0