Skip to content

Commit 735581c

Browse files
committed
fix: fixing tests for earlier versions
1 parent 56f9b33 commit 735581c

File tree

1 file changed

+69
-36
lines changed

1 file changed

+69
-36
lines changed

tests/integrations/fastmcp/test_fastmcp.py

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def call_tool_through_mcp(mcp_instance, tool_name, arguments):
8686
arguments: Dictionary of arguments to pass to the tool
8787
8888
Returns:
89-
The tool result (extracted from CallToolResult)
89+
The tool result normalized to {"result": value} format
9090
"""
9191
import asyncio
9292
import json
@@ -102,14 +102,29 @@ def call_tool_through_mcp(mcp_instance, tool_name, arguments):
102102
if hasattr(result, "root"):
103103
result = result.root
104104
if hasattr(result, "structuredContent") and result.structuredContent:
105-
return result.structuredContent
106-
if hasattr(result, "content") and result.content:
107-
text = result.content[0].text
108-
try:
109-
return json.loads(text)
110-
except (json.JSONDecodeError, TypeError):
111-
return text
112-
return result
105+
result = result.structuredContent
106+
elif hasattr(result, "content"):
107+
if result.content:
108+
text = result.content[0].text
109+
try:
110+
result = json.loads(text)
111+
except (json.JSONDecodeError, TypeError):
112+
result = text
113+
else:
114+
# Empty content means None return
115+
result = None
116+
117+
# Normalize return value to consistent format
118+
# If already a dict, return as-is (tool functions return dicts directly)
119+
if isinstance(result, dict):
120+
return result
121+
122+
# Handle string "None" or "null" as actual None
123+
if isinstance(result, str) and result in ("None", "null"):
124+
result = None
125+
126+
# Wrap primitive values (int, str, bool, None) in dict format for consistency
127+
return {"result": result}
113128

114129

115130
async def call_tool_through_mcp_async(mcp_instance, tool_name, arguments):
@@ -127,14 +142,29 @@ async def call_tool_through_mcp_async(mcp_instance, tool_name, arguments):
127142
if hasattr(result, "root"):
128143
result = result.root
129144
if hasattr(result, "structuredContent") and result.structuredContent:
130-
return result.structuredContent
131-
if hasattr(result, "content") and result.content:
132-
text = result.content[0].text
133-
try:
134-
return json.loads(text)
135-
except (json.JSONDecodeError, TypeError):
136-
return text
137-
return result
145+
result = result.structuredContent
146+
elif hasattr(result, "content"):
147+
if result.content:
148+
text = result.content[0].text
149+
try:
150+
result = json.loads(text)
151+
except (json.JSONDecodeError, TypeError):
152+
result = text
153+
else:
154+
# Empty content means None return
155+
result = None
156+
157+
# Normalize return value to consistent format
158+
# If already a dict, return as-is (tool functions return dicts directly)
159+
if isinstance(result, dict):
160+
return result
161+
162+
# Handle string "None" or "null" as actual None
163+
if isinstance(result, str) and result in ("None", "null"):
164+
result = None
165+
166+
# Wrap primitive values (int, str, bool, None) in dict format for consistency
167+
return {"result": result}
138168

139169

140170
def call_prompt_through_mcp(mcp_instance, prompt_name, arguments=None):
@@ -710,7 +740,15 @@ def read_file(path: str):
710740
return "file contents"
711741

712742
with start_transaction(name="fastmcp tx"):
713-
result = call_resource_through_mcp(mcp, "file:///test.txt")
743+
try:
744+
result = call_resource_through_mcp(mcp, "file:///test.txt")
745+
except ValueError as e:
746+
# Older FastMCP versions may not support this URI pattern
747+
if "Unknown resource" in str(e):
748+
pytest.skip(
749+
f"Resource URI not supported in this FastMCP version: {e}"
750+
)
751+
raise
714752

715753
# Resource content is returned as-is
716754
assert "file contents" in result.contents[0].text
@@ -759,9 +797,17 @@ async def read_url(resource: str):
759797
return "resource data"
760798

761799
with start_transaction(name="fastmcp tx"):
762-
result = await call_resource_through_mcp_async(
763-
mcp, "https://example.com/resource"
764-
)
800+
try:
801+
result = await call_resource_through_mcp_async(
802+
mcp, "https://example.com/resource"
803+
)
804+
except ValueError as e:
805+
# Older FastMCP versions may not support this URI pattern
806+
if "Unknown resource" in str(e):
807+
pytest.skip(
808+
f"Resource URI not supported in this FastMCP version: {e}"
809+
)
810+
raise
765811

766812
assert "resource data" in result.contents[0].text
767813

@@ -1076,21 +1122,8 @@ def none_return_tool(action: str) -> None:
10761122
with start_transaction(name="fastmcp tx"):
10771123
result = call_tool_through_mcp(mcp, "none_return_tool", {"action": "log"})
10781124

1079-
# Handle different return types between mcp.server.fastmcp and fastmcp
1080-
if isinstance(result, dict):
1081-
# mcp.server.fastmcp wraps in dict
1082-
assert result["result"] is None
1083-
elif hasattr(result, "content"):
1084-
# fastmcp package returns CallToolResult directly
1085-
# For None returns, content is empty or contains null/None
1086-
if result.content:
1087-
assert result.content[0].text in ("null", "None", "")
1088-
else:
1089-
# Empty content means None
1090-
assert result.content == []
1091-
else:
1092-
# Some versions might return None directly
1093-
assert result is None
1125+
# Helper function normalizes to {"result": value} format
1126+
assert result["result"] is None
10941127

10951128
(tx,) = events
10961129
assert tx["type"] == "transaction"

0 commit comments

Comments
 (0)