| |
| import sys |
| import os |
| import asyncio |
| import re |
| from unittest.mock import MagicMock |
|
|
| |
| sys.path.append(os.getcwd()) |
|
|
| |
| sys.modules['cv2'] = MagicMock() |
| sys.modules['ocr_strip_engine'] = MagicMock() |
|
|
| import math_intent_detector |
| from smart_solver import SmartSolver |
| from strategy_manager import StrategyManager |
| from orchestrator import seal_pedagogical_output |
|
|
| async def test_grade7_lockdown(): |
| print("🧪 [V4.2] Testing Grade 7 Strategy Lockdown...") |
| |
| |
| problem = "f(x) = 3x + 5. פתור את המשוואה עבור f(x)=0" |
| grade_num = 7 |
| intent = math_intent_detector.detect_intent(problem, grade_num) |
| contract = math_intent_detector.get_intent_contract(intent, grade_num) |
| |
| print(f"Detected Intent: {intent}") |
| |
| if intent != "SIMPLE_LINEAR_SOLVE": |
| print("❌ Failure: Grade 7 problem not classified as SIMPLE_LINEAR_SOLVE") |
| return |
|
|
| |
| print("\n🧪 [V4.2.4] Testing Global Output Sealer...") |
| leaky_response = { |
| "final_answer": "x = -1.66", |
| "teacher_summary": "מצאנו את הנגזרת f'(x) וגילינו שזה קו ישר.", |
| "sections": [{ |
| "steps": [{"content_mixed": "נחשב את הנגזרת f(x) = 3x+5..."}] |
| }] |
| } |
| |
| sealed = seal_pedagogical_output(leaky_response, 7) |
| sealed_str = str(sealed) |
| |
| forbidden_terms = ["נגזרת", "f'(x)", "f(x)"] |
| success = True |
| for term in forbidden_terms: |
| if term in sealed_str: |
| print(f"❌ Failure: Forbidden term '{term}' still present in sealed output!") |
| success = False |
| |
| if success: |
| print("✅ Success: Global Sealer scrubbed all forbidden Grade 7 concepts.") |
|
|
| |
| print("\n🧪 [V4.2.4] Testing StrategyManager Narrative Contract...") |
| mock_llm = MagicMock() |
| captured_prompt = "" |
| |
| async def mock_generate(payload): |
| nonlocal captured_prompt |
| captured_prompt = payload[0] if isinstance(payload, list) else payload |
| mock_resp = MagicMock() |
| mock_resp.text = '{"steps": [{"step_id": 1, "pedagogical_explanation": "הסבר פשוט"}]}' |
| return mock_resp |
|
|
| mock_llm.generate_content_async = mock_generate |
| |
| manager = StrategyManager(mock_llm) |
| await manager.solve_with_strategy( |
| problem, |
| {"function_equations": ["3*x + 5"]}, |
| grade="7", |
| intent=intent, |
| intent_contract=contract |
| ) |
| |
| if "### STRICT CONTRACT ###" in captured_prompt and "Narrative Projector" in captured_prompt: |
| print("✅ Success: StrategyManager injected STRICT CONTRACT into narrative prompt.") |
| else: |
| print("❌ Failure: STRICT CONTRACT missing from narrative prompt.") |
|
|
| def verify_infrastructure(): |
| print("\n🧪 [V4.2] Verifying Infrastructure Lockdown...") |
| import config |
| expected_bucket = "buddy-math-dev.firebasestorage.app" |
| |
| bucket = getattr(config, 'STORAGE_BUCKET', None) |
| if not bucket and hasattr(config, 'DevelopmentConfig'): |
| bucket = getattr(config.DevelopmentConfig, 'STORAGE_BUCKET', None) |
| |
| if bucket == expected_bucket: |
| print(f"✅ Success: Firebase Storage bucket locked to: {expected_bucket}") |
| else: |
| print(f"❌ Failure: Bucket mismatch! Found: {bucket}") |
|
|
| if __name__ == "__main__": |
| asyncio.run(test_grade7_lockdown()) |
| verify_infrastructure() |
| print("\n✨ V4.2.4 Strategy Lockdown Verification COMPLETE!") |
|
|