import sys, os sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) import pytest from unittest.mock import AsyncMock, patch from app.curator.retrospective import build_retrospective, _detect_bias def test_detect_bias_persistent_low(): reviews = [ {"pattern_delta": "저번호 편향 +1.2 / 합계 -18"}, {"pattern_delta": "저번호 편향 +0.8"}, {"pattern_delta": "저번호 편향 +1.0 / 홀짝 +0.5"}, ] assert "저번호" in _detect_bias(reviews) def test_detect_bias_no_persistence(): reviews = [ {"pattern_delta": "저번호 편향 +1.2"}, {"pattern_delta": "고번호 편향 +0.8"}, ] assert _detect_bias(reviews) == "" @pytest.mark.asyncio async def test_build_retrospective_with_data(): with patch("app.service_proxy.lotto_review_by_draw", new=AsyncMock(return_value={ "draw_no": 1153, "curator_avg_match": 1.8, "curator_best_tier": "안정", "user_avg_match": 2.0, "user_5plus_prizes": 1, "pattern_delta": "저번호 편향 +1.2", })), patch("app.service_proxy.lotto_reviews_history", new=AsyncMock(return_value=[ {"draw_no": 1153, "curator_avg_match": 1.8, "user_avg_match": 2.0, "pattern_delta": "저번호 편향 +1.2"}, {"draw_no": 1152, "curator_avg_match": 1.6, "user_avg_match": 1.5, "pattern_delta": "저번호 편향 +0.8"}, {"draw_no": 1151, "curator_avg_match": 1.7, "user_avg_match": 1.8, "pattern_delta": "저번호 편향 +1.0"}, {"draw_no": 1150, "curator_avg_match": 1.9, "user_avg_match": 2.2, "pattern_delta": ""}, ])): out = await build_retrospective(1154) assert out["last_draw"]["draw_no"] == 1153 assert out["trend_4w"]["curator_avg_4w"] == round((1.8+1.6+1.7+1.9)/4, 2) assert "저번호" in out["trend_4w"]["user_persistent_bias"] @pytest.mark.asyncio async def test_build_retrospective_no_review(): with patch("app.service_proxy.lotto_review_by_draw", new=AsyncMock(return_value=None)): out = await build_retrospective(1154) assert out is None