test: add offline unit tests for Phase A reliability fixes
Mock-based tests (no live services) covering:
- ollama_llm_model resolution under the OLLAMA_MODEL env collision
- per-leg retrieval failure -> source_status/degraded signaling
- Phase 0/Phase 4 LLM timeout fallbacks
- /stats wiki page count using the users/{user} path prefix
- Wiki.js list_all_pages limit-growth pagination and
list_pages limit-after-filter behavior
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
"""
|
||||
Unit tests for the /stats endpoint (offline, all clients mocked).
|
||||
|
||||
Covers the wiki page count fix: the endpoint must count pages under the
|
||||
user namespace ("users/{user}"), not pass the bare user name as prefix
|
||||
(which matched nothing and always reported 0 pages).
|
||||
"""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from src.main import stats
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def neo4j_client():
|
||||
neo4j = MagicMock()
|
||||
neo4j.execute_query = AsyncMock(return_value=[{"count": 5}])
|
||||
return neo4j
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def qdrant_client():
|
||||
qdrant = MagicMock()
|
||||
qdrant.list_collections = AsyncMock(return_value=[
|
||||
{"name": "user_jp", "vectors_count": 42}
|
||||
])
|
||||
return qdrant
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def wikijs_client():
|
||||
wikijs = MagicMock()
|
||||
wikijs.list_all_pages = AsyncMock(return_value=[
|
||||
{"id": i, "path": f"users/jpmschweitzer/p{i}"} for i in range(138)
|
||||
])
|
||||
return wikijs
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def paperless_client():
|
||||
paperless = MagicMock()
|
||||
paperless.list_documents = AsyncMock(return_value={"count": 3})
|
||||
paperless.list_tags = AsyncMock(return_value=[])
|
||||
paperless.list_correspondents = AsyncMock(return_value=[])
|
||||
paperless.list_document_types = AsyncMock(return_value=[])
|
||||
return paperless
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestStatsWikiPageCount:
|
||||
"""/stats must scope the wiki page count to the user namespace."""
|
||||
|
||||
async def test_uses_user_namespace_path_prefix(
|
||||
self, neo4j_client, qdrant_client, wikijs_client, paperless_client
|
||||
):
|
||||
await stats(
|
||||
user="jpmschweitzer",
|
||||
neo4j=neo4j_client,
|
||||
qdrant=qdrant_client,
|
||||
wikijs=wikijs_client,
|
||||
paperless=paperless_client,
|
||||
api_key="test-key",
|
||||
)
|
||||
|
||||
wikijs_client.list_all_pages.assert_awaited_once_with(
|
||||
path_prefix="users/jpmschweitzer"
|
||||
)
|
||||
|
||||
async def test_reports_page_count(
|
||||
self, neo4j_client, qdrant_client, wikijs_client, paperless_client
|
||||
):
|
||||
response = await stats(
|
||||
user="jpmschweitzer",
|
||||
neo4j=neo4j_client,
|
||||
qdrant=qdrant_client,
|
||||
wikijs=wikijs_client,
|
||||
paperless=paperless_client,
|
||||
api_key="test-key",
|
||||
)
|
||||
|
||||
assert response.wiki_pages == 138
|
||||
|
||||
async def test_wiki_failure_degrades_to_zero(
|
||||
self, neo4j_client, qdrant_client, wikijs_client, paperless_client
|
||||
):
|
||||
wikijs_client.list_all_pages = AsyncMock(side_effect=RuntimeError("wiki down"))
|
||||
|
||||
response = await stats(
|
||||
user="jpmschweitzer",
|
||||
neo4j=neo4j_client,
|
||||
qdrant=qdrant_client,
|
||||
wikijs=wikijs_client,
|
||||
paperless=paperless_client,
|
||||
api_key="test-key",
|
||||
)
|
||||
|
||||
assert response.wiki_pages == 0
|
||||
Reference in New Issue
Block a user