From de4f28963b7dac847ceb5e467dc6df11d95a92d9 Mon Sep 17 00:00:00 2001 From: phernandez Date: Fri, 20 Dec 2024 18:01:55 -0600 Subject: [PATCH] commit tests for file_sync_service --- .../services/file_sync_service.py | 4 + tests/services/test_file_sync_service.py | 84 ++++++++++--------- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/basic_memory/services/file_sync_service.py b/src/basic_memory/services/file_sync_service.py index 2288efaa..6fd4d1da 100644 --- a/src/basic_memory/services/file_sync_service.py +++ b/src/basic_memory/services/file_sync_service.py @@ -63,6 +63,7 @@ class FileSyncService: try: content = path.read_text() checksum = await self.document_service.compute_checksum(content) + # Store path relative to root directory rel_path = str(path.relative_to(directory)) files[rel_path] = checksum except Exception as e: @@ -117,6 +118,7 @@ class FileSyncService: full_path = directory / path try: content = full_path.read_text() + # Use relative path for document await self.document_service.create_document(path, content) except Exception as e: raise SyncError(f"Failed to sync new file {path}: {e}") @@ -135,6 +137,7 @@ class FileSyncService: full_path = directory / path try: content = full_path.read_text() + # Use relative path for document await self.document_service.update_document(path, content) except Exception as e: raise SyncError(f"Failed to sync modified file {path}: {e}") @@ -179,6 +182,7 @@ class FileSyncService: # Process deleted files for path in changes.deleted: logger.debug(f"Processing deleted file: {path}") + # Use relative path for deletion await self.document_service.delete_document(path) logger.info("Sync completed successfully") diff --git a/tests/services/test_file_sync_service.py b/tests/services/test_file_sync_service.py index ae46c462..60145345 100644 --- a/tests/services/test_file_sync_service.py +++ b/tests/services/test_file_sync_service.py @@ -22,23 +22,24 @@ async def docs_dir(test_project_path) -> Path: @pytest_asyncio.fixture async def sample_files(docs_dir) -> dict[str, str]: - """Create some sample files for testing.""" + """Create some sample test files.""" # Create test structure design_dir = docs_dir / "design" notes_dir = docs_dir / "notes" - design_dir.mkdir() - notes_dir.mkdir() + design_dir.mkdir(exist_ok=True) + notes_dir.mkdir(exist_ok=True) + # Map of relative paths to content files = { "design/architecture.md": "# Architecture\nSome design notes", "notes/meeting.md": "# Meeting Notes\nDiscussion points", "README.md": "# Project\nOverview doc", } - # Create files - for path, content in files.items(): - file_path = docs_dir / path - file_path.write_text(content) + # Create files with full paths + for rel_path, content in files.items(): + full_path = docs_dir / rel_path + full_path.write_text(content) return files @@ -47,13 +48,13 @@ async def sample_files(docs_dir) -> dict[str, str]: async def test_scan_files(file_sync_service, docs_dir, sample_files): """Test scanning directory for files.""" scanned = await file_sync_service.scan_files(docs_dir) - + # Should find all files assert len(scanned) == len(sample_files) - - # Paths should be relative - assert all(str(docs_dir) not in path for path in scanned) - + + # Paths should be relative and match sample files + assert set(scanned.keys()) == set(sample_files.keys()) + # All files should have checksums assert all(isinstance(checksum, str) for checksum in scanned.values()) @@ -61,8 +62,10 @@ async def test_scan_files(file_sync_service, docs_dir, sample_files): @pytest.mark.asyncio async def test_find_new_files(file_sync_service, docs_dir, sample_files): """Test detecting new files.""" - changes = await file_sync_service.find_changes(await file_sync_service.scan_files(docs_dir)) - + changes = await file_sync_service.find_changes( + await file_sync_service.scan_files(docs_dir) + ) + # All files should be new assert len(changes.new) == len(sample_files) assert len(changes.modified) == 0 @@ -74,14 +77,16 @@ async def test_find_modified_files(file_sync_service, docs_dir, sample_files): """Test detecting modified files.""" # First sync to create DB records await file_sync_service.sync(docs_dir) - + # Modify a file mod_path = docs_dir / "design/architecture.md" mod_path.write_text("# Updated Architecture") - + # Check changes - changes = await file_sync_service.find_changes(await file_sync_service.scan_files(docs_dir)) - + changes = await file_sync_service.find_changes( + await file_sync_service.scan_files(docs_dir) + ) + assert len(changes.modified) == 1 assert "design/architecture.md" in changes.modified assert len(changes.new) == 0 @@ -93,14 +98,16 @@ async def test_find_deleted_files(file_sync_service, docs_dir, sample_files): """Test detecting deleted files.""" # First sync to create DB records await file_sync_service.sync(docs_dir) - + # Delete a file del_path = docs_dir / "notes/meeting.md" del_path.unlink() - + # Check changes - changes = await file_sync_service.find_changes(await file_sync_service.scan_files(docs_dir)) - + changes = await file_sync_service.find_changes( + await file_sync_service.scan_files(docs_dir) + ) + assert len(changes.deleted) == 1 assert "notes/meeting.md" in changes.deleted assert len(changes.new) == 0 @@ -113,30 +120,28 @@ async def test_full_sync_process(file_sync_service, docs_dir, sample_files): # First sync to create initial state initial_sync = await file_sync_service.sync(docs_dir) assert initial_sync.total_changes == len(sample_files) - + # Make some changes: # 1. Add new file - new_file = docs_dir / "notes/todo.md" - new_file.write_text("# TODO\n- First item") - + (docs_dir / "notes").mkdir(exist_ok=True) # Ensure parent exists + (docs_dir / "notes/todo.md").write_text("# TODO\n- First item") + # 2. Modify existing file - mod_file = docs_dir / "README.md" - mod_file.write_text("# Updated Project") - + (docs_dir / "README.md").write_text("# Updated Project") + # 3. Delete a file - del_file = docs_dir / "design/architecture.md" - del_file.unlink() - + (docs_dir / "design/architecture.md").unlink() + # Run sync changes = await file_sync_service.sync(docs_dir) - + # Verify changes assert len(changes.new) == 1 assert "notes/todo.md" in changes.new - + assert len(changes.modified) == 1 assert "README.md" in changes.modified - + assert len(changes.deleted) == 1 assert "design/architecture.md" in changes.deleted @@ -146,10 +151,10 @@ async def test_no_changes_sync(file_sync_service, docs_dir, sample_files): """Test sync when no changes are present.""" # First sync to create initial state await file_sync_service.sync(docs_dir) - + # Sync again immediately changes = await file_sync_service.sync(docs_dir) - + # Should detect no changes assert changes.total_changes == 0 @@ -168,6 +173,9 @@ async def test_error_on_unreadable_file(file_sync_service, docs_dir): bad_file = docs_dir / "bad.md" bad_file.write_text("test") bad_file.chmod(0o000) # Remove all permissions - + with pytest.raises(SyncError): await file_sync_service.sync(docs_dir) + + # Clean up + bad_file.chmod(0o666) # Make readable/writable for cleanup \ No newline at end of file