mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-13 09:09:10 +02:00
91 lines
3 KiB
Python
91 lines
3 KiB
Python
"""Tests for the ResourcesAsTools plugin wrapper.
|
|
|
|
Transform behavior is covered by `test_resources_as_tools.py`. This file
|
|
only covers plugin-layer concerns — config validation, meta derivation,
|
|
and the deprecation shim at the old import path.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import warnings
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from fastmcp import Client, FastMCP
|
|
from fastmcp.server.plugins.resources_as_tools import (
|
|
ResourcesAsTools,
|
|
ResourcesAsToolsConfig,
|
|
)
|
|
|
|
|
|
class TestResourcesAsToolsConfig:
|
|
def test_config_generic_binding(self):
|
|
assert ResourcesAsTools._config_cls is ResourcesAsToolsConfig
|
|
|
|
def test_unknown_config_key_rejected(self):
|
|
with pytest.raises((ValidationError, Exception), match="forbid|extra"):
|
|
ResourcesAsToolsConfig(not_a_real_option=True) # ty: ignore[unknown-argument]
|
|
|
|
def test_default_meta(self):
|
|
assert ResourcesAsTools.meta.name == "resources-as-tools"
|
|
assert ResourcesAsTools.meta.version is None
|
|
|
|
|
|
class TestResourcesAsToolsPluginRegistration:
|
|
async def test_plugin_registers_synthetic_tools(self):
|
|
mcp = FastMCP("t", plugins=[ResourcesAsTools()])
|
|
|
|
@mcp.resource("test://hello")
|
|
def hello() -> str:
|
|
return "world"
|
|
|
|
async with Client(mcp) as c:
|
|
tools = await c.list_tools()
|
|
names = {t.name for t in tools}
|
|
|
|
assert {"list_resources", "read_resource"}.issubset(names)
|
|
|
|
|
|
class TestDeprecationShim:
|
|
def test_old_path_emits_deprecation_warning(self):
|
|
import importlib
|
|
import sys
|
|
|
|
from fastmcp.exceptions import FastMCPDeprecationWarning
|
|
|
|
sys.modules.pop("fastmcp.server.transforms.resources_as_tools", None)
|
|
|
|
with warnings.catch_warnings(record=True) as caught:
|
|
warnings.simplefilter("always")
|
|
importlib.import_module("fastmcp.server.transforms.resources_as_tools")
|
|
|
|
fastmcp_deprecations = [
|
|
w for w in caught if issubclass(w.category, FastMCPDeprecationWarning)
|
|
]
|
|
assert any(
|
|
"plugins.resources_as_tools" in str(w.message) for w in fastmcp_deprecations
|
|
), (
|
|
f"expected FastMCPDeprecationWarning pointing at plugins.resources_as_tools, "
|
|
f"got {[(w.category.__name__, str(w.message)) for w in caught]}"
|
|
)
|
|
|
|
async def test_legacy_add_transform_pattern_still_works(self):
|
|
from fastmcp.exceptions import FastMCPDeprecationWarning
|
|
|
|
with warnings.catch_warnings():
|
|
warnings.simplefilter("ignore", FastMCPDeprecationWarning)
|
|
from fastmcp.server.transforms.resources_as_tools import (
|
|
ResourcesAsTools as OldResourcesAsTools,
|
|
)
|
|
|
|
mcp = FastMCP("legacy")
|
|
|
|
@mcp.resource("test://hello")
|
|
def hello() -> str:
|
|
return "world"
|
|
|
|
mcp.add_transform(OldResourcesAsTools(mcp))
|
|
|
|
tools = await mcp.list_tools(run_middleware=False)
|
|
assert {"list_resources", "read_resource"}.issubset({t.name for t in tools})
|