| from unittest.mock import AsyncMock, MagicMock, patch |
|
|
| import pytest |
|
|
| from src.server.services.search.rag_service import RAGService |
|
|
|
|
| @pytest.fixture |
| def mock_genai_client(): |
| with patch("src.server.services.search.rag_service.genai.Client") as mock: |
| client_instance = mock.return_value |
|
|
| |
| mock_response = MagicMock() |
| mock_candidate = MagicMock() |
| mock_part = MagicMock() |
| mock_part.text = "This is a web search summary." |
| mock_candidate.content.parts = [mock_part] |
|
|
| |
| mock_chunk = MagicMock() |
| mock_chunk.web.uri = "https://example.com" |
| mock_candidate.grounding_metadata.grounding_chunks = [mock_chunk] |
|
|
| mock_response.candidates = [mock_candidate] |
|
|
| client_instance.models.generate_content.return_value = mock_response |
| client_instance.aio.models.generate_content = AsyncMock(return_value=mock_response) |
| yield client_instance |
|
|
|
|
| @pytest.fixture |
| def mock_librarian(): |
| |
| import src.server.services.librarian_service |
|
|
| |
| with patch("src.server.services.librarian_service.LibrarianService") as mock: |
| instance = mock.return_value |
| instance.archive_web_research = AsyncMock(return_value="web-source-123") |
| yield instance |
|
|
|
|
| @pytest.fixture |
| def mock_credential_service(): |
| |
| with patch("src.server.services.credential_service.credential_service") as mock: |
| mock.get_credential = AsyncMock(return_value="fake-api-key") |
| yield mock |
|
|
|
|
| @pytest.fixture |
| def mock_base_dependencies(): |
| with ( |
| patch("src.server.services.search.rag_service.get_supabase_client"), |
| patch("src.server.services.search.rag_service.BaseSearchStrategy"), |
| patch("src.server.services.search.rag_service.HybridSearchStrategy"), |
| patch("src.server.services.search.rag_service.AgenticRAGStrategy"), |
| patch("src.server.services.search.rag_service.create_embedding", new_callable=AsyncMock) as mock_embed, |
| ): |
| mock_embed.return_value = [0.1, 0.2, 0.3] |
| yield |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_perform_web_research_success( |
| mock_base_dependencies, mock_genai_client, mock_librarian, mock_credential_service |
| ): |
| service = RAGService() |
|
|
| content, source_id = await service.perform_web_research("latest ai trends") |
|
|
| assert content == "This is a web search summary." |
| assert source_id == "web-source-123" |
|
|
| |
| mock_genai_client.aio.models.generate_content.assert_called_once() |
|
|
| |
| mock_librarian.archive_web_research.assert_called_once() |
| args = mock_librarian.archive_web_research.call_args[0] |
| assert args[0] == "latest ai trends" |
| assert args[1] == "This is a web search summary." |
| assert args[2] == ["https://example.com"] |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_perform_rag_query_with_web_research( |
| mock_base_dependencies, mock_genai_client, mock_librarian, mock_credential_service |
| ): |
| service = RAGService() |
|
|
| |
| service.base_strategy.vector_search = AsyncMock( |
| return_value=[{"id": "doc-1", "content": "Internal doc", "similarity": 0.8}] |
| ) |
|
|
| |
| result_success, result_data = await service.perform_rag_query( |
| query="latest trends", filter_metadata={"enable_web_research": True} |
| ) |
|
|
| assert result_success is True |
| results = result_data["results"] |
|
|
| |
| assert len(results) >= 2 |
| assert results[0]["metadata"]["type"] == "web_research" |
| assert results[0]["content"] == "This is a web search summary." |
|
|
| |
| |
| mock_librarian.archive_web_research.assert_called_once() |
|
|