Spaces:
Running
Running
| """Tests for EHRAgent parsing and deterministic context fallback behaviour.""" | |
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| from backend.models.ehr_agent import EHRAgent, parse_agent_output | |
| FHIR_SAMPLE_PATH = Path("data/fhir_bundles/pt-001.json") | |
| async def _async_raw_context(patient_id: str) -> dict: | |
| """Return async raw context helper for monkeypatched query call. | |
| Args: | |
| patient_id (str): Patient identifier. | |
| Returns: | |
| dict: Raw grouped FHIR context payload. | |
| """ | |
| return _build_raw_context(patient_id) | |
| def _build_raw_context(patient_id: str) -> dict: | |
| """Build deterministic raw context payload from local FHIR bundle fixture. | |
| Args: | |
| patient_id (str): Patient identifier used to construct context. | |
| Returns: | |
| dict: Aggregated resources grouped by FHIR type. | |
| """ | |
| bundle = json.loads(FHIR_SAMPLE_PATH.read_text(encoding="utf-8")) | |
| grouped = { | |
| "patient_id": patient_id, | |
| "patients": [], | |
| "conditions": [], | |
| "medications": [], | |
| "observations": [], | |
| "allergies": [], | |
| "diagnostic_reports": [], | |
| "encounters": [], | |
| } | |
| type_mapping = { | |
| "Patient": "patients", | |
| "Condition": "conditions", | |
| "MedicationRequest": "medications", | |
| "Observation": "observations", | |
| "AllergyIntolerance": "allergies", | |
| "DiagnosticReport": "diagnostic_reports", | |
| "Encounter": "encounters", | |
| } | |
| for entry in bundle.get("entry", []): | |
| resource = entry.get("resource", {}) | |
| bucket = type_mapping.get(resource.get("resourceType")) | |
| if bucket: | |
| grouped[bucket].append(resource) | |
| return grouped | |
| def test_parse_agent_output_strips_system_and_markdown_fences() -> None: | |
| """Verify parser extracts first valid JSON object from noisy model output. | |
| Args: | |
| None: Uses hardcoded sample output with prompt leakage and code fences. | |
| Returns: | |
| None: Assertions validate parser output fields. | |
| """ | |
| raw = ( | |
| "<|system|>hidden instructions<|end|>\n" | |
| "```json\n" | |
| '{"patient_id": "pt-001", "problem_list": ["Type 2 diabetes mellitus"]}' | |
| "\n```" | |
| ) | |
| payload = parse_agent_output(raw) | |
| assert payload["patient_id"] == "pt-001" | |
| assert payload["problem_list"] == ["Type 2 diabetes mellitus"] | |
| def test_ehr_agent_mock_mode_returns_valid_patient_context_for_pt001(monkeypatch) -> None: | |
| """Verify mock mode returns deterministic PatientContext populated from FHIR data. | |
| Args: | |
| monkeypatch (pytest.MonkeyPatch): Fixture used to patch raw context retrieval. | |
| Returns: | |
| None: Assertions verify key context fields for pt-001 fixtures. | |
| """ | |
| monkeypatch.setattr( | |
| "backend.models.ehr_agent.get_full_patient_context", | |
| (lambda patient_id: _async_raw_context(patient_id)), | |
| ) | |
| agent = EHRAgent(model_id="mock") | |
| context = agent.get_patient_context("pt-001") | |
| assert context.patient_id == "pt-001" | |
| assert any("diabetes" in problem.lower() for problem in context.problem_list) | |
| assert any("metformin" in medication["name"].lower() for medication in context.medications) | |
| assert any("penicillin" in allergy["substance"].lower() for allergy in context.allergies) | |
| assert any(lab.name == "HbA1c" and lab.value == "55" for lab in context.recent_labs) | |
| def test_ehr_agent_fallback_path_sets_warning_when_summarisation_fails(monkeypatch) -> None: | |
| """Verify retrieval warnings are added when model summarisation path fails twice. | |
| Args: | |
| monkeypatch (pytest.MonkeyPatch): Fixture for forcing repeated summarisation failures. | |
| Returns: | |
| None: Assertions verify deterministic fallback and warning propagation. | |
| """ | |
| monkeypatch.setattr( | |
| "backend.models.ehr_agent.get_full_patient_context", | |
| (lambda patient_id: _async_raw_context(patient_id)), | |
| ) | |
| agent = EHRAgent(model_id="mock") | |
| agent.is_mock_mode = False | |
| monkeypatch.setattr(agent, "load_model", lambda: None) | |
| def always_fail(_: dict) -> dict: | |
| raise ValueError("invalid model output") | |
| monkeypatch.setattr(agent, "_summarise_with_model", always_fail) | |
| context = agent.get_patient_context("pt-001") | |
| assert context.retrieval_warnings | |
| assert "deterministic extraction" in context.retrieval_warnings[0].lower() | |
| assert context.patient_id == "pt-001" | |