Spaces:
Sleeping
Sleeping
| """The combined service serves both products: scriber /api/v1/* and | |
| interpreter /api/* + /ws/* from one FastAPI app with one lifespan.""" | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| import tempfile | |
| import unittest | |
| from pathlib import Path | |
| REPO_ROOT = Path(__file__).resolve().parents[2] | |
| sys.path.insert(0, str(REPO_ROOT / "scribe")) | |
| sys.path.insert(0, str(REPO_ROOT / "interpreter")) | |
| # Hermetic keyless config for both products (same pattern as test_api.py). | |
| os.environ.setdefault("ASR_PROVIDER", "mock") | |
| os.environ.setdefault("ALLOW_MOCK_ASR", "true") | |
| os.environ.setdefault("LLM_PROVIDER", "offline") | |
| os.environ.setdefault("MEDICAL_LEXICON_PATH", str(REPO_ROOT / "data" / "medical_lexicon.json")) | |
| os.environ.setdefault("CAREPATH_ENV_FILE", "__tests_no_env__") | |
| os.environ.setdefault("PROVIDER_MODE", "mock") | |
| _TMP_DB = Path(tempfile.mkdtemp(prefix="carepath_combined_")) / "combined.db" | |
| os.environ["DATABASE_URL"] = f"sqlite:///{_TMP_DB.as_posix()}" | |
| from fastapi.testclient import TestClient | |
| import app.config as interpreter_config | |
| import app.db as interpreter_db | |
| from carepath.main import SITE_DIST_DIR, app, get_pipeline, get_settings | |
| class CombinedAppTests(unittest.TestCase): | |
| def setUpClass(cls) -> None: | |
| get_settings.cache_clear() | |
| get_pipeline.cache_clear() | |
| interpreter_config.get_settings.cache_clear() | |
| interpreter_db.set_engine(None) | |
| def test_lifespan_boots_both_products_and_serves_both_apis(self) -> None: | |
| # The context manager runs the combined lifespan: scriber warmup plus | |
| # interpreter init_db/seed_glossary/purge. | |
| with TestClient(app) as client: | |
| scriber_health = client.get("/api/v1/health") | |
| self.assertEqual(scriber_health.status_code, 200, scriber_health.text) | |
| self.assertEqual(scriber_health.json()["asr_provider"], "mock") | |
| interpreter_health = client.get("/api/health") | |
| self.assertEqual(interpreter_health.status_code, 200, interpreter_health.text) | |
| self.assertEqual(interpreter_health.json()["provider_mode"], "mock") | |
| created = client.post( | |
| "/api/sessions", | |
| json={"consent": {"language": "vi", "accepted": True}}, | |
| ) | |
| self.assertEqual(created.status_code, 201, created.text) | |
| session_id = created.json()["session_id"] | |
| with client.websocket_connect(f"/ws/sessions/{session_id}") as websocket: | |
| snapshot = websocket.receive_json() | |
| self.assertEqual(snapshot["type"], "session_state") | |
| self.assertEqual(snapshot["turns"], []) | |
| def test_clinical_notes_route_serves_the_site_entrypoint(self) -> None: | |
| with TestClient(app) as client: | |
| response = client.get("/ghi-chep-lam-sang/") | |
| self.assertEqual(response.status_code, 200, response.text) | |
| self.assertIn('id="root"', response.text) | |
| def test_public_interpreter_browser_paths_are_blocked(self) -> None: | |
| with TestClient(app) as client: | |
| responses = [ | |
| client.get("/phien-dich-y-khoa/"), | |
| client.get("/phien-dich-y-khoa/assets/index.js"), | |
| client.get("/console"), | |
| client.get("/console/?lang=en"), | |
| ] | |
| for response in responses: | |
| self.assertEqual(response.status_code, 404, response.text) | |
| if __name__ == "__main__": | |
| unittest.main() | |