Download tests/test_interview_api.py from build-small-hackathon/dental-soap: direct link, hf CLI and curl.
- Browser
- Download file 2.44 kB
-
https://huggingface.co/spaces/build-small-hackathon/dental-soap/resolve/main/tests/test_interview_api.py
- Command line
-
hf download hf://spaces/build-small-hackathon/dental-soap/tests/test_interview_api.py
-
curl -L -o test_interview_api.py https://huggingface.co/spaces/build-small-hackathon/dental-soap/resolve/main/tests/test_interview_api.py
2.44 kB
| """Stateless REST endpoint for the guided interview. | |
| Raw HTTP callers can't satisfy Gradio's hidden gr.State input on the UI | |
| endpoints (/info advertises 2 params, the REST validator wants 3 — upstream | |
| inconsistency, found in the June 6 live API check). interview_api carries the | |
| state as an opaque JSON string instead, so a plain curl works end to end. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import pytest | |
| import app as app_mod | |
| def test_interview_api_starts_fresh_and_returns_state(): | |
| result = app_mod.interview_api("Sam, 34") | |
| assert result["reply"].endswith("?") | |
| assert not result["done"] | |
| assert not result["early_exit"] | |
| state = json.loads(result["state"]) | |
| assert state["user_turns"] == ["Sam, 34"] | |
| assert state["patient_age"] == 34 | |
| def test_interview_api_round_trip_continues_interview(): | |
| first = app_mod.interview_api("Sam, 34") | |
| second = app_mod.interview_api("My crown feels high when I bite.", first["state"]) | |
| state = json.loads(second["state"]) | |
| assert state["user_turns"] == ["Sam, 34", "My crown feels high when I bite."] | |
| assert not second["done"] | |
| def test_interview_api_runs_deterministic_sentinel(): | |
| """The emergency interrupt must fire over the raw API exactly as in the UI.""" | |
| result = app_mod.interview_api( | |
| "I have no pain but I cannot breathe properly and my throat is swelling" | |
| ) | |
| assert result["early_exit"] | |
| assert result["done"] | |
| assert result["hard_findings"] | |
| assert "urgent" in result["reply"].lower() or "emergency" in result["reply"].lower() | |
| def test_interview_api_rejects_malformed_state(): | |
| with pytest.raises(ValueError): | |
| app_mod.interview_api("hello", "{not valid json") | |
| def test_interview_api_rejects_state_with_wrong_fields(): | |
| with pytest.raises(ValueError): | |
| app_mod.interview_api("hello", json.dumps({"phase": "demographics", "bogus": 1})) | |
| def test_interview_api_rejects_unknown_phase(): | |
| """Crafted phase must raise a clean ValueError, not 500 via KeyError in step().""" | |
| with pytest.raises(ValueError): | |
| app_mod.interview_api("hello", json.dumps({"phase": "hacked"})) | |
| def test_interview_api_rejects_oversized_turn_history(): | |
| """Replayed token may not exceed the interview's own turn cap (prompt inflation).""" | |
| bloated = json.dumps({"user_turns": ["tooth hurts"] * 1000}) | |
| with pytest.raises(ValueError): | |
| app_mod.interview_api("hello", bloated) | |