mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
4aa0cbdd62
Signed-off-by: phernandez <paul@basicmachines.co>
170 lines
5.4 KiB
Python
170 lines
5.4 KiB
Python
"""Integration tests for MCP tools accepting string-serialized list/dict params.
|
|
|
|
Goes through the full FastMCP Client → validate_call → tool function path,
|
|
which is where Pydantic rejects strings for list/dict params.
|
|
"""
|
|
|
|
import pytest
|
|
from fastmcp import Client
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_notes_entity_types_as_string(mcp_server, app, test_project):
|
|
"""search_notes should accept entity_types as a JSON string via MCP protocol."""
|
|
async with Client(mcp_server) as client:
|
|
await client.call_tool(
|
|
"write_note",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "Entity Type Coerce Test",
|
|
"directory": "test",
|
|
"content": "# Test\nContent for entity type coercion",
|
|
},
|
|
)
|
|
|
|
# MCP client sends entity_types as a string
|
|
result = await client.call_tool(
|
|
"search_notes",
|
|
{
|
|
"project": test_project.name,
|
|
"query": "coercion",
|
|
"search_type": "text",
|
|
"entity_types": '["entity"]',
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Search Failed" not in text
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_notes_note_types_as_string(mcp_server, app, test_project):
|
|
"""search_notes should accept note_types as a JSON string via MCP protocol."""
|
|
async with Client(mcp_server) as client:
|
|
await client.call_tool(
|
|
"write_note",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "Note Type Coerce Test",
|
|
"directory": "test",
|
|
"content": "# Test\nContent for note type coercion",
|
|
},
|
|
)
|
|
|
|
result = await client.call_tool(
|
|
"search_notes",
|
|
{
|
|
"project": test_project.name,
|
|
"query": "coercion",
|
|
"search_type": "text",
|
|
"note_types": '["note"]',
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Search Failed" not in text
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_notes_tags_as_string(mcp_server, app, test_project):
|
|
"""search_notes should accept tags as a JSON string via MCP protocol."""
|
|
async with Client(mcp_server) as client:
|
|
await client.call_tool(
|
|
"write_note",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "Tags Coerce Test",
|
|
"directory": "test",
|
|
"content": "# Test\nTagged content for coercion",
|
|
"tags": "alpha",
|
|
},
|
|
)
|
|
|
|
result = await client.call_tool(
|
|
"search_notes",
|
|
{
|
|
"project": test_project.name,
|
|
"query": "tagged",
|
|
"search_type": "text",
|
|
"tags": '["alpha"]',
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Search Failed" not in text
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_notes_metadata_filters_as_string(mcp_server, app, test_project):
|
|
"""search_notes should accept metadata_filters as a JSON string via MCP protocol."""
|
|
async with Client(mcp_server) as client:
|
|
await client.call_tool(
|
|
"write_note",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "Metadata Coerce Test",
|
|
"directory": "test",
|
|
"content": "# Test\nMetadata content for coercion",
|
|
},
|
|
)
|
|
|
|
result = await client.call_tool(
|
|
"search_notes",
|
|
{
|
|
"project": test_project.name,
|
|
"query": "metadata",
|
|
"search_type": "text",
|
|
"metadata_filters": '{"type": "note"}',
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Search Failed" not in text
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_write_note_metadata_as_string(mcp_server, app, test_project):
|
|
"""write_note should accept metadata as a JSON string via MCP protocol."""
|
|
async with Client(mcp_server) as client:
|
|
result = await client.call_tool(
|
|
"write_note",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "String Metadata Note",
|
|
"directory": "test",
|
|
"content": "# Test\nWith string metadata",
|
|
"metadata": '{"priority": "high"}',
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Created note" in text or "Updated note" in text
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_canvas_nodes_edges_as_string(mcp_server, app, test_project):
|
|
"""canvas should accept nodes and edges as JSON strings via MCP protocol."""
|
|
import json
|
|
|
|
nodes = [
|
|
{
|
|
"id": "n1",
|
|
"type": "text",
|
|
"text": "Hello",
|
|
"x": 0,
|
|
"y": 0,
|
|
"width": 200,
|
|
"height": 100,
|
|
}
|
|
]
|
|
edges = [{"id": "e1", "fromNode": "n1", "toNode": "n1", "label": "self"}]
|
|
|
|
async with Client(mcp_server) as client:
|
|
result = await client.call_tool(
|
|
"canvas",
|
|
{
|
|
"project": test_project.name,
|
|
"title": "Coerce Canvas Test",
|
|
"directory": "test",
|
|
"nodes": json.dumps(nodes),
|
|
"edges": json.dumps(edges),
|
|
},
|
|
)
|
|
text = result.content[0].text
|
|
assert "Created" in text or "Updated" in text
|