class _DummyMeta(dict):
def __getattr__(self, item):
try:
return self[item]
except KeyError as exc:
raise AttributeError(item) from exc
model_extra = property(lambda self: self)
def model_dump(self, exclude_none=True):
if not exclude_none:
return dict(self)
return {k: v for k, v in self.items() if v is not None}
class DummyContext:
"""Mock context object for testing"""
def __init__(self, **meta):
import uuid
self.log_info = []
self.log_warning = []
self.log_error = []
self._meta = _DummyMeta(meta)
# Give each context a unique session_id to avoid state leakage between tests
self.session_id = str(uuid.uuid4())
# Add state storage to mimic FastMCP context state
self._state = {}
class _RequestContext:
def __init__(self, meta):
self.meta = meta
self.request_context = _RequestContext(self._meta)
async def info(self, message):
self.log_info.append(message)
async def warning(self, message):
self.log_warning.append(message)
# Some code paths call warn(); treat it as an alias of warning()
async def warn(self, message):
await self.warning(message)
async def error(self, message):
self.log_error.append(message)
def set_state(self, key, value):
"""Set state value (mimics FastMCP context.set_state)"""
self._state[key] = value
def get_state(self, key, default=None):
"""Get state value (mimics FastMCP context.get_state)"""
return self._state.get(key, default)
class DummyMCP:
"""Mock MCP server for testing tool registration patterns."""
def __init__(self):
self.tools = {}
def tool(self, *args, **kwargs):
def deco(fn):
self.tools[fn.__name__] = fn
return fn
return deco
def setup_script_tools():
"""
Setup script-related tools for testing.
Returns a dict mapping tool names to their async handler functions.
Useful for testing parameter serialization and SDK behavior.
"""
mcp = DummyMCP()
# Import tools to trigger decorator-based registration
import services.tools.manage_script
from services.registry import get_registered_tools
for tool_info in get_registered_tools():
name = tool_info['name']
if any(k in name for k in ['script', 'apply_text', 'create_script',
'delete_script', 'validate_script', 'get_sha']):
mcp.tools[name] = tool_info['func']
return mcp.tools