"""
Client Interaction Integration Tests
Tests the full client-server interaction workflow, migrated and enhanced
from the original server_test.py file.
"""
import pytest
from fastmcp import Client
@pytest.mark.integration
@pytest.mark.asyncio
async def test_tool_discovery(mcp_client):
"""Test that tools can be discovered by the client."""
tools = await mcp_client.list_tools()
# Should have at least the arithmetic tools
tool_names = [tool.name for tool in tools]
assert "add" in tool_names, "Add tool should be available"
assert "subtract" in tool_names, "Subtract tool should be available"
assert len(tools) >= 2, "Should have at least 2 tools registered"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_add_tool_execution(mcp_client):
"""Test the add tool execution via client."""
result = await mcp_client.call_tool("add", {"a": 1, "b": 2})
assert result.content[0].text == "3", f"Expected '3', got '{result.content[0].text}'"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_subtract_tool_execution(mcp_client):
"""Test the subtract tool execution via client."""
result = await mcp_client.call_tool("subtract", {"a": 10, "b": 3})
assert result.content[0].text == "7", f"Expected '7', got '{result.content[0].text}'"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_multiple_tool_calls(mcp_client):
"""Test multiple sequential tool calls."""
# Test add operation
add_result = await mcp_client.call_tool("add", {"a": 5, "b": 3})
assert add_result.content[0].text == "8"
# Test subtract operation
subtract_result = await mcp_client.call_tool("subtract", {"a": 15, "b": 7})
assert subtract_result.content[0].text == "8"
# Both should return the same result
assert add_result.content[0].text == subtract_result.content[0].text
@pytest.mark.integration
@pytest.mark.asyncio
async def test_tool_with_negative_numbers(mcp_client):
"""Test tools with negative numbers."""
# Add with negative
result1 = await mcp_client.call_tool("add", {"a": -5, "b": 3})
assert result1.content[0].text == "-2"
# Subtract with negative
result2 = await mcp_client.call_tool("subtract", {"a": 5, "b": -3})
assert result2.content[0].text == "8"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_tool_with_zero(mcp_client):
"""Test tools with zero values."""
# Add with zero
result1 = await mcp_client.call_tool("add", {"a": 0, "b": 5})
assert result1.content[0].text == "5"
# Subtract with zero
result2 = await mcp_client.call_tool("subtract", {"a": 5, "b": 0})
assert result2.content[0].text == "5"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_resource_access(mcp_client):
"""Test accessing resources via client."""
# This will depend on the specific resource implementation
# For now, we'll test that we can list resources
try:
resources = await mcp_client.list_resources()
# Should have at least the system resources
assert len(resources) >= 1, "Should have at least 1 resource"
except Exception as e:
# If list_resources is not available, that's ok for now
pytest.skip(f"Resource listing not available: {e}")
@pytest.mark.integration
@pytest.mark.asyncio
async def test_prompt_access(mcp_client):
"""Test accessing prompts via client."""
try:
prompts = await mcp_client.list_prompts()
# Should have at least the text processing prompts
assert len(prompts) >= 1, "Should have at least 1 prompt"
except Exception as e:
# If list_prompts is not available, that's ok for now
pytest.skip(f"Prompt listing not available: {e}")