| """Tests for app/pages/2_profile_review.py — PRESCREEN state.""" |
|
|
| from unittest.mock import patch |
|
|
| import pytest |
| from streamlit.testing.v1 import AppTest |
|
|
| from app.services.mock_data import ( |
| MOCK_ELIGIBILITY_LEDGERS, |
| MOCK_PATIENT_PROFILE, |
| MOCK_TRIAL_CANDIDATES, |
| ) |
|
|
|
|
| @pytest.fixture |
| def profile_app(): |
| at = AppTest.from_file("app/pages/2_profile_review.py", default_timeout=10) |
| at.session_state["journey_state"] = "PRESCREEN" |
| at.session_state["patient_profile"] = MOCK_PATIENT_PROFILE |
| at.session_state["parlant_session_id"] = None |
| at.session_state["parlant_agent_id"] = None |
| at.session_state["uploaded_files"] = [] |
| at.session_state["search_anchors"] = None |
| at.session_state["trial_candidates"] = [] |
| at.session_state["eligibility_ledger"] = [] |
| at.session_state["last_event_offset"] = 0 |
| return at.run() |
|
|
|
|
| def test_page_renders_without_error(profile_app): |
| assert len(profile_app.exception) == 0 |
|
|
|
|
| def test_displays_patient_demographics(profile_app): |
| all_md = " ".join(str(m.value) for m in profile_app.markdown) |
| assert "62" in all_md |
| assert "Female" in all_md |
|
|
|
|
| def test_displays_diagnosis(profile_app): |
| all_md = " ".join(str(m.value) for m in profile_app.markdown) |
| assert "IIIB" in all_md |
|
|
|
|
| def test_displays_biomarkers(profile_app): |
| all_md = " ".join(str(m.value) for m in profile_app.markdown) |
| assert "EGFR" in all_md |
| assert "PD-L1" in all_md |
|
|
|
|
| def test_displays_unknowns(profile_app): |
| all_md = " ".join(str(m.value) for m in profile_app.markdown) |
| assert "KRAS" in all_md |
|
|
|
|
| def test_has_confirm_button(profile_app): |
| labels = [str(b.label) for b in profile_app.button] |
| assert any("confirm" in lbl.lower() or "search" in lbl.lower() for lbl in labels) |
|
|
|
|
| @patch( |
| "app.services.direct_pipeline.run_trial_search_and_evaluate", |
| return_value=(MOCK_TRIAL_CANDIDATES, MOCK_ELIGIBILITY_LEDGERS), |
| ) |
| def test_confirm_advances_to_validate_trials(mock_pipeline, profile_app): |
| confirm_btns = [ |
| b |
| for b in profile_app.button |
| if "confirm" in str(b.label).lower() or "search" in str(b.label).lower() |
| ] |
| if confirm_btns: |
| confirm_btns[0].click() |
| at = profile_app.run() |
| assert at.session_state["journey_state"] == "VALIDATE_TRIALS" |
| assert len(at.exception) == 0 |
|
|
|
|
| def test_guard_without_profile(): |
| """Page should handle missing profile gracefully.""" |
| at = AppTest.from_file("app/pages/2_profile_review.py", default_timeout=10) |
| at.session_state["journey_state"] = "PRESCREEN" |
| at.session_state["patient_profile"] = None |
| at.session_state["parlant_session_id"] = None |
| at.session_state["parlant_agent_id"] = None |
| at.session_state["uploaded_files"] = [] |
| at.session_state["search_anchors"] = None |
| at.session_state["trial_candidates"] = [] |
| at.session_state["eligibility_ledger"] = [] |
| at.session_state["last_event_offset"] = 0 |
| at = at.run() |
| assert len(at.exception) == 0 |
| all_warns = [str(w.value) for w in at.warning] |
| assert any("upload" in w.lower() or "profile" in w.lower() for w in all_warns) |
|
|