Spaces:
Running
Running
| """Unit tests for RAG Index Service.""" | |
| import pytest | |
| from unittest.mock import MagicMock, patch | |
| from pathlib import Path | |
| from backend.src.services.rag_index import RAGIndexService | |
| from backend.src.services.config import AppConfig | |
| def mock_config(tmp_path): | |
| config = MagicMock(spec=AppConfig) | |
| config.google_api_key = "fake-key" | |
| config.llamaindex_persist_dir = tmp_path / "data" / "llamaindex" | |
| return config | |
| def rag_service(mock_config): | |
| with patch("backend.src.services.rag_index.get_config", return_value=mock_config): | |
| with patch("backend.src.services.rag_index.VaultService") as mock_vault: | |
| service = RAGIndexService() | |
| service.vault_service = mock_vault.return_value | |
| yield service | |
| def test_get_persist_dir(rag_service): | |
| user_id = "test-user" | |
| persist_dir = rag_service.get_persist_dir(user_id) | |
| assert user_id in persist_dir | |
| assert Path(persist_dir).exists() | |
| def test_get_or_build_index_existing(mock_storage_context, mock_load, rag_service): | |
| """Test loading an existing index.""" | |
| user_id = "test-user" | |
| mock_index = MagicMock() | |
| mock_load.return_value = mock_index | |
| # Assume load succeeds | |
| index = rag_service.get_or_build_index(user_id) | |
| assert index == mock_index | |
| mock_load.assert_called_once() | |
| # Should NOT build | |
| rag_service.vault_service.list_notes.assert_not_called() | |
| def test_get_or_build_index_new(mock_load, mock_vector_store, rag_service): | |
| """Test building a new index when load fails.""" | |
| user_id = "test-user" | |
| mock_load.side_effect = Exception("No index") | |
| mock_index = MagicMock() | |
| mock_vector_store.from_documents.return_value = mock_index | |
| # Mock vault data | |
| rag_service.vault_service.list_notes.return_value = [{"path": "note1.md"}] | |
| rag_service.vault_service.read_note.return_value = { | |
| "title": "Note 1", | |
| "body": "Content", | |
| "metadata": {} | |
| } | |
| index = rag_service.get_or_build_index(user_id) | |
| rag_service.vault_service.list_notes.assert_called_with(user_id) | |
| def test_get_status(mock_exists, rag_service): | |
| user_id = "test-user" | |
| mock_exists.return_value = True | |
| status = rag_service.get_status(user_id) | |
| assert status.status == "ready" | |
| mock_exists.return_value = False | |
| status = rag_service.get_status(user_id) | |
| assert status.status == "building" | |
| def test_chat(mock_storage, mock_load, rag_service): | |
| user_id = "test-user" | |
| # Mock Index and ChatEngine | |
| mock_index = MagicMock() | |
| mock_chat_engine = MagicMock() | |
| mock_index.as_chat_engine.return_value = mock_chat_engine | |
| mock_load.return_value = mock_index | |
| # Mock Response | |
| mock_response = MagicMock() | |
| mock_response.__str__.return_value = "AI Answer" | |
| # Mock Source Nodes | |
| mock_node = MagicMock() | |
| mock_node.metadata = {"path": "note.md", "title": "Note"} | |
| mock_node.get_content.return_value = "Snippet content" | |
| mock_node.score = 0.9 | |
| mock_response.source_nodes = [mock_node] | |
| mock_chat_engine.chat.return_value = mock_response | |
| from backend.src.models.rag import ChatMessage | |
| messages = [ChatMessage(role="user", content="Question")] | |
| response = rag_service.chat(user_id, messages) | |
| assert response.answer == "AI Answer" | |
| assert len(response.sources) == 1 | |
| assert response.sources[0].path == "note.md" | |
| mock_chat_engine.chat.assert_called() | |