"""Tests for vote service engine functions: threshold details, session logic, nuanced evaluation, and simulation. All tests are pure unit tests that exercise the engine functions directly without any database dependency. Real-world reference case: Vote Engagement Forgeron v2.0.0 (Feb 2026) wot_size=7224, votes_for=97, votes_against=23, total=120 params M=50, B=0.1, G=0.2 => threshold=94 => adopted (97 >= 94) """ from __future__ import annotations import math import pytest from app.engine.nuanced_vote import evaluate_nuanced from app.engine.smith_threshold import smith_threshold from app.engine.techcomm_threshold import techcomm_threshold from app.engine.threshold import wot_threshold # --------------------------------------------------------------------------- # Threshold details computation: real Forgeron case (97/23/7224) # --------------------------------------------------------------------------- class TestThresholdDetailsForgeron: """Simulate the threshold details computation that the service would return for the real Engagement Forgeron v2.0.0 vote.""" WOT_SIZE = 7224 VOTES_FOR = 97 VOTES_AGAINST = 23 TOTAL = 120 SMITH_SIZE = 20 SMITH_EXPONENT = 0.1 TECHCOMM_SIZE = 5 TECHCOMM_EXPONENT = 0.1 def _compute_details(self) -> dict: """Reproduce the threshold details logic from vote_service.get_threshold_details.""" wot_thresh = wot_threshold( wot_size=self.WOT_SIZE, total_votes=self.TOTAL, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, constant_base=0.0, ) wot_passed = self.VOTES_FOR >= wot_thresh smith_thresh = smith_threshold(self.SMITH_SIZE, self.SMITH_EXPONENT) # Assume all smith members voted for smith_votes_for = 5 smith_passed = smith_votes_for >= smith_thresh techcomm_thresh = techcomm_threshold(self.TECHCOMM_SIZE, self.TECHCOMM_EXPONENT) # Assume 2 techcomm members voted for techcomm_votes_for = 2 techcomm_passed = techcomm_votes_for >= techcomm_thresh overall_passed = wot_passed and smith_passed and techcomm_passed participation_rate = self.TOTAL / self.WOT_SIZE return { "wot_threshold": wot_thresh, "smith_threshold": smith_thresh, "techcomm_threshold": techcomm_thresh, "votes_for": self.VOTES_FOR, "votes_against": self.VOTES_AGAINST, "votes_total": self.TOTAL, "wot_passed": wot_passed, "smith_passed": smith_passed, "techcomm_passed": techcomm_passed, "overall_passed": overall_passed, "participation_rate": round(participation_rate, 6), "formula_params": { "M": 50, "B": 0.1, "G": 0.2, "C": 0.0, "S": self.SMITH_EXPONENT, "T": self.TECHCOMM_EXPONENT, }, } def test_wot_threshold_value(self): """WoT threshold for Forgeron vote should be in the expected range.""" details = self._compute_details() assert 80 <= details["wot_threshold"] <= 120 # 97 votes_for must pass assert details["wot_passed"] is True def test_smith_threshold_value(self): """Smith threshold: ceil(20^0.1) = ceil(1.35) = 2.""" details = self._compute_details() assert details["smith_threshold"] == 2 assert details["smith_passed"] is True def test_techcomm_threshold_value(self): """TechComm threshold: ceil(5^0.1) = ceil(1.175) = 2.""" details = self._compute_details() assert details["techcomm_threshold"] == 2 assert details["techcomm_passed"] is True def test_overall_pass(self): """All three criteria pass => overall adopted.""" details = self._compute_details() assert details["overall_passed"] is True def test_participation_rate(self): """Participation rate for 120/7224 ~ 1.66%.""" details = self._compute_details() expected = round(120 / 7224, 6) assert details["participation_rate"] == expected assert details["participation_rate"] < 0.02 # less than 2% def test_formula_params_present(self): """All formula params must be present and correct.""" details = self._compute_details() params = details["formula_params"] assert params["M"] == 50 assert params["B"] == 0.1 assert params["G"] == 0.2 assert params["C"] == 0.0 assert params["S"] == 0.1 assert params["T"] == 0.1 # --------------------------------------------------------------------------- # Close session behavior (engine-level logic) # --------------------------------------------------------------------------- class TestCloseSessionLogic: """Test the logic that would execute when a session is closed: computing the final tally and determining adopted/rejected.""" def test_binary_vote_adopted(self): """97 for / 23 against out of 7224 WoT => adopted.""" threshold = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) adopted = 97 >= threshold assert adopted is True result = "adopted" if adopted else "rejected" assert result == "adopted" def test_binary_vote_rejected(self): """50 for / 70 against out of 7224 WoT => rejected.""" threshold = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) adopted = 50 >= threshold assert adopted is False result = "adopted" if adopted else "rejected" assert result == "rejected" def test_close_with_zero_votes(self): """Session with 0 votes => threshold is ~0 (B^W), effectively rejected because 0 votes_for cannot meet even a tiny threshold.""" threshold = wot_threshold( wot_size=7224, total_votes=0, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # B^W = 0.1^7224 -> effectively 0, ceil(0) = 0 # But with 0 votes_for, 0 >= 0 is True # This is a degenerate case; in practice sessions with 0 votes # would be marked invalid assert threshold == 0 or threshold == math.ceil(0.1 ** 7224) def test_close_high_participation(self): """3000/7224 participating, 2500 for / 500 against => should pass. At ~41.5% participation with G=0.2, the inertia factor is low, so a strong supermajority should pass. """ threshold = wot_threshold( wot_size=7224, total_votes=3000, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # At ~41.5% participation, threshold is lower than near-unanimity # but still above simple majority (1500) assert threshold > 1500, f"Threshold {threshold} should be above simple majority" assert threshold < 3000, f"Threshold {threshold} should be below total votes" adopted = 2500 >= threshold assert adopted is True def test_close_barely_fails(self): """Use exact threshold to verify borderline rejection.""" threshold = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # votes_for = threshold - 1 => should fail barely_fail = (threshold - 1) >= threshold assert barely_fail is False def test_close_smith_criterion_blocks(self): """Even if WoT passes, failing Smith criterion blocks adoption.""" threshold = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) wot_pass = 97 >= threshold smith_required = smith_threshold(20, 0.1) # ceil(20^0.1) = 2 smith_ok = 1 >= smith_required # Only 1 smith voted -> fails adopted = wot_pass and smith_ok assert wot_pass is True assert smith_ok is False assert adopted is False # --------------------------------------------------------------------------- # Nuanced vote result evaluation # --------------------------------------------------------------------------- class TestNuancedVoteResult: """Test nuanced vote evaluation with per-level breakdown, as would be returned by compute_result for nuanced votes.""" def test_nuanced_adopted_with_breakdown(self): """Standard nuanced vote that passes threshold and min_participants.""" votes = [5] * 30 + [4] * 20 + [3] * 15 + [2] * 5 + [1] * 3 + [0] * 2 result = evaluate_nuanced(votes, threshold_pct=80, min_participants=59) # Total = 75, positive = 30+20+15 = 65 assert result["total"] == 75 assert result["positive_count"] == 65 assert result["positive_pct"] == pytest.approx(86.67, abs=0.1) assert result["adopted"] is True # Verify per-level breakdown assert result["per_level_counts"][5] == 30 assert result["per_level_counts"][4] == 20 assert result["per_level_counts"][3] == 15 assert result["per_level_counts"][2] == 5 assert result["per_level_counts"][1] == 3 assert result["per_level_counts"][0] == 2 def test_nuanced_rejected_threshold_not_met(self): """Nuanced vote where positive percentage is below threshold.""" votes = [5] * 10 + [4] * 10 + [3] * 10 + [2] * 15 + [1] * 15 + [0] * 10 result = evaluate_nuanced(votes, threshold_pct=80, min_participants=59) # Total = 70, positive = 10+10+10 = 30 assert result["total"] == 70 assert result["positive_count"] == 30 assert result["positive_pct"] == pytest.approx(42.86, abs=0.1) assert result["threshold_met"] is False assert result["min_participants_met"] is True assert result["adopted"] is False def test_nuanced_all_neutre(self): """All voters at level 3 (NEUTRE) still counts as positive.""" votes = [3] * 60 result = evaluate_nuanced(votes, threshold_pct=80, min_participants=59) assert result["total"] == 60 assert result["positive_count"] == 60 assert result["positive_pct"] == 100.0 assert result["adopted"] is True def test_nuanced_mixed_heavy_negative(self): """Majority at levels 0-2 => rejected.""" votes = [0] * 20 + [1] * 20 + [2] * 15 + [3] * 2 + [4] * 1 + [5] * 1 result = evaluate_nuanced(votes, threshold_pct=80, min_participants=59) # Total = 59, positive = 2+1+1 = 4 assert result["total"] == 59 assert result["positive_count"] == 4 assert result["positive_pct"] < 10 assert result["adopted"] is False def test_nuanced_breakdown_dict_structure(self): """Verify the breakdown structure matches what the service builds.""" votes = [5] * 20 + [4] * 20 + [3] * 19 + [2] * 5 + [1] * 3 + [0] * 2 evaluation = evaluate_nuanced(votes, threshold_pct=80, min_participants=59) # Simulate the nuanced_breakdown dict the service builds nuanced_breakdown = { "per_level_counts": evaluation["per_level_counts"], "positive_count": evaluation["positive_count"], "positive_pct": evaluation["positive_pct"], "threshold_met": evaluation["threshold_met"], "min_participants_met": evaluation["min_participants_met"], "threshold_pct": 80, "min_participants": 59, } assert "per_level_counts" in nuanced_breakdown assert nuanced_breakdown["threshold_pct"] == 80 assert nuanced_breakdown["min_participants"] == 59 assert nuanced_breakdown["positive_count"] == 59 assert nuanced_breakdown["threshold_met"] is True # --------------------------------------------------------------------------- # Simulation endpoint logic (pure engine functions) # --------------------------------------------------------------------------- class TestSimulationLogic: """Test the formula simulation that the /simulate endpoint performs, exercising all three threshold engine functions together.""" def test_simulation_forgeron_case(self): """Simulate the Forgeron vote: wot=7224, total=120, M50 B.1 G.2.""" wot_thresh = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # Derived values (matching the simulate endpoint logic) w = 7224 t = 120 m = 0.5 g = 0.2 participation_rate = t / w turnout_ratio = min(t / w, 1.0) inertia_factor = 1.0 - turnout_ratio ** g required_ratio = m + (1.0 - m) * inertia_factor assert 80 <= wot_thresh <= 120 assert participation_rate == pytest.approx(0.016611, abs=0.001) assert 0 < inertia_factor < 1 assert required_ratio > m # Inertia pushes above simple majority def test_simulation_full_participation(self): """At 100% participation, threshold approaches simple majority.""" wot_size = 100 total = 100 wot_thresh = wot_threshold( wot_size=wot_size, total_votes=total, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # At full participation, turnout_ratio = 1.0 # inertia_factor = 1.0 - 1.0^0.2 = 0 # required_ratio = 0.5 + 0.5*0 = 0.5 # threshold = 0 + 0.1^100 + 0.5 * 100 = ~50 assert wot_thresh == math.ceil(0.1 ** 100 + 0.5 * 100) assert wot_thresh == 50 def test_simulation_with_smith_and_techcomm(self): """Simulate with all three criteria.""" wot_thresh = wot_threshold( wot_size=7224, total_votes=120, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) smith_thresh = smith_threshold(smith_wot_size=20, exponent=0.1) techcomm_thresh = techcomm_threshold(cotec_size=5, exponent=0.1) assert wot_thresh > 0 assert smith_thresh == 2 # ceil(20^0.1) = ceil(1.35) = 2 assert techcomm_thresh == 2 # ceil(5^0.1) = ceil(1.175) = 2 def test_simulation_varying_majority(self): """Higher majority_pct increases the threshold at full participation.""" thresh_50 = wot_threshold(wot_size=100, total_votes=100, majority_pct=50) thresh_66 = wot_threshold(wot_size=100, total_votes=100, majority_pct=66) thresh_80 = wot_threshold(wot_size=100, total_votes=100, majority_pct=80) assert thresh_50 < thresh_66 < thresh_80 def test_simulation_varying_gradient(self): """Higher gradient exponent means more inertia at partial participation. With T/W < 1, a higher G makes (T/W)^G smaller, so inertia_factor = 1 - (T/W)^G becomes larger, raising the threshold. At 50% participation: (0.5)^0.2 ~ 0.87, (0.5)^1.0 = 0.5. """ thresh_g02 = wot_threshold( wot_size=200, total_votes=100, majority_pct=50, gradient_exponent=0.2, ) thresh_g10 = wot_threshold( wot_size=200, total_votes=100, majority_pct=50, gradient_exponent=1.0, ) # Higher G = more inertia at partial participation = higher threshold assert thresh_g10 > thresh_g02 def test_simulation_zero_votes(self): """Zero votes produces a minimal threshold.""" thresh = wot_threshold( wot_size=7224, total_votes=0, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # B^W = 0.1^7224 ~ 0, ceil(0) = 0 assert thresh == 0 def test_simulation_small_wot(self): """Small WoT size (e.g. 5 members).""" thresh = wot_threshold( wot_size=5, total_votes=3, majority_pct=50, base_exponent=0.1, gradient_exponent=0.2, ) # With 3/5 participation, should require more than simple majority of 3 assert thresh >= 2 assert thresh <= 3 def test_simulation_result_structure(self): """Verify the simulation produces all expected values for the API response.""" w = 7224 t = 120 m_pct = 50 m = m_pct / 100.0 b = 0.1 g = 0.2 c = 0.0 wot_thresh = wot_threshold( wot_size=w, total_votes=t, majority_pct=m_pct, base_exponent=b, gradient_exponent=g, constant_base=c, ) smith_thresh = smith_threshold(smith_wot_size=20, exponent=0.1) techcomm_thresh = techcomm_threshold(cotec_size=5, exponent=0.1) participation_rate = t / w turnout_ratio = min(t / w, 1.0) inertia_factor = 1.0 - turnout_ratio ** g required_ratio = m + (1.0 - m) * inertia_factor # Build the simulation result dict (matching FormulaSimulationResult schema) result = { "wot_threshold": wot_thresh, "smith_threshold": smith_thresh, "techcomm_threshold": techcomm_thresh, "participation_rate": round(participation_rate, 6), "required_ratio": round(required_ratio, 6), "inertia_factor": round(inertia_factor, 6), } assert isinstance(result["wot_threshold"], int) assert isinstance(result["smith_threshold"], int) assert isinstance(result["techcomm_threshold"], int) assert 0 < result["participation_rate"] < 1 assert 0 < result["required_ratio"] <= 1 assert 0 < result["inertia_factor"] < 1