fix: validate date format in create_schedule with clear error message

This commit is contained in:
2026-03-09 20:36:55 -05:00
parent c670ea5bc9
commit 6154b83455
3 changed files with 120 additions and 6 deletions

View File

@@ -4,10 +4,17 @@ MCP Server for Naliia Module
from contextlib import asynccontextmanager
from fastmcp import FastMCP
from typing import List, AsyncIterator, Any, Dict
import datetime
from typing import List, Dict, AsyncIterator, Any
from datetime import datetime, timezone
from tryton_mcp.config import settings
import logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
@asynccontextmanager
@@ -29,18 +36,63 @@ def tryton_call(name: str, args: list) -> Dict[str, Any]:
return {"success": False, "error": str(e)}
@mcp.tool()
def find_customer_by_identifier(identifier: str) -> List[Dict]:
result = tryton_call(
"model.party.identifier.search_read",
[
[["code", "=", identifier]],
0,
None,
None,
["party", "party.name"],
{"company": 1},
],
)
if not result["success"]:
raise Exception(f"Customer with identifier {identifier} not found.")
return result["data"]
@mcp.tool()
def create_customer(
name: str, identifiers: List[tuple[str, List[Dict[str, Any]]]]
) -> List[int]:
result = tryton_call(
"model.party.party.create",
[{"name": name, "identifiers": identifiers}, {}],
)
if not result["success"]:
raise Exception(f"Failed to create {name} as customer")
return result["data"]
@mcp.tool()
def create_schedule(
professional: int, description: str, customer: int, date: str, service_center: int
) -> List[int]:
try:
dt = datetime.fromisoformat(date)
except ValueError:
raise ValueError(
f"Invalid date format: '{date}'. Expected ISO format (e.g., '2026-03-15T10:00:00' or '2026-03-15T10:00:00+00:00')"
)
utc_dt = dt.astimezone(timezone.utc)
example_schedule = [
{
"professional": 6,
"professional": professional,
"description": description,
"customer": 4,
"date": datetime.datetime.fromisoformat(date),
"service_center": 11,
"customer": customer,
"date": utc_dt,
"service_center": service_center,
}
]

48
tests/test_customer.py Normal file
View File

@@ -0,0 +1,48 @@
import pytest
import sys
from pathlib import Path
import json
from tryton_mcp.server import create_customer
sys.path.insert(0, str(Path(__file__).parent / "src"))
@pytest.mark.asyncio
class TestParty:
async def test_create_new_customer(self, mcp_client, mock_settings):
mock_client = mock_settings.get_client.return_value
mock_client.call.return_value = [1]
result = await mcp_client.call_tool(
"create_customer",
{
"name": "Alejandro Zapata",
"identifiers": [["create", [{"type": "mobile", "code": "310659595"}]]],
},
)
assert result.content is not None
assert len(result.content) == 1
assert result.content[0].text == "[1]"
async def test_find_customer(self, mcp_client, mock_settings):
expected_return = [
{'id': 19, 'party': 44, 'party.': {'name': 'Alejandro Zapata', 'id': 44}}
]
mock_client = mock_settings.get_client.return_value
mock_client.call.return_value = expected_return
result = await mcp_client.call_tool(
"find_customer_by_identifier",
{
"identifier": "310659595"
})
assert result.content is not None
assert len(result.content) == 1
assert json.loads(result.content[0].text) == expected_return

View File

@@ -2,6 +2,7 @@ import pytest
from unittest.mock import MagicMock, patch
import datetime
import json
from fastmcp.exceptions import ToolError
import sys
from pathlib import Path
@@ -78,6 +79,19 @@ class TestCreateSchedule:
},
)
async def test_create_schedule_invalid_date_format(self, mcp_client, mock_settings):
with pytest.raises(ToolError, match="Invalid date format"):
await mcp_client.call_tool(
"create_schedule",
{
"professional": 6,
"description": "Test appointment",
"customer": 4,
"date": "invalid-date",
"service_center": 11,
},
)
@pytest.mark.asyncio
class TestFindServiceCenters: