test_server.pyā¢5.85 kB
"""Tests for the analysis MCP server (LLM-Orchestrator Pattern)."""
import pytest
from analysis_mcp.server import _apply_lens, _compare_positions, _deconstruct_claim, _get_trace, mcp
class TestDeconstructClaim:
"""Test the deconstruct_claim tool (orchestrator pattern)."""
def test_basic_claim(self):
"""Test with a simple claim."""
result = _deconstruct_claim("AI will replace all human jobs")
# Verify orchestrator pattern output
assert "trace_id" in result
assert result["trace_id"].startswith("deconstruct-")
assert "outline" in result
assert "next_prompt" in result
# Verify outline structure
assert result["outline"]["claim"] == "AI will replace all human jobs"
assert "analysis_sections" in result["outline"]
# Verify next_prompt contains key elements
assert "TASK:" in result["next_prompt"]
assert "CONTENT:" in result["next_prompt"]
assert "ASSUMPTIONS" in result["next_prompt"]
def test_empty_claim(self):
"""Test with empty claim."""
result = _deconstruct_claim("")
assert "trace_id" in result
assert result["outline"]["claim"] == ""
def test_complex_claim(self):
"""Test with a complex multi-part claim."""
claim = "Climate change is both a technological and political problem requiring immediate action"
result = _deconstruct_claim(claim)
assert claim in result["next_prompt"]
assert "trace_id" in result
class TestComparePositions:
"""Test the compare_positions tool (orchestrator pattern)."""
def test_default_positions(self):
"""Test with default perspectives."""
result = _compare_positions("Universal basic income")
# Verify orchestrator pattern output
assert "trace_id" in result
assert result["trace_id"].startswith("compare-")
assert "outline" in result
assert "next_prompt" in result
# Verify outline structure
assert result["outline"]["topic"] == "Universal basic income"
assert len(result["outline"]["perspectives"]) == 5
assert "progressive" in result["outline"]["perspectives"]
# Verify next_prompt structure
assert "TASK:" in result["next_prompt"]
assert "progressive" in result["next_prompt"]
def test_custom_positions(self):
"""Test with custom perspectives."""
custom = ["marxist", "libertarian", "feminist"]
result = _compare_positions("Labor unions", positions=custom)
assert result["outline"]["perspectives"] == custom
assert all(pos in result["next_prompt"] for pos in custom)
assert "trace_id" in result
def test_single_position(self):
"""Test with just one position."""
result = _compare_positions("Tax policy", positions=["neoliberal"])
assert len(result["outline"]["perspectives"]) == 1
assert "neoliberal" in result["next_prompt"]
class TestApplyLens:
"""Test the apply_lens tool (orchestrator pattern)."""
@pytest.mark.parametrize("lens", [
"historical", "economic", "geopolitical", "psychological",
"technological", "sociocultural", "philosophical", "systems", "media"
])
def test_valid_lenses(self, lens):
"""Test all valid lens types."""
result = _apply_lens("New AI regulation passed", lens)
# Verify orchestrator pattern output
assert "trace_id" in result
assert result["trace_id"].startswith(f"lens-{lens}-")
assert "outline" in result
assert "next_prompt" in result
assert "error" not in result
# Verify outline structure
assert result["outline"]["lens"] == lens
assert result["outline"]["event"] == "New AI regulation passed"
def test_invalid_lens(self):
"""Test with invalid lens type."""
result = _apply_lens("Some event", "invalid_lens")
assert "error" in result
assert "Invalid lens" in result["error"]
assert "trace_id" not in result
def test_historical_lens_content(self):
"""Test that historical lens includes appropriate prompts."""
result = _apply_lens("Tech bubble burst", "historical")
assert "historical precedents" in result["next_prompt"].lower() or "historical" in result["next_prompt"].lower()
assert "TASK:" in result["next_prompt"]
def test_economic_lens_content(self):
"""Test that economic lens includes appropriate prompts."""
result = _apply_lens("Trade war", "economic")
assert "economic" in result["next_prompt"].lower()
assert "TASK:" in result["next_prompt"]
class TestGetTrace:
"""Test the get_trace tool."""
def test_retrieve_trace(self):
"""Test retrieving a stored trace."""
# Create a trace first
result = _deconstruct_claim("Test claim")
trace_id = result["trace_id"]
# Retrieve it
trace = _get_trace(trace_id)
assert trace["found"] is True
assert trace["trace_id"] == trace_id
assert "data" in trace
assert trace["data"]["tool"] == "deconstruct_claim"
def test_nonexistent_trace(self):
"""Test retrieving a nonexistent trace."""
result = _get_trace("nonexistent-12345-abcde")
assert "error" in result
assert "not found" in result["error"].lower()
class TestMCPServer:
"""Test the MCP server configuration."""
def test_server_name(self):
"""Test server is properly named."""
assert mcp.name == "analysis-mcp"
def test_tools_registered(self):
"""Test that all tools are registered."""
# FastMCP should have our tools registered
# This is a basic check that the server object exists
assert mcp is not None