"""Contract tests for get_critical_path 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 TestGetCriticalPathContract: """Contract tests verifying get_critical_path tool interface.""" async def test_get_critical_path_returns_critical_activities( self, sample_xer_single_project: Path ) -> None: """get_critical_path returns activities with driving_path_flag set.""" from xer_mcp.tools.get_critical_path import get_critical_path from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await get_critical_path() assert "critical_activities" in result assert len(result["critical_activities"]) == 4 async def test_get_critical_path_includes_expected_fields( self, sample_xer_single_project: Path ) -> None: """get_critical_path returns activities with required fields.""" from xer_mcp.tools.get_critical_path import get_critical_path from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await get_critical_path() activity = result["critical_activities"][0] assert "task_id" in activity assert "task_code" in activity assert "task_name" in activity assert "target_start_date" in activity assert "target_end_date" in activity assert "total_float_hr_cnt" in activity async def test_get_critical_path_ordered_by_date(self, sample_xer_single_project: Path) -> None: """get_critical_path returns activities ordered by start date.""" from xer_mcp.tools.get_critical_path import get_critical_path from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await get_critical_path() activities = result["critical_activities"] for i in range(len(activities) - 1): assert activities[i]["target_start_date"] <= activities[i + 1]["target_start_date"] async def test_get_critical_path_excludes_non_critical( self, sample_xer_single_project: Path ) -> None: """get_critical_path excludes activities not on critical path.""" from xer_mcp.tools.get_critical_path import get_critical_path from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await get_critical_path() # A1020 "Foundation Work" has driving_path_flag = N activity_names = [a["task_name"] for a in result["critical_activities"]] assert "Foundation Work" not in activity_names async def test_get_critical_path_no_file_loaded_returns_error(self) -> None: """get_critical_path without loaded file returns NO_FILE_LOADED error.""" from xer_mcp.server import set_file_loaded from xer_mcp.tools.get_critical_path import get_critical_path set_file_loaded(False) result = await get_critical_path() assert "error" in result assert result["error"]["code"] == "NO_FILE_LOADED"