Complete local hybrid search and improve agent reliability
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
_TEST_DATA_DIR = None
|
||||
if "SOVEREIGNAI_DATA_DIR" not in os.environ:
|
||||
_TEST_DATA_DIR = tempfile.TemporaryDirectory(prefix="sovereignai-web-search-tests-")
|
||||
os.environ["SOVEREIGNAI_DATA_DIR"] = _TEST_DATA_DIR.name
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
|
||||
|
||||
class _FakeSearchClient:
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, traceback):
|
||||
return None
|
||||
|
||||
async def get(self, *args, **kwargs):
|
||||
return SimpleNamespace(
|
||||
content=b"<html>mock search</html>",
|
||||
text="<html>mock search</html>",
|
||||
raise_for_status=lambda: None,
|
||||
)
|
||||
|
||||
|
||||
class WebSearchApiTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.client = TestClient(app)
|
||||
|
||||
def test_search_returns_per_source_and_total_fetch_durations(self) -> None:
|
||||
candidates = [
|
||||
{"title": "Source A", "url": "https://a.example/article", "snippet": "A excerpt"},
|
||||
{"title": "Source B", "url": "https://b.example/article", "snippet": "B excerpt"},
|
||||
]
|
||||
|
||||
async def read_page(url: str) -> tuple[str, str, str]:
|
||||
await asyncio.sleep(0.01)
|
||||
title = "A article" if "a.example" in url else "B article"
|
||||
return url, title, f"Content for {title}"
|
||||
|
||||
provider = MagicMock(default_model="test-model")
|
||||
completion = {"choices": [{"message": {"content": "ملخص موثق."}}]}
|
||||
with (
|
||||
patch("app.main.httpx.AsyncClient", return_value=_FakeSearchClient()),
|
||||
patch("app.main.parse_duckduckgo_results", return_value=candidates),
|
||||
patch("app.main._validate_public_http_url", side_effect=lambda url: url),
|
||||
patch("app.main._read_public_page", side_effect=read_page),
|
||||
patch("app.main.get_model_provider", return_value=provider),
|
||||
patch("app.main.get_completion", new=AsyncMock(return_value=completion)),
|
||||
):
|
||||
response = self.client.post(
|
||||
"/v1/web/search",
|
||||
json={"query": "اختبار البحث", "max_results": 2},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200, response.text)
|
||||
body = response.json()
|
||||
self.assertEqual(body["result"], "ملخص موثق.")
|
||||
self.assertGreaterEqual(body["source_fetch_ms"], 0)
|
||||
self.assertEqual(len(body["sources"]), 2)
|
||||
self.assertTrue(all(source["fetch_ms"] >= 0 for source in body["sources"]))
|
||||
self.assertTrue(all(source["status"] == "read" for source in body["sources"]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user