from __future__ import annotations import httpx from app.services.knowledge.demo import DemoKnowledgeProvider from app.services.knowledge.ragcore import RAGcoreKnowledgeProvider def test_s6_damage_question_is_grounded_with_expected_sources(): provider = DemoKnowledgeProvider() answer = provider.ask( "What must I do when a vehicle returns with damage?", "test-correlation-1" ) assert answer.evidence_state == "grounded" document_ids = {s.document_id for s in answer.sources} assert "damage-procedure" in document_ids assert "vehicle-return-procedure" in document_ids assert answer.answer # never empty for a grounded answer for source in answer.sources: assert source.excerpt def test_unrelated_question_is_insufficient(): provider = DemoKnowledgeProvider() answer = provider.ask("What is the capital of France?", "test-correlation-2") assert answer.evidence_state == "insufficient" assert "France" not in answer.answer # never fabricates an answer beyond the procedures def test_demo_provider_health_reports_document_count(): provider = DemoKnowledgeProvider() health = provider.health() assert health.provider == "demo" assert health.available is True assert health.document_count == 10 def test_ask_question_endpoint_grounded(ops_client): response = ops_client.post( "/api/v1/knowledge/questions", json={"question": "What must I do when a vehicle returns with damage?"}, ) assert response.status_code == 200 body = response.json() assert body["evidence_state"] == "grounded" assert body["provider"] == "demo" assert len(body["sources"]) > 0 def test_ask_question_requires_authentication(client): response = client.post("/api/v1/knowledge/questions", json={"question": "Anything?"}) assert response.status_code == 401 def test_ask_question_is_audited_without_leaking_full_text(ops_client): ops_client.post( "/api/v1/knowledge/questions", json={"question": "What must I do when a vehicle returns with damage?"}, ) events = ops_client.get( "/api/v1/audit", params={"action": "knowledge_question_asked"} ).json() assert len(events) >= 1 metadata = events[0]["metadata"] assert "evidence_state" in metadata assert "source_ids" in metadata assert "question" not in metadata def test_knowledge_status_endpoint(ops_client): response = ops_client.get("/api/v1/knowledge/status") assert response.status_code == 200 assert response.json()["provider"] == "demo" def test_ragcore_provider_degrades_to_unavailable(monkeypatch): def fake_client(*args, **kwargs): raise httpx.ConnectError("no ragcore in this environment") provider = RAGcoreKnowledgeProvider() monkeypatch.setattr(provider, "_client", fake_client) answer = provider.ask("Anything?", "test-correlation-3") assert answer.evidence_state == "unavailable" assert answer.sources == []