Files
xer-mcp/tests/unit/test_table_handlers.py
Bill Ballou ccc8296418 feat: implement XER MCP Server with 9 schedule query tools
Implement complete MCP server for parsing Primavera P6 XER files and
exposing schedule data through MCP tools. All 4 user stories complete.

Tools implemented:
- load_xer: Parse XER files into SQLite database
- list_activities: Query activities with pagination and filtering
- get_activity: Get activity details by ID
- list_relationships: Query activity dependencies
- get_predecessors/get_successors: Query activity relationships
- get_project_summary: Project overview with counts
- list_milestones: Query milestone activities
- get_critical_path: Query driving path activities

Features:
- Tab-delimited XER format parsing with pluggable table handlers
- In-memory SQLite database for fast queries
- Pagination with 100-item default limit
- Multi-project file support with project selection
- ISO8601 date formatting
- NO_FILE_LOADED error handling for all query tools

Test coverage: 81 tests (contract, integration, unit)
2026-01-06 21:27:35 -05:00

193 lines
5.6 KiB
Python

"""Unit tests for XER table handlers."""
class TestProjectHandler:
"""Tests for PROJECT table handler."""
def test_parse_project_row(self) -> None:
"""Handler should parse PROJECT row correctly."""
from xer_mcp.parser.table_handlers.project import ProjectHandler
handler = ProjectHandler()
# Minimal PROJECT fields
fields = [
"proj_id",
"proj_short_name",
"plan_start_date",
"plan_end_date",
]
values = ["1001", "Test Project", "2026-01-01 00:00", "2026-06-30 00:00"]
result = handler.parse_row(fields, values)
assert result is not None
assert result["proj_id"] == "1001"
assert result["proj_short_name"] == "Test Project"
assert result["plan_start_date"] == "2026-01-01T00:00:00"
assert result["plan_end_date"] == "2026-06-30T00:00:00"
def test_table_name(self) -> None:
"""Handler should report correct table name."""
from xer_mcp.parser.table_handlers.project import ProjectHandler
handler = ProjectHandler()
assert handler.table_name == "PROJECT"
class TestTaskHandler:
"""Tests for TASK table handler."""
def test_parse_task_row(self) -> None:
"""Handler should parse TASK row correctly."""
from xer_mcp.parser.table_handlers.task import TaskHandler
handler = TaskHandler()
fields = [
"task_id",
"proj_id",
"wbs_id",
"task_code",
"task_name",
"task_type",
"status_code",
"target_start_date",
"target_end_date",
"total_float_hr_cnt",
"driving_path_flag",
]
values = [
"2001",
"1001",
"100",
"A1000",
"Site Prep",
"TT_Task",
"TK_NotStart",
"2026-01-02 07:00",
"2026-01-08 15:00",
"0",
"Y",
]
result = handler.parse_row(fields, values)
assert result is not None
assert result["task_id"] == "2001"
assert result["task_code"] == "A1000"
assert result["task_type"] == "TT_Task"
assert result["driving_path_flag"] is True
assert result["total_float_hr_cnt"] == 0.0
def test_table_name(self) -> None:
"""Handler should report correct table name."""
from xer_mcp.parser.table_handlers.task import TaskHandler
handler = TaskHandler()
assert handler.table_name == "TASK"
class TestTaskpredHandler:
"""Tests for TASKPRED table handler."""
def test_parse_relationship_row(self) -> None:
"""Handler should parse TASKPRED row correctly."""
from xer_mcp.parser.table_handlers.taskpred import TaskpredHandler
handler = TaskpredHandler()
fields = [
"task_pred_id",
"task_id",
"pred_task_id",
"proj_id",
"pred_proj_id",
"pred_type",
"lag_hr_cnt",
]
values = ["3001", "2002", "2001", "1001", "1001", "PR_FS", "8"]
result = handler.parse_row(fields, values)
assert result is not None
assert result["task_pred_id"] == "3001"
assert result["task_id"] == "2002"
assert result["pred_task_id"] == "2001"
assert result["pred_type"] == "PR_FS"
assert result["lag_hr_cnt"] == 8.0
def test_table_name(self) -> None:
"""Handler should report correct table name."""
from xer_mcp.parser.table_handlers.taskpred import TaskpredHandler
handler = TaskpredHandler()
assert handler.table_name == "TASKPRED"
class TestProjwbsHandler:
"""Tests for PROJWBS table handler."""
def test_parse_wbs_row(self) -> None:
"""Handler should parse PROJWBS row correctly."""
from xer_mcp.parser.table_handlers.projwbs import ProjwbsHandler
handler = ProjwbsHandler()
fields = [
"wbs_id",
"proj_id",
"parent_wbs_id",
"wbs_short_name",
"wbs_name",
]
values = ["100", "1001", "", "ROOT", "Project Root"]
result = handler.parse_row(fields, values)
assert result is not None
assert result["wbs_id"] == "100"
assert result["proj_id"] == "1001"
assert result["parent_wbs_id"] == ""
assert result["wbs_short_name"] == "ROOT"
def test_table_name(self) -> None:
"""Handler should report correct table name."""
from xer_mcp.parser.table_handlers.projwbs import ProjwbsHandler
handler = ProjwbsHandler()
assert handler.table_name == "PROJWBS"
class TestCalendarHandler:
"""Tests for CALENDAR table handler."""
def test_parse_calendar_row(self) -> None:
"""Handler should parse CALENDAR row correctly."""
from xer_mcp.parser.table_handlers.calendar import CalendarHandler
handler = CalendarHandler()
fields = [
"clndr_id",
"clndr_name",
"day_hr_cnt",
"week_hr_cnt",
]
values = ["1", "Standard 5 Day", "8", "40"]
result = handler.parse_row(fields, values)
assert result is not None
assert result["clndr_id"] == "1"
assert result["clndr_name"] == "Standard 5 Day"
assert result["day_hr_cnt"] == 8.0
assert result["week_hr_cnt"] == 40.0
def test_table_name(self) -> None:
"""Handler should report correct table name."""
from xer_mcp.parser.table_handlers.calendar import CalendarHandler
handler = CalendarHandler()
assert handler.table_name == "CALENDAR"