Files
basicmachines-co-basic-memory/tests/test_entity_service.py
T
2024-12-11 19:49:34 -06:00

233 lines
7.7 KiB
Python

"""Tests for EntityService."""
import pytest
from basic_memory.fileio import EntityNotFoundError
from basic_memory.models import Entity
from basic_memory.schemas import EntityIn
pytestmark = pytest.mark.asyncio
async def test_create_entity_success(entity_service):
"""Test successful entity creation."""
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="A test entity description"
)
# Act
entity = await entity_service.create_entity(entity_data)
# Assert Entity
assert isinstance(entity, Entity)
assert entity.name == "Test Entity"
assert entity.entity_type == "test"
assert entity.description == "A test entity description"
assert entity.created_at is not None
# Verify we can retrieve it
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description == "A test entity description"
async def test_get_by_type_and_name(entity_service):
"""Test finding entity by type and name combination."""
# Create two entities with same name but different types
entity1_data = EntityIn(
name="Test Entity",
entity_type="type1",
description="First test entity"
)
entity1 = await entity_service.create_entity(entity1_data)
entity2_data = EntityIn(
name="Test Entity", # Same name
entity_type="type2", # Different type
description="Second test entity"
)
entity2 = await entity_service.create_entity(entity2_data)
# Find by type1 and name
found = await entity_service.get_by_type_and_name("type1", "Test Entity")
assert found is not None
assert found.id == entity1.id
assert found.entity_type == "type1"
assert found.description == "First test entity"
# Find by type2 and name
found = await entity_service.get_by_type_and_name("type2", "Test Entity")
assert found is not None
assert found.id == entity2.id
assert found.entity_type == "type2"
assert found.description == "Second test entity"
# Test not found case
with pytest.raises(EntityNotFoundError):
await entity_service.get_by_type_and_name("nonexistent", "Test Entity")
async def test_create_entity_no_description(entity_service):
"""Test creating entity without description (should be None)."""
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
)
entity = await entity_service.create_entity(entity_data)
assert entity.description is None
# Verify after retrieval
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description is None
async def test_get_entity_success(entity_service):
"""Test successful entity retrieval."""
# Arrange
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="Test description"
)
created = await entity_service.create_entity(entity_data)
# Act
retrieved = await entity_service.get_entity(created.id)
# Assert
assert isinstance(retrieved, Entity)
assert retrieved.id == created.id
assert retrieved.name == created.name
assert retrieved.entity_type == created.entity_type
assert retrieved.description == "Test description"
# relations are tested in test_memory_service
async def test_update_entity_description(entity_service):
"""Test updating an entity's description."""
# Create entity with description
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="Initial description"
)
entity = await entity_service.create_entity(entity_data)
# Update description
updated = await entity_service.update_entity(entity.id, {"description": "Updated description"})
assert updated.description == "Updated description"
# Verify after retrieval
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description == "Updated description"
async def test_update_entity_description_to_none(entity_service):
"""Test updating an entity's description to None."""
# Create entity with description
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="Initial description"
)
entity = await entity_service.create_entity(entity_data)
# Update description to None
updated = await entity_service.update_entity(entity.id, {"description": None})
assert updated.description is None
# Verify after retrieval
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description is None
async def test_delete_entity_success(entity_service):
"""Test successful entity deletion."""
# Arrange
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
)
entity = await entity_service.create_entity(entity_data)
# Act
result = await entity_service.delete_entity(entity.id)
# Assert
assert result is True
with pytest.raises(EntityNotFoundError):
await entity_service.get_entity(entity.id)
# Error Path Tests
async def test_get_entity_not_found(entity_service):
"""Test handling of non-existent entity retrieval."""
with pytest.raises(EntityNotFoundError):
await entity_service.get_entity("nonexistent-id")
async def test_create_entity_db_error(entity_service, monkeypatch):
"""Test handling of database errors during creation."""
# Arrange - make db operations fail
async def mock_create(*args, **kwargs):
raise Exception("Mock DB error")
monkeypatch.setattr(entity_service.entity_repo, "create", mock_create)
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="Test description"
)
# Act/Assert
with pytest.raises(Exception, match="Mock DB error"):
await entity_service.create_entity(entity_data)
async def test_delete_nonexistent_entity(entity_service):
"""Test deleting an entity that doesn't exist."""
await entity_service.delete_entity("nonexistent-id")
# If we get here, the deletion succeeded or failed silently as expected
# Edge Cases
async def test_create_entity_with_special_chars(entity_service):
"""Test entity creation with special characters in name and description."""
name = "Test & Entity! With @ Special #Chars"
description = "Description with $pecial chars & symbols!"
entity_data = EntityIn(
name=name,
entity_type="test",
description=description
)
entity = await entity_service.create_entity(entity_data)
assert entity.name == name
assert entity.description == description
# Verify after retrieval
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description == description
async def test_entity_id_generation(entity_service):
"""Test that entities get unique IDs generated correctly."""
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description="Test description",
observations=[]
)
entity = await entity_service.create_entity(entity_data)
assert entity.id # ID should be generated
assert "test/test_entity" == entity.id # Should contain normalized name
async def test_create_entity_long_description(entity_service):
"""Test creating entity with a long description."""
long_description = "A" * 1000 # 1000 character description
entity_data = EntityIn(
name="Test Entity",
entity_type="test",
description=long_description
)
entity = await entity_service.create_entity(entity_data)
assert entity.description == long_description
# Verify after retrieval
retrieved = await entity_service.get_entity(entity.id)
assert retrieved.description == long_description