tests/test_literature_check_report.py
Rama main · réplica de lectura del repositorio original.
"""
End-to-end test of the bibliography check report: parse → database lookup
→ field comparison → report, with a fake LLM and fake databases. Runs the
report in English and in German (output-language catalog).
"""
import asyncio
import json
import pytest
from src import output_language
from src.connectors.literature_apis import LiteratureAPIClient
from src.pipeline.literature_check import LiteratureChecker
RAW = """Smith, J. (2020). Deep learning for bibliographies. Journal of Tests, 12(3), 1-10.
Doe, A. (2019). A paper nobody can find. Unknown Press."""
PARSED = [
{"raw_text": "Smith, J. (2020). Deep learning for bibliographies.", "authors": ["Smith, J."],
"title": "Deep learning for bibliographies", "year": "2020", "journal": "Journal of Tests",
"volume": "12", "issue": "3", "pages": "1-10", "entry_type": "article"},
{"raw_text": "Doe, A. (2019). A paper nobody can find.", "authors": ["Doe, A."],
"title": "A paper nobody can find", "year": "2019", "entry_type": "book"},
]
class FakeLLM:
async def primary_complete(self, messages, **kw):
text = messages[-1]["content"]
if "Context:" in text:
return "Harmless formatting difference."
return json.dumps(PARSED)
def get_usage_stats(self):
return {"total_requests": 2, "total_tokens": 100}
class FakeAPIs(LiteratureAPIClient):
def __init__(self):
super().__init__()
async def lookup_entry(self, entry):
if entry.title.startswith("Deep"):
return [{"source": "crossref", "title": "Deep learning for bibliographies",
"authors": ["John Smith"], "year": "2021", "journal": "Journal of Tests",
"doi": "10.1000/test", "cited_by_count": 42}]
return []
def _run(lang):
checker = LiteratureChecker(FakeLLM(), searxng=None, lang=lang)
checker.api_client = FakeAPIs()
async def progress(*args, **kwargs):
pass
markdown, report = asyncio.run(checker.check(raw_text=RAW, progress_callback=progress))
asyncio.run(checker.close())
return markdown, report
def test_report_in_english():
md, report = _run("en")
assert report.total == 2
assert "# Bibliography check report" in md
assert "Entries checked" in md
assert "Year" in md # deviation 2020 → 2021, field label
assert "Corrected bibliography (APA)" in md
assert "Prüfbericht" not in md
@pytest.fixture
def german(monkeypatch):
monkeypatch.setenv("OUTPUT_LANGUAGES", "en,de")
output_language.reload()
yield
monkeypatch.delenv("OUTPUT_LANGUAGES")
output_language.reload()
def test_report_in_german(german):
md, _ = _run("de")
assert "# Prüfbericht Literaturverzeichnis" in md
assert "Geprüfte Einträge" in md
assert "Jahr" in md
assert "Korrigiertes Literaturverzeichnis (APA)" in md
def test_llm_failure_is_not_reported_as_a_format_problem():
"""If the model cannot be reached, the message says so — not 'check the format'."""
class BrokenLLM(FakeLLM):
async def primary_complete(self, messages, **kw):
raise ConnectionError("Connection error.")
checker = LiteratureChecker(BrokenLLM(), searxng=None, lang="en")
checker.api_client = FakeAPIs()
async def progress(*args, **kwargs):
pass
md, report = asyncio.run(checker.check(raw_text=RAW, progress_callback=progress))
asyncio.run(checker.close())
assert report.total == 0
assert "language model returned an error" in md and "Connection error" in md
assert "check the format" not in md