mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
get tests working again for entity.id int
This commit is contained in:
@@ -32,7 +32,7 @@ async def test_create_single_entity(app):
|
||||
assert entity.entity_type == "test"
|
||||
assert len(entity.observations) == 1
|
||||
assert entity.observations[0].content == "Test observation"
|
||||
assert entity.id == "test/singletest"
|
||||
assert entity.id is not None
|
||||
|
||||
# Verify entity can be found via search
|
||||
search_result = await handle_call_tool("search_nodes", {"query": "SingleTest"})
|
||||
@@ -68,9 +68,9 @@ async def test_create_multiple_entities(app):
|
||||
assert "BulkTest3" in entities
|
||||
|
||||
# Verify IDs were generated correctly
|
||||
assert entities["BulkTest1"].id == "test/bulktest1"
|
||||
assert entities["BulkTest2"].id == "test/bulktest2"
|
||||
assert entities["BulkTest3"].id == "demo/bulktest3"
|
||||
assert entities["BulkTest1"].id is not None
|
||||
assert entities["BulkTest2"].id is not None
|
||||
assert entities["BulkTest3"].id is not None
|
||||
|
||||
# Verify observations were saved
|
||||
assert len(entities["BulkTest1"].observations) == 1
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import pytest
|
||||
|
||||
from basic_memory.mcp.server import handle_call_tool
|
||||
from basic_memory.schemas import SearchNodesResponse
|
||||
from basic_memory.schemas import SearchNodesResponse, CreateEntityResponse
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -17,14 +17,19 @@ async def test_create_relations(app):
|
||||
]
|
||||
}
|
||||
|
||||
await handle_call_tool("create_entities", entity_data)
|
||||
create_entity_result = await handle_call_tool("create_entities", entity_data)
|
||||
create_entity_response = CreateEntityResponse.model_validate_json(
|
||||
create_entity_result[0].resource.text # pyright: ignore [reportAttributeAccessIssue]
|
||||
)
|
||||
|
||||
from_entity = create_entity_response.entities[0]
|
||||
to_entity = create_entity_response.entities[1]
|
||||
# Create relation between them
|
||||
relation_data = {
|
||||
"relations": [
|
||||
{
|
||||
"from_id": "test/TestEntityA",
|
||||
"to_id": "test/TestEntityB",
|
||||
"from_id": from_entity.id,
|
||||
"to_id": to_entity.id,
|
||||
"relation_type": "relates_to",
|
||||
}
|
||||
]
|
||||
@@ -39,5 +44,5 @@ async def test_create_relations(app):
|
||||
assert len(response.matches) == 1
|
||||
entity = response.matches[0]
|
||||
assert len(entity.relations) == 1
|
||||
assert entity.relations[0].to_id == "test/testentityb"
|
||||
assert entity.relations[0].to_id == to_entity.id
|
||||
assert entity.relations[0].relation_type == "relates_to"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import pytest
|
||||
|
||||
from basic_memory.mcp.server import handle_call_tool
|
||||
from basic_memory.schemas import SearchNodesResponse
|
||||
from basic_memory.schemas import SearchNodesResponse, CreateEntityResponse
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -16,10 +16,15 @@ async def test_delete_entities(app):
|
||||
{"name": "DeleteTest2", "entity_type": "test", "observations": ["To be deleted 2"]},
|
||||
]
|
||||
}
|
||||
await handle_call_tool("create_entities", entities)
|
||||
create_entity_result = await handle_call_tool("create_entities", entities)
|
||||
create_entity_response = CreateEntityResponse.model_validate_json(
|
||||
create_entity_result[0].resource.text # pyright: ignore [reportAttributeAccessIssue]
|
||||
)
|
||||
|
||||
# Delete first entity
|
||||
await handle_call_tool("delete_entities", {"entity_ids": ["test/deletetest1"]})
|
||||
await handle_call_tool(
|
||||
"delete_entities", {"entity_ids": [create_entity_response.entities[0].id]}
|
||||
)
|
||||
|
||||
# Verify through search
|
||||
search_result = await handle_call_tool("search_nodes", {"query": "DeleteTest"})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import pytest
|
||||
|
||||
from basic_memory.mcp.server import handle_call_tool
|
||||
from basic_memory.schemas import SearchNodesResponse
|
||||
from basic_memory.schemas import SearchNodesResponse, CreateEntityResponse
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -16,14 +16,19 @@ async def test_delete_relations(app):
|
||||
{"name": "RelTarget", "entity_type": "test", "observations": ["Target entity"]},
|
||||
]
|
||||
}
|
||||
await handle_call_tool("create_entities", entities)
|
||||
create_entity_result = await handle_call_tool("create_entities", entities)
|
||||
create_entity_response = CreateEntityResponse.model_validate_json(
|
||||
create_entity_result[0].resource.text # pyright: ignore [reportAttributeAccessIssue]
|
||||
)
|
||||
from_entity = create_entity_response.entities[0]
|
||||
to_entity = create_entity_response.entities[1]
|
||||
|
||||
# Create relation
|
||||
relation = {
|
||||
"relations": [
|
||||
{
|
||||
"from_id": "test/relsource",
|
||||
"to_id": "test/reltarget",
|
||||
"from_id": from_entity.id,
|
||||
"to_id": to_entity.id,
|
||||
"relation_type": "relates_to",
|
||||
}
|
||||
]
|
||||
@@ -36,8 +41,8 @@ async def test_delete_relations(app):
|
||||
{
|
||||
"relations": [
|
||||
{
|
||||
"from_id": "test/relsource",
|
||||
"to_id": "test/reltarget",
|
||||
"from_id": from_entity.id,
|
||||
"to_id": to_entity.id,
|
||||
"relation_type": "relates_to",
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,7 +5,6 @@ from mcp.shared.exceptions import McpError
|
||||
from mcp.types import INVALID_PARAMS
|
||||
|
||||
from basic_memory.mcp.server import handle_call_tool
|
||||
from basic_memory.schemas import CreateEntityResponse, SearchNodesResponse
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -80,7 +79,7 @@ async def test_invalid_relation_format_to_id(app):
|
||||
{
|
||||
"relations": [
|
||||
{
|
||||
"from_id": "test/entity1",
|
||||
"from_id": 1,
|
||||
# Missing to_id
|
||||
"relation_type": "relates_to",
|
||||
}
|
||||
@@ -99,8 +98,8 @@ async def test_invalid_relation_format_relation_type(app):
|
||||
{
|
||||
"relations": [
|
||||
{
|
||||
"from_id": "test/entity1",
|
||||
"to_id": "test/entity2",
|
||||
"from_id": 1,
|
||||
"to_id": 2,
|
||||
"relation_type": "", # Empty relation type
|
||||
}
|
||||
]
|
||||
@@ -117,7 +116,7 @@ async def test_observation_validation_len(app):
|
||||
await handle_call_tool(
|
||||
"add_observations",
|
||||
{
|
||||
"entity_id": "test/entity1",
|
||||
"entity_id": 1,
|
||||
"observations": ["", ""], # Empty observations
|
||||
},
|
||||
)
|
||||
@@ -131,7 +130,7 @@ async def test_observation_validation_delete(app):
|
||||
await handle_call_tool(
|
||||
"delete_observations",
|
||||
{
|
||||
"entity_id": "test/entity1",
|
||||
"entity_id": 1,
|
||||
"deletions": [], # Empty deletions
|
||||
},
|
||||
)
|
||||
@@ -147,58 +146,3 @@ async def test_edge_case_validation_search_len(app):
|
||||
"search_nodes",
|
||||
{"query": "x" * 10000}, # Extremely long query
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_edge_case_validation_name_sanitization(app):
|
||||
"""Test that entity names are properly sanitized for IDs."""
|
||||
# Test cases for different sanitization scenarios
|
||||
test_cases = [
|
||||
{
|
||||
"name": "🧪 FOO & File (1)", # Emoji and special chars
|
||||
"expected_id": "test/foo_file_1",
|
||||
},
|
||||
{
|
||||
"name": "BARR Multiple Spaces", # Multiple spaces
|
||||
"expected_id": "test/barr_multiple_spaces",
|
||||
},
|
||||
{
|
||||
"name": "LOTSOF@#$Special&*Chars", # Special characters
|
||||
"expected_id": "test/lotsofspecialchars",
|
||||
},
|
||||
{
|
||||
"name": "\x00null", # Null byte
|
||||
"expected_id": "test/null",
|
||||
},
|
||||
{
|
||||
"name": "\nline", # Newline
|
||||
"expected_id": "test/line",
|
||||
},
|
||||
]
|
||||
|
||||
for test in test_cases:
|
||||
result = await handle_call_tool(
|
||||
"create_entities",
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"name": test["name"],
|
||||
"entity_type": "test",
|
||||
"observations": [],
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
response = CreateEntityResponse.model_validate_json(result[0].resource.text) # pyright: ignore [reportAttributeAccessIssue]
|
||||
entity = response.entities[0]
|
||||
|
||||
# Original name should be preserved
|
||||
assert entity.name == test["name"]
|
||||
# ID should be sanitized
|
||||
assert entity.id == test["expected_id"]
|
||||
|
||||
# Verify we can find it with original name
|
||||
search_result = await handle_call_tool("search_nodes", {"query": test["name"]})
|
||||
search_response = SearchNodesResponse.model_validate_json(search_result[0].resource.text) # pyright: ignore [reportAttributeAccessIssue]
|
||||
assert len(search_response.matches) > 0
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
from mcp.types import EmbeddedResource
|
||||
|
||||
from basic_memory.mcp.server import MIME_TYPE, handle_call_tool
|
||||
from basic_memory.schemas import OpenNodesResponse
|
||||
from basic_memory.schemas import OpenNodesResponse, CreateEntityResponse
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -31,12 +31,15 @@ async def test_open_nodes(app):
|
||||
]
|
||||
}
|
||||
|
||||
await handle_call_tool("create_entities", entity_data)
|
||||
create_entity_result = await handle_call_tool("create_entities", entity_data)
|
||||
create_entity_response = CreateEntityResponse.model_validate_json(
|
||||
create_entity_result[0].resource.text # pyright: ignore [reportAttributeAccessIssue]
|
||||
)
|
||||
entity_a = create_entity_response.entities[0]
|
||||
entity_b = create_entity_response.entities[1]
|
||||
|
||||
# Open specific nodes
|
||||
result = await handle_call_tool(
|
||||
"open_nodes", {"entity_ids": ["test/opentesta", "test/opentestb"]}
|
||||
)
|
||||
result = await handle_call_tool("open_nodes", {"entity_ids": [entity_a.id, entity_b.id]})
|
||||
|
||||
# Verify response format
|
||||
assert len(result) == 1
|
||||
@@ -54,7 +57,7 @@ async def test_open_nodes(app):
|
||||
|
||||
# Verify entity content
|
||||
entity = response.entities[0]
|
||||
assert entity.id == "test/opentesta"
|
||||
assert entity.id == entity_a.id
|
||||
assert entity.entity_type == "test"
|
||||
assert len(entity.observations) == 1
|
||||
assert entity.observations[0].content == "First test entity"
|
||||
|
||||
@@ -97,11 +97,11 @@ def test_entity_out_from_attributes():
|
||||
"description": "test description",
|
||||
"observations": [{"id": 1, "content": "test obs", "context": None}],
|
||||
"relations": [
|
||||
{"id": 1, "from_id": "123", "to_id": "456", "relation_type": "test", "context": None}
|
||||
{"id": 1, "from_id": 123, "to_id": 456, "relation_type": "test", "context": None}
|
||||
],
|
||||
}
|
||||
entity = EntityResponse.model_validate(db_data)
|
||||
assert entity.id == "123"
|
||||
assert entity.id == 123
|
||||
assert entity.description == "test description"
|
||||
assert len(entity.observations) == 1
|
||||
assert entity.observations[0].id == 1
|
||||
|
||||
Reference in New Issue
Block a user