"""Tests for the memory notes extraction module.""" import pytest from unittest.mock import AsyncMock, MagicMock, patch from reachy_mini_conversation_app.memory_notes import ( NotesManager, SECTION_KEY_FACTS, SECTION_ENTITIES, SECTION_PREFERENCES, SECTION_THREADS, ) class TestNotesManagerDatabase: """Test NotesManager database interactions (no LLM calls).""" def test_get_context_empty(self, tmp_path): """Test context generation with no notes.""" from reachy_mini_conversation_app.database import MiniMinderDB db = MiniMinderDB(tmp_path / "test.db") manager = NotesManager(db) context = manager.get_context_for_prompt() assert context == "" db.close() def test_get_context_with_notes(self, tmp_path): """Test context generation with existing notes.""" from reachy_mini_conversation_app.database import MiniMinderDB db = MiniMinderDB(tmp_path / "test.db") # Add some notes directly to database db.add_note(SECTION_KEY_FACTS, "Takes Topiramate at 8am daily") db.add_note(SECTION_PREFERENCES, "Prefers quiet voice after migraines") db.add_note(SECTION_ENTITIES, "Maya - daughter, lives remotely") manager = NotesManager(db) context = manager.get_context_for_prompt() assert "What I Remember About You" in context assert "Topiramate" in context assert "quiet voice" in context assert "Maya" in context db.close() def test_get_preferences(self, tmp_path): """Test retrieving user preferences.""" from reachy_mini_conversation_app.database import MiniMinderDB db = MiniMinderDB(tmp_path / "test.db") db.add_note(SECTION_PREFERENCES, "Likes morning check-ins") db.add_note(SECTION_PREFERENCES, "Prefers British English") manager = NotesManager(db) prefs = manager.get_preferences() assert len(prefs) == 2 assert "morning check-ins" in prefs[0] or "morning check-ins" in prefs[1] db.close() class TestNotesManagerExtraction: """Test NotesManager LLM extraction (mocked).""" @pytest.mark.asyncio async def test_extract_and_save(self, tmp_path): """Test extraction with mocked LLM response.""" from reachy_mini_conversation_app.database import MiniMinderDB db = MiniMinderDB(tmp_path / "test.db") manager = NotesManager(db) # Mock the LLM response mock_response = MagicMock() mock_response.content = """```json { "key_facts": ["Takes medication at 8am"], "entities": ["Maya - daughter"], "preferences": ["Prefers quiet reminders"], "threads": [] } ```""" with patch.object(manager, "_get_llm") as mock_llm: mock_llm.return_value.ainvoke = AsyncMock(return_value=mock_response) conversation = [ {"role": "user", "content": "I take my medication at 8am"}, {"role": "assistant", "content": "I'll remember that."}, ] result = await manager.extract_and_save(conversation, session_id="test123") assert "key_facts" in result assert len(result["key_facts"]) == 1 assert "8am" in result["key_facts"][0] # Verify notes were saved to database notes = db.get_notes() assert len(notes) >= 1 db.close() @pytest.mark.asyncio async def test_extract_empty_conversation(self, tmp_path): """Test extraction with empty conversation.""" from reachy_mini_conversation_app.database import MiniMinderDB db = MiniMinderDB(tmp_path / "test.db") manager = NotesManager(db) result = await manager.extract_and_save([], session_id="test") assert result == {} db.close()