BuddyMath / tests /test_adaptive_failure.py
dotandru's picture
Fix: Clean production deployment with sse-starlette
9d29c62
Raw
History Blame Contribute Delete
3.35 kB
import asyncio
import unittest
from unittest.mock import MagicMock, AsyncMock
from orchestrator import BuddyOrchestrator
from config import CONFIDENCE_THRESHOLD_HIGH, CONFIDENCE_THRESHOLD_MEDIUM
class TestAdaptiveFailureMode(unittest.IsolatedAsyncioTestCase):
def setUp(self):
self.orchestrator = BuddyOrchestrator()
# Mock strategy manager
self.orchestrator.strategy_manager = MagicMock()
self.orchestrator.strategy_manager.solve_with_strategy = AsyncMock()
# Mock internal methods to isolate orchestration logic
self.orchestrator._classify_question = AsyncMock(return_value={"complexity": "COMPLEX", "num_parts": 1})
self.orchestrator._extract_key_data = AsyncMock(return_value={})
self.orchestrator.smart_solve = AsyncMock(return_value={"sections": []})
async def test_high_confidence_flow(self):
print(f"\n🟢 Testing High Confidence (> {CONFIDENCE_THRESHOLD_HIGH}):")
self.orchestrator._last_ocr_confidence = CONFIDENCE_THRESHOLD_HIGH + 0.05
await self.orchestrator.solve_problem("x + 1 = 2 and we need to solve it step by step for the student", "×™'", "TestStudent")
# Verify smart_solve was called with ambiguity_warning=False
args, kwargs = self.orchestrator.smart_solve.call_args
self.assertFalse(kwargs['ambiguity_warning'])
print(f" ✅ High Confidence {self.orchestrator._last_ocr_confidence} - Passed (No warning)")
async def test_medium_confidence_soft_recovery(self):
print(f"\n🟡 Testing Medium Confidence ({CONFIDENCE_THRESHOLD_MEDIUM} - {CONFIDENCE_THRESHOLD_HIGH}):")
# Ensure we are in the medium range
self.orchestrator._last_ocr_confidence = (CONFIDENCE_THRESHOLD_HIGH + CONFIDENCE_THRESHOLD_MEDIUM) / 2
# Force escalation to smart_solve by mocking quick_solve failure
self.orchestrator._quick_solve = AsyncMock(return_value=None)
await self.orchestrator.solve_problem("x + 1 = 2 and we need to solve it step by step for the student", "×™'", "TestStudent")
# Verify smart_solve was called with ambiguity_warning=True
args, kwargs = self.orchestrator.smart_solve.call_args
self.assertTrue(kwargs['ambiguity_warning'])
print(f" ✅ Medium Confidence {self.orchestrator._last_ocr_confidence} - Passed (Soft Recovery triggered)")
async def test_low_confidence_hard_stop(self):
# We need to make sure we are BELOW CONFIDENCE_THRESHOLD_MEDIUM
# In DEV it is 0.01, so let's use 0.005
low_val = min(0.005, CONFIDENCE_THRESHOLD_MEDIUM - 0.001)
print(f"\n🔴 Testing Low Confidence (< {CONFIDENCE_THRESHOLD_MEDIUM}):")
self.orchestrator._last_ocr_confidence = low_val
result = await self.orchestrator.solve_problem("x + 1 = 2 and we need to solve it step by step for the student", "×™'", "TestStudent")
# V7.3: Check logic_error and error_type instead of 'status'
self.assertTrue(result.get("logic_error"))
self.assertEqual(result.get("error_type"), "RECAPTURE_REQUIRED")
self.orchestrator.smart_solve.assert_not_called()
print(f" ✅ Low Confidence {self.orchestrator._last_ocr_confidence} - Passed (Hard Stop triggered)")
if __name__ == "__main__":
unittest.main()