mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
187 lines
5.5 KiB
Python
187 lines
5.5 KiB
Python
"""Tests for knowledge sync service."""
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
from pathlib import Path
|
|
from typing import AsyncGenerator
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from basic_memory.services.sync.knowledge_sync_service import KnowledgeSyncService
|
|
from basic_memory.services import KnowledgeService, FileChangeScanner
|
|
from basic_memory.markdown import KnowledgeParser
|
|
from basic_memory.utils.file_utils import compute_checksum
|
|
|
|
|
|
|
|
pytestmark = pytest.mark.skip("Knowledge sync WIP")
|
|
|
|
@pytest_asyncio.fixture
|
|
async def knowledge_sync_service(
|
|
file_sync_service: FileChangeScanner, # from conftest
|
|
knowledge_service: KnowledgeService, # from conftest
|
|
knowledge_parser: KnowledgeParser # need to add to conftest
|
|
) -> KnowledgeSyncService:
|
|
"""Create knowledge sync service for testing."""
|
|
return KnowledgeSyncService(file_sync_service, knowledge_service, knowledge_parser)
|
|
|
|
|
|
async def create_test_entity_file(
|
|
path: Path,
|
|
entity_type: str = "test",
|
|
name: str = "Test Entity",
|
|
content: str = "test content"
|
|
) -> None:
|
|
"""Create a test entity file with frontmatter."""
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Create basic entity markdown
|
|
file_content = f"""---
|
|
type: {entity_type}
|
|
id: {entity_type}/{name.lower().replace(' ', '_')}
|
|
created: 2024-12-27T10:00:00Z
|
|
modified: 2024-12-27T10:00:00Z
|
|
tags: [test]
|
|
---
|
|
|
|
# {name}
|
|
|
|
{content}
|
|
|
|
## Observations
|
|
- [test] First observation #test
|
|
- [test] Second observation #test
|
|
|
|
## Relations
|
|
- relates_to [[Other_Entity]]
|
|
"""
|
|
path.write_text(file_content)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sync_new_entity(
|
|
knowledge_sync_service: KnowledgeSyncService,
|
|
test_config,
|
|
):
|
|
"""Test syncing a new entity file."""
|
|
knowledge_dir = test_config.knowledge_dir
|
|
test_file = knowledge_dir / "test" / "test_entity.md"
|
|
|
|
# Create test file
|
|
await create_test_entity_file(test_file)
|
|
|
|
# Run sync
|
|
changes = await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Verify changes
|
|
assert len(changes.new) == 1
|
|
assert "test/test_entity.md" in changes.new
|
|
|
|
# Verify entity in DB
|
|
entity = await knowledge_sync_service.knowledge_service.get_entity_by_path_id("test/test_entity")
|
|
assert entity.name == "Test Entity"
|
|
assert entity.entity_type == "test"
|
|
assert len(entity.observations) == 2
|
|
assert len(entity.outbound_relations) == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sync_modified_entity(
|
|
knowledge_sync_service: KnowledgeSyncService,
|
|
test_config,
|
|
entity_repository,
|
|
):
|
|
"""Test syncing a modified entity file."""
|
|
knowledge_dir = test_config.knowledge_dir
|
|
test_file = knowledge_dir / "test" / "test_entity.md"
|
|
|
|
# Create initial file and sync
|
|
await create_test_entity_file(test_file)
|
|
await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Modify file
|
|
await create_test_entity_file(
|
|
test_file,
|
|
content="modified content",
|
|
name="Test Entity" # Keep same name/path
|
|
)
|
|
|
|
# Run sync again
|
|
changes = await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Verify changes
|
|
assert len(changes.modified) == 1
|
|
assert "test/test_entity.md" in changes.modified
|
|
|
|
# Verify entity updated
|
|
entity = await knowledge_sync_service.knowledge_service.get_entity_by_path_id("test/test_entity")
|
|
assert "modified content" in entity.description
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sync_moved_entity(
|
|
knowledge_sync_service: KnowledgeSyncService,
|
|
test_config,
|
|
entity_repository
|
|
):
|
|
"""Test syncing a moved entity file."""
|
|
knowledge_dir = test_config.knowledge_dir
|
|
original_file = knowledge_dir / "test" / "original.md"
|
|
new_file = knowledge_dir / "test" / "moved.md"
|
|
|
|
# Create initial file and sync
|
|
await create_test_entity_file(original_file, name="Original")
|
|
await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Create new file with same content
|
|
new_file.parent.mkdir(parents=True, exist_ok=True)
|
|
await create_test_entity_file(new_file, name="Moved")
|
|
original_file.unlink()
|
|
|
|
# Run sync
|
|
changes = await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Verify changes
|
|
assert len(changes.moved) == 1
|
|
assert "test/moved.md" in changes.moved
|
|
assert changes.moved["test/moved.md"].moved_from == "test/original.md"
|
|
|
|
# Verify entity updated
|
|
with pytest.raises(Exception):
|
|
# Original should be gone
|
|
await knowledge_sync_service.knowledge_service.get_entity_by_path_id("test/original")
|
|
|
|
# New entity should exist
|
|
entity = await knowledge_sync_service.knowledge_service.get_entity_by_path_id("test/moved")
|
|
assert entity.name == "Moved"
|
|
assert len(entity.observations) == 2
|
|
assert len(entity.outbound_relations) == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sync_deleted_entity(
|
|
knowledge_sync_service: KnowledgeSyncService,
|
|
test_config,
|
|
entity_repository
|
|
):
|
|
"""Test syncing a deleted entity file."""
|
|
knowledge_dir = test_config.knowledge_dir
|
|
test_file = knowledge_dir / "test" / "to_delete.md"
|
|
|
|
# Create initial file and sync
|
|
await create_test_entity_file(test_file)
|
|
await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Delete file
|
|
test_file.unlink()
|
|
|
|
# Run sync
|
|
changes = await knowledge_sync_service.sync(knowledge_dir)
|
|
|
|
# Verify changes
|
|
assert len(changes.deleted) == 1
|
|
assert "test/to_delete.md" in changes.deleted
|
|
|
|
# Verify entity deleted
|
|
with pytest.raises(Exception):
|
|
await knowledge_sync_service.knowledge_service.get_entity_by_path_id("test/to_delete") |