forked from HomeLab/unraid-mcp
Refactor the entire tool layer to use the consolidated action pattern (action: Literal[...] with QUERIES/MUTATIONS dicts). This reduces LLM context from ~12k to ~5k tokens while adding ~60 new API capabilities. New tools: unraid_info (19 actions), unraid_array (12), unraid_notifications (9), unraid_users (8), unraid_keys (5). Rewritten: unraid_docker (15), unraid_vm (9), unraid_storage (6), unraid_rclone (4), unraid_health (3). Includes 129 tests across 10 test files, code review fixes for 16 issues (severity ordering, PrefixedID regex, sensitive var redaction, etc.). Removes tools/system.py (replaced by tools/info.py). Version bumped to 0.2.0.
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""Shared test fixtures and helpers for Unraid MCP server tests."""
|
|
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
from fastmcp import FastMCP
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_graphql_request() -> AsyncMock:
|
|
"""Fixture that patches make_graphql_request at the core module.
|
|
|
|
NOTE: Since each tool file imports make_graphql_request into its own
|
|
namespace, tool-specific tests should patch at the tool module level
|
|
(e.g., "unraid_mcp.tools.info.make_graphql_request") instead of using
|
|
this fixture. This fixture is useful for testing the core client
|
|
or for integration tests that reload modules.
|
|
"""
|
|
with patch("unraid_mcp.core.client.make_graphql_request", new_callable=AsyncMock) as mock:
|
|
yield mock
|
|
|
|
|
|
def make_tool_fn(
|
|
module_path: str,
|
|
register_fn_name: str,
|
|
tool_name: str,
|
|
) -> Any:
|
|
"""Extract a tool function from a FastMCP registration for testing.
|
|
|
|
This wraps the repeated pattern of creating a test FastMCP instance,
|
|
registering a tool, and extracting the inner function. Centralizing
|
|
this avoids reliance on FastMCP's private `_tool_manager._tools` API
|
|
in every test file.
|
|
|
|
Args:
|
|
module_path: Dotted import path to the tool module (e.g., "unraid_mcp.tools.info")
|
|
register_fn_name: Name of the registration function (e.g., "register_info_tool")
|
|
tool_name: Name of the registered tool (e.g., "unraid_info")
|
|
|
|
Returns:
|
|
The async tool function callable
|
|
"""
|
|
import importlib
|
|
|
|
module = importlib.import_module(module_path)
|
|
register_fn = getattr(module, register_fn_name)
|
|
test_mcp = FastMCP("test")
|
|
register_fn(test_mcp)
|
|
return test_mcp._tool_manager._tools[tool_name].fn
|