"""Contract tests for list_milestones 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 TestListMilestonesContract: """Contract tests verifying list_milestones tool interface.""" async def test_list_milestones_returns_milestone_activities( self, sample_xer_single_project: Path ) -> None: """list_milestones returns only milestone type activities.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await list_milestones() assert "milestones" in result assert len(result["milestones"]) == 2 async def test_list_milestones_includes_expected_fields( self, sample_xer_single_project: Path ) -> None: """list_milestones returns milestones with required fields.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await list_milestones() milestone = result["milestones"][0] assert "task_id" in milestone assert "task_code" in milestone assert "task_name" in milestone assert "target_start_date" in milestone assert "target_end_date" in milestone async def test_list_milestones_returns_correct_activities( self, sample_xer_single_project: Path ) -> None: """list_milestones returns the expected milestone activities.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await list_milestones() milestone_names = [m["task_name"] for m in result["milestones"]] assert "Project Start" in milestone_names assert "Project Complete" in milestone_names async def test_list_milestones_empty_when_no_milestones(self, sample_xer_empty: Path) -> None: """list_milestones returns empty list when no milestones exist.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_empty)) result = await list_milestones() assert "milestones" in result assert len(result["milestones"]) == 0 async def test_list_milestones_no_file_loaded_returns_error(self) -> None: """list_milestones without loaded file returns NO_FILE_LOADED error.""" from xer_mcp.server import set_file_loaded from xer_mcp.tools.list_milestones import list_milestones set_file_loaded(False) result = await list_milestones() assert "error" in result assert result["error"]["code"] == "NO_FILE_LOADED" async def test_list_milestones_includes_milestone_type_field( self, sample_xer_single_project: Path ) -> None: """list_milestones returns milestones with milestone_type field.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await list_milestones() # All milestones should have milestone_type field for milestone in result["milestones"]: assert "milestone_type" in milestone async def test_list_milestones_returns_start_and_finish_types( self, sample_xer_single_project: Path ) -> None: """list_milestones returns milestones with correct start/finish types.""" from xer_mcp.tools.list_milestones import list_milestones from xer_mcp.tools.load_xer import load_xer await load_xer(file_path=str(sample_xer_single_project)) result = await list_milestones() # Find milestones by name and verify their types milestones_by_name = {m["task_name"]: m for m in result["milestones"]} # "Project Start" should be a start milestone assert milestones_by_name["Project Start"]["milestone_type"] == "start" # "Project Complete" should be a finish milestone assert milestones_by_name["Project Complete"]["milestone_type"] == "finish"