diff --git a/backend/app/routers/search.py b/backend/app/routers/search.py new file mode 100644 index 0000000..a2d3d2b --- /dev/null +++ b/backend/app/routers/search.py @@ -0,0 +1,11 @@ +from fastapi import APIRouter, Depends + +from app.dependencies import get_search_client +from app.search_client import SearchClient + +router = APIRouter() + + +@router.get("/api/search") +def search(q: str = "", client: SearchClient = Depends(get_search_client)): + return {"results": client.search(q)} diff --git a/backend/tests/test_routers_search.py b/backend/tests/test_routers_search.py new file mode 100644 index 0000000..41bc0c1 --- /dev/null +++ b/backend/tests/test_routers_search.py @@ -0,0 +1,52 @@ +import pytest +from fastapi.testclient import TestClient + +from app.main import app +from app.dependencies import get_search_client + + +class FakeSearchClient: + def __init__(self): + self.queries = [] + + def search(self, query): + self.queries.append(query) + if query == "检索": + return [ + { + "key": "产品文档/架构设计.md", + "title": "架构设计.md", + "path": "产品文档", + "snippet": "支持全文检索功能", + } + ] + return [] + + +@pytest.fixture +def client(): + fake_client = FakeSearchClient() + app.dependency_overrides[get_search_client] = lambda: fake_client + with TestClient(app) as test_client: + test_client.fake_client = fake_client + yield test_client + app.dependency_overrides.clear() + + +def test_search_returns_matching_results(client): + response = client.get("/api/search", params={"q": "检索"}) + assert response.status_code == 200 + body = response.json() + assert body["results"][0]["key"] == "产品文档/架构设计.md" + assert "检索" in body["results"][0]["snippet"] + + +def test_search_returns_empty_results_for_no_match(client): + response = client.get("/api/search", params={"q": "不存在的关键词"}) + assert response.status_code == 200 + assert response.json() == {"results": []} + + +def test_search_passes_query_string_to_search_client(client): + client.get("/api/search", params={"q": "MinIO"}) + assert client.fake_client.queries == ["MinIO"]