# apps/api/tests/test_ai_router_feedback.py | 2026-04-20 @ Asia/Taipei
# 2026-04-22 @ Asia/Taipei: 重構移除 FakeRepo/FakeSession（違反 feedback_no_mock_testing.md）
#   方案：抽取 AIRouter._aggregate_feedback_stats 純函數，直接單元測試，零 DB 依賴。
#   DB 聚合查詢行為已由 integration/test_ai_router_feedback_integration.py 覆蓋。
"""Unit tests for AIRouter._aggregate_feedback_stats — 純邏輯，無 DB。"""
import pytest
from src.services.ai_router import AIRouter


# =============================================================================
# _aggregate_feedback_stats 純函數測試（無 DB 依賴）
# =============================================================================

def test_feedback_aggregates_by_model():
    stats = [
        {"repo": "awoooi", "model": "elephant-alpha", "total": 10,
         "errors": 2, "success_rate": 0.8},
        {"repo": "awoooi", "model": "gemini-pro", "total": 5,
         "errors": 0, "success_rate": 1.0},
    ]
    out = AIRouter._aggregate_feedback_stats(stats)
    assert out["elephant-alpha"] == 0.8
    assert out["gemini-pro"] == 1.0


def test_feedback_filters_by_repo():
    stats = [
        {"repo": "awoooi", "model": "elephant-alpha", "total": 5,
         "errors": 1, "success_rate": 0.8},
        {"repo": "other-repo", "model": "elephant-alpha", "total": 3,
         "errors": 3, "success_rate": 0.0},
    ]
    out = AIRouter._aggregate_feedback_stats(stats, repo="awoooi")
    assert out == {"elephant-alpha": 0.8}


def test_feedback_handles_empty_stats():
    out = AIRouter._aggregate_feedback_stats([])
    assert out == {}


def test_feedback_skips_missing_model():
    stats = [
        {"repo": "awoooi", "model": None, "success_rate": 0.9},
        {"repo": "awoooi", "model": "gemini-pro", "success_rate": 0.7},
    ]
    out = AIRouter._aggregate_feedback_stats(stats)
    assert list(out.keys()) == ["gemini-pro"]


# =============================================================================
# feedback_from_aider_events — DB 失敗降級行為（error path，無 FakeRepo）
# =============================================================================

@pytest.mark.asyncio
async def test_feedback_returns_empty_on_db_failure(monkeypatch):
    monkeypatch.setattr(
        "src.services.ai_router.get_session_factory",
        lambda: (_ for _ in ()).throw(RuntimeError("DB unavailable")),
        raising=False,
    )

    r = AIRouter()
    out = await r.feedback_from_aider_events(days=7)
    assert out == {}
