"""Unit tests for activation threshold configuration.""" from __future__ import annotations import pytest from sqlalchemy.ext.asyncio import AsyncSession from app.exceptions import ValidationError from app.services.admin_service import ( get_activation_config, update_activation_config, ) @pytest.fixture async def session() -> AsyncSession: """DB session compatible with services that commit.""" from tests.conftest import _test_session_factory async with _test_session_factory() as session: yield session class TestActivationConfig: async def test_defaults_when_unset(self, session: AsyncSession): config = await get_activation_config(session) assert config == { "min_momentum_percentile": 80.0, "min_rr": 1.2, "min_confidence": 55.0, "require_high_conviction": False, "exclude_conflicts": False, "exclude_neutral": True, } async def test_update_and_read_back(self, session: AsyncSession): updated = await update_activation_config( session, {"min_momentum_percentile": 70.0, "min_confidence": 60.0} ) assert updated["min_momentum_percentile"] == 70.0 assert updated["min_confidence"] == 60.0 config = await get_activation_config(session) assert config["min_momentum_percentile"] == 70.0 assert config["min_confidence"] == 60.0 async def test_partial_update_keeps_other_value(self, session: AsyncSession): await update_activation_config(session, {"min_confidence": 80.0}) config = await get_activation_config(session) assert config["min_rr"] == 1.2 # default untouched assert config["min_confidence"] == 80.0 async def test_rejects_out_of_range_momentum_percentile(self, session: AsyncSession): with pytest.raises(ValidationError): await update_activation_config(session, {"min_momentum_percentile": 150.0}) async def test_conviction_flags_round_trip(self, session: AsyncSession): await update_activation_config( session, {"require_high_conviction": True, "exclude_conflicts": True}, ) config = await get_activation_config(session) assert config["require_high_conviction"] is True assert config["exclude_conflicts"] is True async def test_exclude_neutral_round_trip(self, session: AsyncSession): # On by default; can be turned off. assert (await get_activation_config(session))["exclude_neutral"] is True await update_activation_config(session, {"exclude_neutral": False}) assert (await get_activation_config(session))["exclude_neutral"] is False async def test_rejects_negative_rr(self, session: AsyncSession): with pytest.raises(ValidationError): await update_activation_config(session, {"min_rr": -1.0}) async def test_rejects_out_of_range_confidence(self, session: AsyncSession): with pytest.raises(ValidationError): await update_activation_config(session, {"min_confidence": 120.0})