from __future__ import annotations from collections.abc import AsyncIterator from contextlib import asynccontextmanager import pytest import pytest_asyncio from httpx import ASGITransport from httpx import AsyncClient from mcp import ClientSession from mcp.client.streamable_http import streamable_http_client from personal_mcp.web.app import create_app @pytest_asyncio.fixture async def client() -> AsyncIterator[AsyncClient]: """Provides an AsyncClient bound to a fresh application instance.""" app = create_app() async with AsyncClient( transport=ASGITransport(app=app), base_url="http://testserver", timeout=10.0, ) as test_client: yield test_client @pytest.fixture def mcp_session_factory(): """Provides an in-process context manager factory for MCP SDK sessions.""" @asynccontextmanager async def create_session(*, initialize: bool = True) -> AsyncIterator[ClientSession]: app = create_app() mcp_url = f"http://testserver{app.state.settings.mounts.mcp}" async with ( app.router.lifespan_context(app), AsyncClient( transport=ASGITransport(app=app), base_url="http://testserver", timeout=10.0, ) as http_client, streamable_http_client( mcp_url, http_client=http_client, ) as (read_stream, write_stream, _), ClientSession(read_stream, write_stream) as session, ): if initialize: await session.initialize() yield session return create_session