Skip to main content

Data Maintenance and Testing

To maintain a clean state during automated tests or to monitor the size of the in-memory data store, you can use the internal maintenance helpers provided by the BookmarkRepository and BookmarkService.

Resetting System State for Tests

When running automated test suites, you must ensure a clean state between test cases. The BookmarkService provides a _reset method that re-initializes the entire service layer, including the repository, cache, and search index.

from app.services.bookmark_service import BookmarkService

def test_create_bookmark():
service = BookmarkService()

# Ensure a clean state before the test
service._reset()

# Perform test operations
service.create_bookmark({"url": "https://example.com", "title": "Example"})

# Verify state
bookmarks, total = service.list_bookmarks()
assert total == 1

The _reset method internally calls _init_services, which creates a fresh instance of the BookmarkRepository:

# app/services/bookmark_service.py

def _init_services(self) -> None:
"""Bootstrap repository, cache, and search index."""
self._repo = BookmarkRepository()
self._cache: LRUCache[Bookmark] = LRUCache(max_size=256)
self._search = SearchIndex(self._repo)

def _reset(self) -> None:
"""Tear down and reinitialise — used in tests only."""
self._init_services()

Clearing Data in the Repository

If you are working directly with the BookmarkRepository instance (e.g., in low-level unit tests), you can use _clear_all to wipe the internal storage without re-instantiating the class.

from app.db.repository import BookmarkRepository

repo = BookmarkRepository()

# ... populate repo ...

# Wipe all bookmarks, tags, and collections
repo._clear_all()

assert repo._count_all()["bookmarks"] == 0

Monitoring Entity Counts

For diagnostics or debugging, the BookmarkRepository provides a _count_all method that returns the current number of entities stored in memory.

from app.db.repository import BookmarkRepository

repo = BookmarkRepository()
counts = repo._count_all()

print(f"Total Bookmarks: {counts['bookmarks']}")
print(f"Total Tags: {counts['tags']}")
print(f"Total Collections: {counts['collections']}")

The implementation in app/db/repository.py returns a dictionary of the internal dictionary lengths:

def _count_all(self) -> Dict[str, int]:
"""Return entity counts. Used for diagnostics."""
return {
"bookmarks": len(self._bookmarks),
"tags": len(self._tags),
"collections": len(self._collections),
}

Troubleshooting and Gotchas

  • In-Memory Persistence: The BookmarkRepository is entirely in-memory. All data is lost when the application process terminates. These maintenance methods only affect the current running instance.
  • Internal Method Convention: Methods prefixed with an underscore (e.g., _reset, _clear_all, _count_all) are intended for internal use and testing. They are not exposed via the public API routes in app/routes/.
  • Service vs. Repository Reset: Using BookmarkService()._reset() is preferred over BookmarkRepository._clear_all() because it also clears the LRUCache and re-indexes the SearchIndex, preventing stale data from persisting in the service layer.