"""Contract tests for get_successors MCP tool.""" from pathlib import Path import pytest from xer_mcp.db import db @pytest.fixture(autouse=True) def setup_db(): """Initialize and clear database for each test.""" db.initialize() yield db.clear() class TestGetSuccessorsContract: """Contract tests verifying get_successors tool interface.""" async def test_get_successors_returns_list(self, sample_xer_single_project: Path) -> None: """get_successors returns successor activities.""" from xer_mcp.tools.get_successors import get_successors from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) # A1010 (2002) has two successors: A1020 (2003) and A1030 (2004) result = await get_successors(activity_id="2002") assert "activity_id" in result assert result["activity_id"] == "2002" assert "successors" in result assert len(result["successors"]) == 2 async def test_get_successors_includes_relationship_details( self, sample_xer_single_project: Path ) -> None: """get_successors includes relationship type and lag.""" from xer_mcp.tools.get_successors import get_successors from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await get_successors(activity_id="2001") succ = result["successors"][0] assert "relationship_type" in succ assert "lag_hr_cnt" in succ assert succ["relationship_type"] in ["FS", "SS", "FF", "SF"] async def test_get_successors_empty_list_for_no_successors( self, sample_xer_single_project: Path ) -> None: """get_successors returns empty list when no successors exist.""" from xer_mcp.tools.get_successors import get_successors from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) # A1040 (2005) has no successors result = await get_successors(activity_id="2005") assert "successors" in result assert len(result["successors"]) == 0 async def test_get_successors_no_file_loaded_returns_error(self) -> None: """get_successors without loaded file returns NO_FILE_LOADED error.""" from xer_mcp.server import set_file_loaded from xer_mcp.tools.get_successors import get_successors set_file_loaded(False) result = await get_successors(activity_id="2002") assert "error" in result assert result["error"]["code"] == "NO_FILE_LOADED" async def test_get_successors_includes_driving_flag( self, sample_xer_single_project: Path ) -> None: """get_successors includes driving flag for each successor.""" from xer_mcp.tools.get_successors import get_successors from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) # A1000 (2001) has one successor: A1010 (2002) result = await get_successors(activity_id="2001") assert "successors" in result assert len(result["successors"]) >= 1 # All successors should have a driving flag for succ in result["successors"]: assert "driving" in succ assert isinstance(succ["driving"], bool)