fix(mcp): scope fixture NullPool + suppression imports inutiles + validation enums + cleanup tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,9 @@ from sqlalchemy import select, and_
|
|||||||
|
|
||||||
from app.core.database import AsyncSessionLocal
|
from app.core.database import AsyncSessionLocal
|
||||||
from app.models.todos import TodoItem
|
from app.models.todos import TodoItem
|
||||||
from app.models.notes import NoteItem
|
|
||||||
from app.models.shopping import ShoppingList, ListItem, Product
|
_VALID_STATUSES = {"pending", "done", "cancelled"}
|
||||||
|
_VALID_PRIORITIES = {"low", "medium", "high"}
|
||||||
|
|
||||||
mcp = FastMCP("HomeHub", stateless_http=True)
|
mcp = FastMCP("HomeHub", stateless_http=True)
|
||||||
|
|
||||||
@@ -79,6 +80,8 @@ async def create_todo(
|
|||||||
domain: str | None = None,
|
domain: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Crée une tâche. due_date en ISO 8601 (ex: 2025-06-01T10:00:00Z). priority: low/medium/high."""
|
"""Crée une tâche. due_date en ISO 8601 (ex: 2025-06-01T10:00:00Z). priority: low/medium/high."""
|
||||||
|
if priority and priority not in _VALID_PRIORITIES:
|
||||||
|
return _dumps({"error": f"Priorité invalide : {priority}. Valeurs: low/medium/high"})
|
||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
parsed_due = None
|
parsed_due = None
|
||||||
if due_date:
|
if due_date:
|
||||||
@@ -121,6 +124,10 @@ async def update_todo(
|
|||||||
item = await session.get(TodoItem, todo_id)
|
item = await session.get(TodoItem, todo_id)
|
||||||
if not item:
|
if not item:
|
||||||
return _dumps({"error": f"Tâche introuvable : {id}"})
|
return _dumps({"error": f"Tâche introuvable : {id}"})
|
||||||
|
if status is not None and status not in _VALID_STATUSES:
|
||||||
|
return _dumps({"error": f"Statut invalide : {status}. Valeurs: pending/done/cancelled"})
|
||||||
|
if priority is not None and priority not in _VALID_PRIORITIES:
|
||||||
|
return _dumps({"error": f"Priorité invalide : {priority}. Valeurs: low/medium/high"})
|
||||||
if title is not None:
|
if title is not None:
|
||||||
item.title = title
|
item.title = title
|
||||||
if status is not None:
|
if status is not None:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ def make_test_engine():
|
|||||||
return create_async_engine(settings.database_url, poolclass=NullPool)
|
return create_async_engine(settings.database_url, poolclass=NullPool)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture
|
||||||
async def mcp_nullpool_session():
|
async def mcp_nullpool_session():
|
||||||
"""Remplace AsyncSessionLocal dans mcp_server par un sessionmaker NullPool
|
"""Remplace AsyncSessionLocal dans mcp_server par un sessionmaker NullPool
|
||||||
pour éviter les conflits d'event loop entre tests."""
|
pour éviter les conflits d'event loop entre tests."""
|
||||||
|
|||||||
@@ -1,8 +1,21 @@
|
|||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
|
from sqlalchemy import delete
|
||||||
from app.api.mcp_server import (
|
from app.api.mcp_server import (
|
||||||
get_todos, create_todo, update_todo, postpone_todo, delete_todo,
|
get_todos, create_todo, update_todo, postpone_todo, delete_todo,
|
||||||
)
|
)
|
||||||
|
from app.core.database import AsyncSessionLocal
|
||||||
|
from app.models.todos import TodoItem
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.usefixtures("mcp_nullpool_session")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
async def cleanup_mcp_todos():
|
||||||
|
yield
|
||||||
|
async with AsyncSessionLocal() as session:
|
||||||
|
await session.execute(delete(TodoItem).where(TodoItem.title.like("TEST_MCP_%")))
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
async def test_get_todos_retourne_liste_json():
|
async def test_get_todos_retourne_liste_json():
|
||||||
|
|||||||
Reference in New Issue
Block a user