"""回归测试: 伤停切片区分「查询成功但无人伤停」与「无数据/未接入」。 验证: 1. 查询成功 + 空结果 → has_data=True 2. 源未配置 → has_data=False 3. 查询异常 → has_data=False 4. 查询成功 + 有数据 → has_data=True """ from __future__ import annotations from datetime import datetime, timezone from unittest.mock import MagicMock, AsyncMock, patch import pytest from src.data.injuries import InjuryQueryResult, get_injuries_for_match from src.llm.context_builder import MatchHeader, injuries_slice def _make_header(): return MatchHeader( match_id=999, home_name="A", away_name="B", league_name="X", season=None, match_date="?", match_date=None, stage=None, home_team_id=1, away_team_id=2, league_id=1, ) class TestInjuryQueryResult: """InjuryQueryResult 基础属性。""" def test_has_data_success(self): result = InjuryQueryResult(records=[], query_status="success") assert result.has_data is True def test_has_data_source_not_configured(self): result = InjuryQueryResult(records=[], query_status="source_not_configured") assert result.has_data is False def test_has_data_query_error(self): result = InjuryQueryResult(records=[], query_status="query_error") assert result.has_data is False class TestInjuriesSliceEmptyVsNotConfigured: """injuries_slice 应区分「查询成功但为空」与「无数据/未接入」。""" @pytest.mark.asyncio async def test_empty_result_has_data_true(self): """查询成功 + 空结果 → has_data=True,文案显示「当前无伤停记录」。""" header = _make_header() # Mock get_injuries_for_match 返回成功但空的结果 async def mock_query(db, team_id, match_date, as_of=None): return InjuryQueryResult(records=[], query_status="success") with patch("src.llm.context_builder.get_injuries_for_match", mock_query): result = await injuries_slice(header, before=None) assert result.has_data is True, "查询成功+空结果应 has_data=True" assert "当前无伤停记录" in result.text, "文案应表明无伤停" @pytest.mark.asyncio async def test_source_not_configured_has_data_false(self): """源未配置 → has_data=False。""" header = _make_header() async def mock_query(db, team_id, match_date, as_of=None): return InjuryQueryResult(records=[], query_status="source_not_configured") with patch("src.llm.context_builder.get_injuries_for_match", mock_query): result = await injuries_slice(header, before=None) assert result.has_data is False, "源未配置应 has_data=False" assert "伤停源未配置" in result.text @pytest.mark.asyncio async def test_query_error_has_data_false(self): """查询异常 → has_data=False。""" header = _make_header() async def mock_query(db, team_id, match_date, as_of=None): return InjuryQueryResult(records=[], query_status="query_error") with patch("src.llm.context_builder.get_injuries_for_match", mock_query): result = await injuries_slice(header, before=None) assert result.has_data is False, "查询异常应 has_data=False" assert "查询异常" in result.text @pytest.mark.asyncio async def test_with_records_has_data_true(self): """查询成功 + 有数据 → has_data=True。""" header = _make_header() mock_inj = MagicMock() mock_inj.reason = "Hamstring" mock_inj.injury_type = None mock_inj.player_name = "Player A" async def mock_query(db, team_id, match_date, as_of=None): if team_id == 1: return InjuryQueryResult(records=[mock_inj], query_status="success") return InjuryQueryResult(records=[], query_status="success") with patch("src.llm.context_builder.get_injuries_for_match", mock_query): result = await injuries_slice(header, before=None) assert result.has_data is True assert "Player A" in result.text