54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
from fastapi.testclient import TestClient
|
|
|
|
from config import Settings
|
|
from main import create_app
|
|
from rag.answer import GroundedAnswerService
|
|
from rag.models import EvidenceDecision, QueryIntent, RetrievalResult, SubjectScope
|
|
|
|
|
|
class FixedRouting:
|
|
def retrieve(self, query, subject_scope, intent):
|
|
assert query == "Liều thuốc?"
|
|
assert subject_scope == SubjectScope.HUMAN
|
|
assert intent == QueryIntent.FACT_LOOKUP
|
|
return RetrievalResult(EvidenceDecision.ABSTAIN, "drug_not_resolved")
|
|
|
|
|
|
class MemoryTraceWriter:
|
|
def __init__(self):
|
|
self.rows = []
|
|
|
|
def save(self, **fields):
|
|
self.rows.append(fields)
|
|
return "trace-1"
|
|
|
|
|
|
def test_health_and_fail_closed_rag_response_are_traced():
|
|
traces = MemoryTraceWriter()
|
|
app = create_app(
|
|
settings=Settings(),
|
|
answer_service=GroundedAnswerService(FixedRouting()),
|
|
trace_writer=traces,
|
|
)
|
|
client = TestClient(app)
|
|
assert client.get("/health").json() == {"status": "ok"}
|
|
response = client.post("/v1/rag/query", json={
|
|
"query": "Liều thuốc?",
|
|
"subject_scope": "human",
|
|
"intent": "fact_lookup",
|
|
})
|
|
assert response.status_code == 200
|
|
assert response.json()["decision"] == "abstain"
|
|
assert response.json()["trace_id"] == "trace-1"
|
|
assert traces.rows[0]["reason"] == "drug_not_resolved"
|
|
|
|
|
|
def test_query_requires_structured_scope_and_intent():
|
|
app = create_app(
|
|
settings=Settings(),
|
|
answer_service=GroundedAnswerService(FixedRouting()),
|
|
trace_writer=MemoryTraceWriter(),
|
|
)
|
|
response = TestClient(app).post("/v1/rag/query", json={"query": "Liều?"})
|
|
assert response.status_code == 422
|