"""Contract tests for load_xer 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 TestLoadXerContract: """Contract tests verifying load_xer tool interface matches spec.""" async def test_load_single_project_returns_success( self, sample_xer_single_project: Path ) -> None: """load_xer with single-project file returns success and project info.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(sample_xer_single_project)) assert result["success"] is True assert "project" in result assert result["project"]["proj_id"] == "1001" assert result["project"]["proj_short_name"] == "Test Project" assert "activity_count" in result assert result["activity_count"] == 5 assert "relationship_count" in result assert result["relationship_count"] == 5 async def test_load_multi_project_without_selection_returns_list( self, sample_xer_multi_project: Path ) -> None: """load_xer with multi-project file without project_id returns available projects.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(sample_xer_multi_project)) assert result["success"] is False assert "available_projects" in result assert len(result["available_projects"]) == 2 assert "message" in result assert "project_id" in result["message"].lower() async def test_load_multi_project_with_selection_returns_success( self, sample_xer_multi_project: Path ) -> None: """load_xer with multi-project file and project_id returns selected project.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(sample_xer_multi_project), project_id="1001") assert result["success"] is True assert result["project"]["proj_id"] == "1001" assert result["project"]["proj_short_name"] == "Project Alpha" async def test_load_nonexistent_file_returns_error(self, nonexistent_xer_path: Path) -> None: """load_xer with missing file returns FILE_NOT_FOUND error.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(nonexistent_xer_path)) assert result["success"] is False assert "error" in result assert result["error"]["code"] == "FILE_NOT_FOUND" async def test_load_invalid_file_returns_error(self, invalid_xer_file: Path) -> None: """load_xer with invalid file returns PARSE_ERROR error.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(invalid_xer_file)) assert result["success"] is False assert "error" in result assert result["error"]["code"] == "PARSE_ERROR" async def test_load_replaces_previous_file( self, sample_xer_single_project: Path, sample_xer_empty: Path ) -> None: """Loading a new file replaces the previous file's data.""" from xer_mcp.tools.load_xer import load_xer # Load first file result1 = await load_xer(file_path=str(sample_xer_single_project)) assert result1["activity_count"] == 5 # Load second file (empty) result2 = await load_xer(file_path=str(sample_xer_empty)) assert result2["activity_count"] == 0 async def test_load_returns_plan_dates(self, sample_xer_single_project: Path) -> None: """load_xer returns project plan start and end dates.""" from xer_mcp.tools.load_xer import load_xer result = await load_xer(file_path=str(sample_xer_single_project)) assert "plan_start_date" in result["project"] assert "plan_end_date" in result["project"] # Dates should be ISO8601 format assert "T" in result["project"]["plan_start_date"]