diff --git a/tests/client/test_streamable_http.py b/tests/client/test_streamable_http.py index bcbf9feee..237316313 100644 --- a/tests/client/test_streamable_http.py +++ b/tests/client/test_streamable_http.py @@ -2,6 +2,7 @@ import asyncio import json import sys from collections.abc import AsyncGenerator +from unittest.mock import AsyncMock import pytest import uvicorn @@ -71,8 +72,10 @@ def fastmcp_server(): return server -def run_server(host: str, port: int, **kwargs) -> None: - fastmcp_server().run(host=host, port=port, **kwargs) +def run_server(host: str, port: int, stateless_http: bool = False, **kwargs) -> None: + server = fastmcp_server() + server.settings.stateless_http = stateless_http + server.run(host=host, port=port, **kwargs) def run_nested_server(host: str, port: int) -> None: @@ -96,21 +99,13 @@ def run_nested_server(host: str, port: int) -> None: @pytest.fixture() -async def streamable_http_server() -> AsyncGenerator[str, None]: - with run_server_in_process(run_server, transport="streamable-http") as url: +async def streamable_http_server(stateless_http: bool = False) -> AsyncGenerator[str, None]: + with run_server_in_process(run_server, stateless_http=stateless_http, transport="streamable-http") as url: async with Client(transport=StreamableHttpTransport(f"{url}/mcp")) as client: assert await client.ping() yield f"{url}/mcp" -PROGRESS_MESSAGES = [] - -async def progress_handler( - progress: float, total: float | None, message: str | None -) -> None: - PROGRESS_MESSAGES.append(dict(progress=progress, total=total, message=message)) - - async def test_ping(streamable_http_server: str): """Test pinging the server.""" async with Client( @@ -133,8 +128,11 @@ async def test_http_headers(streamable_http_server: str): assert json_result["x-demo-header"] == "ABC" +@pytest.mark.parametrize("streamable_http_server", [True, False], indirect=True) async def test_greet_with_progress_tool(streamable_http_server: str): """Test calling the greet tool.""" + progress_handler = AsyncMock(return_value=None) + async with Client( transport=StreamableHttpTransport(streamable_http_server), progress_handler=progress_handler ) as client: @@ -144,9 +142,7 @@ async def test_greet_with_progress_tool(streamable_http_server: str): assert isinstance(result[0], TextContent) assert result[0].text == "Hello, Alice!" - assert PROGRESS_MESSAGES == [ - dict(progress=0.5, total=1.0, message="Greeting in progress"), - ] + progress_handler.assert_called_once_with(0.5, 1.0, "Greeting in progress") async def test_nested_streamable_http_server_resolves_correctly(): diff --git a/tests/client/test_streamable_http_stateless.py b/tests/client/test_streamable_http_stateless.py deleted file mode 100644 index fd55c752e..000000000 --- a/tests/client/test_streamable_http_stateless.py +++ /dev/null @@ -1,60 +0,0 @@ -from collections.abc import AsyncGenerator - -import pytest -from mcp.types import TextContent - -from fastmcp import Context -from fastmcp.client import Client -from fastmcp.client.transports import StreamableHttpTransport -from fastmcp.server.server import FastMCP -from fastmcp.utilities.tests import run_server_in_process - - -def fastmcp_server(): - """Fixture that creates a FastMCP server with tools, resources, and prompts.""" - server = FastMCP("TestServer") - server.settings.stateless_http = True - - @server.tool - async def greet_with_progress(name: str, ctx: Context) -> str: - """Report progress for a greeting.""" - await ctx.report_progress(0.5, 1.0, "Greeting in progress") - return f"Hello, {name}!" - - return server - - -def run_server(host: str, port: int, **kwargs) -> None: - fastmcp_server().run(host=host, port=port, **kwargs) - - -@pytest.fixture() -async def streamable_http_server() -> AsyncGenerator[str, None]: - with run_server_in_process(run_server, transport="streamable-http") as url: - async with Client(transport=StreamableHttpTransport(f"{url}/mcp")) as client: - assert await client.ping() - yield f"{url}/mcp" - - -PROGRESS_MESSAGES = [] - -async def progress_handler( - progress: float, total: float | None, message: str | None -) -> None: - PROGRESS_MESSAGES.append(dict(progress=progress, total=total, message=message)) - - -async def test_greet_with_progress_tool(streamable_http_server: str): - """Test calling the greet tool.""" - async with Client( - transport=StreamableHttpTransport(streamable_http_server), progress_handler=progress_handler - ) as client: - result = await client.call_tool("greet_with_progress", {"name": "Alice"}) - - assert isinstance(result, list) - assert isinstance(result[0], TextContent) - assert result[0].text == "Hello, Alice!" - - assert PROGRESS_MESSAGES == [ - dict(progress=0.5, total=1.0, message="Greeting in progress"), - ]