ai / backend /tests /test_metadata.py
Aissugur Kurganbekov
Claude Opus 4.8
Add hybrid retrieval (TF-IDF + embeddings), OCR, A/B eval, and answer trust/UX
f65a6b3
Raw History Blame Contribute Delete
3.26 kB
"""Focused unit tests for the answer metadata dict (the shared-contract 5th
element of answer_question). These assert the metadata's shape, the confidence
range/calibration, evidence_status, and chunk counts — independently of the
answer text itself."""
from app import config
from app.answering import answer_question
from tests.conftest import make_chunk
INVOICE = (
"Invoice Number INV-2025-0473. Invoice Date March 3 2025. Due Date April 2 "
"2025. Subtotal $2,230.00. Tax $183.98. Total Amount Due $2,413.98. "
"Payment terms net 30."
)
# Every metadata dict must carry exactly these keys (shared contract).
EXPECTED_KEYS = {
"question_type",
"evidence_status",
"confidence",
"top_score",
"matched_terms",
"required_terms",
"retrieved_chunks",
"cited_chunks",
"requested_mode",
"answer_mode",
"latency_ms",
}
def test_metadata_supported_answer_shape_and_confidence():
chunks = [make_chunk(INVOICE)]
_answer, abstained, _mode, citations, metadata = answer_question(
"What is the total amount due?", chunks
)
assert abstained is False
# Contract: the full key set is always present.
assert set(metadata) == EXPECTED_KEYS
assert metadata["evidence_status"] == "supported"
# Confidence is a 0..1 float; a solid invoice-total match should be high.
assert 0.0 <= metadata["confidence"] <= 1.0
assert metadata["confidence"] >= 0.6
# cited_chunks mirrors the returned citations.
assert metadata["cited_chunks"] == len(citations)
assert metadata["cited_chunks"] >= 1
assert metadata["question_type"] == "invoice_total"
assert metadata["latency_ms"] >= 0
assert isinstance(metadata["latency_ms"], int)
def test_metadata_abstained_low_confidence_and_no_citations():
chunks = [make_chunk("The weather today is sunny with a light breeze.")]
_answer, abstained, _mode, _citations, metadata = answer_question(
"What is the total amount due?", chunks
)
assert abstained is True
assert set(metadata) == EXPECTED_KEYS
assert metadata["evidence_status"] == "abstained"
assert metadata["confidence"] == 0.0
assert metadata["cited_chunks"] == 0
def test_metadata_confidence_in_unit_range_for_empty_document():
_answer, abstained, _mode, _citations, metadata = answer_question("anything?", [])
assert abstained is True
assert 0.0 <= metadata["confidence"] <= 1.0
assert metadata["evidence_status"] == "abstained"
assert metadata["retrieved_chunks"] == 0
def test_metadata_question_type_payment_terms():
chunks = [make_chunk(INVOICE)]
_answer, _abstained, _mode, _citations, metadata = answer_question(
"What are the payment terms?", chunks
)
assert metadata["question_type"] == "payment_terms"
def test_metadata_match_text_populated_on_citation():
chunks = [make_chunk(INVOICE)]
_answer, _abstained, _mode, citations, _metadata = answer_question(
"What is the total amount due?", chunks
)
assert citations
# The focused span the question matched is surfaced for UI highlighting and
# is a verbatim substring of the chunk text.
assert citations[0].match_text is not None
assert citations[0].match_text in INVOICE