test(ebook): cover protected phrases and migrate suite to async
Add test_protected_phrases.py covering phrase-matching behavior in the RAG engine, and update the existing ebook_search tests to use the async SQLAlchemy engine/session (create_async_engine, AsyncSession) and async HTTP paths.
This commit is contained in:
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
|
||||
from python.ebook_search.api.main import create_app
|
||||
from python.ebook_search.config import EbookSearchConfig, RerankConfig
|
||||
@@ -66,8 +66,8 @@ def test_is_confident_against_threshold() -> None:
|
||||
|
||||
def patch_app_runtime(mocker: MockerFixture):
|
||||
mocker.patch(
|
||||
"python.ebook_search.api.main.get_postgres_engine",
|
||||
side_effect=lambda **_kwargs: create_engine("sqlite+pysqlite:///:memory:", future=True),
|
||||
"python.ebook_search.api.main.get_async_postgres_engine",
|
||||
side_effect=lambda **_kwargs: create_async_engine("sqlite+aiosqlite:///:memory:"),
|
||||
)
|
||||
mocker.patch("python.ebook_search.api.main.ensure_bm25_corpus", side_effect=lambda _session, _config: None)
|
||||
|
||||
@@ -75,11 +75,12 @@ def patch_app_runtime(mocker: MockerFixture):
|
||||
def test_low_confidence_skips_answer_generation(mocker: MockerFixture) -> None:
|
||||
called = False
|
||||
|
||||
def fake_search_ebooks(_engine, query, _config, *, rerank=False):
|
||||
def fake_search_ebooks(_engine, _client, query, _config, *, rerank=False, phrase_matching=False):
|
||||
del rerank
|
||||
del phrase_matching
|
||||
return SearchResponse(query=query, rank_label="Hybrid", results=make_results(1, vector_score=0.05))
|
||||
|
||||
def fake_answer_query(_query, _results, _config):
|
||||
def fake_answer_query(_client, _query, _results, _config):
|
||||
nonlocal called
|
||||
called = True
|
||||
return "answer"
|
||||
@@ -104,14 +105,15 @@ def test_low_confidence_skips_answer_generation(mocker: MockerFixture) -> None:
|
||||
|
||||
|
||||
def test_invalid_citation_is_flagged(mocker: MockerFixture) -> None:
|
||||
def fake_search_ebooks(_engine, query, _config, *, rerank=False):
|
||||
def fake_search_ebooks(_engine, _client, query, _config, *, rerank=False, phrase_matching=False):
|
||||
del rerank
|
||||
del phrase_matching
|
||||
return SearchResponse(query=query, rank_label="Hybrid", results=make_results(2, vector_score=0.9))
|
||||
|
||||
mocker.patch("python.ebook_search.api.routes.search.search_ebooks", side_effect=fake_search_ebooks)
|
||||
mocker.patch(
|
||||
"python.ebook_search.api.routes.search.answer_query",
|
||||
side_effect=lambda _query, _results, _config: "Per the text [9].",
|
||||
side_effect=lambda _client, _query, _results, _config: "Per the text [9].",
|
||||
)
|
||||
patch_app_runtime(mocker)
|
||||
app = create_app()
|
||||
@@ -126,14 +128,15 @@ def test_invalid_citation_is_flagged(mocker: MockerFixture) -> None:
|
||||
|
||||
|
||||
def test_grounded_answer_has_no_warning_badge(mocker: MockerFixture) -> None:
|
||||
def fake_search_ebooks(_engine, query, _config, *, rerank=False):
|
||||
def fake_search_ebooks(_engine, _client, query, _config, *, rerank=False, phrase_matching=False):
|
||||
del rerank
|
||||
del phrase_matching
|
||||
return SearchResponse(query=query, rank_label="Hybrid", results=make_results(2, vector_score=0.9))
|
||||
|
||||
mocker.patch("python.ebook_search.api.routes.search.search_ebooks", side_effect=fake_search_ebooks)
|
||||
mocker.patch(
|
||||
"python.ebook_search.api.routes.search.answer_query",
|
||||
side_effect=lambda _query, _results, _config: "Grounded in [1] and [2].",
|
||||
side_effect=lambda _client, _query, _results, _config: "Grounded in [1] and [2].",
|
||||
)
|
||||
patch_app_runtime(mocker)
|
||||
app = create_app()
|
||||
|
||||
Reference in New Issue
Block a user