TrialPath / app /tests /test_gap_analysis_page.py
yakilee's picture
test: update tests for evidence-linked mock data and new features
f8adedd
"""Tests for app/pages/4_gap_analysis.py — GAP_FOLLOWUP state."""
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 gap_app():
at = AppTest.from_file("app/pages/4_gap_analysis.py", default_timeout=10)
at.session_state["journey_state"] = "GAP_FOLLOWUP"
at.session_state["patient_profile"] = MOCK_PATIENT_PROFILE
at.session_state["trial_candidates"] = MOCK_TRIAL_CANDIDATES
at.session_state["eligibility_ledger"] = MOCK_ELIGIBILITY_LEDGERS
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["last_event_offset"] = 0
return at.run()
def test_page_renders_without_error(gap_app):
assert len(gap_app.exception) == 0
def test_displays_gaps(gap_app):
expander_labels = [str(e.label) for e in gap_app.expander]
all_labels = " ".join(expander_labels)
all_md = " ".join(str(m.value) for m in gap_app.markdown)
combined = all_labels + " " + all_md
assert "Brain MRI" in combined or "EGFR" in combined
def test_displays_recommended_actions(gap_app):
all_md = " ".join(str(m.value) for m in gap_app.markdown)
assert "upload" in all_md.lower() or "request" in all_md.lower()
def test_displays_would_match_phrasing(gap_app):
"""PRD core value proposition: 'You would match [trial] IF you had' phrasing."""
all_md = " ".join(str(m.value) for m in gap_app.markdown)
assert "You would match" in all_md
assert "IF you had" in all_md
def test_has_summary_button(gap_app):
labels = [str(b.label) for b in gap_app.button]
assert any("summary" in lbl.lower() or "generate" in lbl.lower() for lbl in labels)
def test_summary_button_advances_state(gap_app):
summary_btns = [
b
for b in gap_app.button
if "summary" in str(b.label).lower() or "generate" in str(b.label).lower()
]
if summary_btns:
summary_btns[0].click()
at = gap_app.run()
assert at.session_state["journey_state"] == "SUMMARY"
assert len(at.exception) == 0
def test_no_gaps_message():
"""When no gaps exist, page should indicate so."""
from trialpath.models import (
CriterionAssessment,
CriterionDecision,
EligibilityLedger,
OverallAssessment,
)
clean_ledger = EligibilityLedger(
patient_id="P001",
nct_id="NCT04000001",
overall_assessment=OverallAssessment.LIKELY_ELIGIBLE,
criteria=[
CriterionAssessment(
criterion_id="inc_1",
type="inclusion",
text="NSCLC confirmed",
decision=CriterionDecision.MET,
),
],
gaps=[],
)
at = AppTest.from_file("app/pages/4_gap_analysis.py", default_timeout=10)
at.session_state["journey_state"] = "GAP_FOLLOWUP"
at.session_state["patient_profile"] = MOCK_PATIENT_PROFILE
at.session_state["trial_candidates"] = MOCK_TRIAL_CANDIDATES
at.session_state["eligibility_ledger"] = [clean_ledger]
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["last_event_offset"] = 0
at = at.run()
assert len(at.exception) == 0
all_text = " ".join(str(m.value) for m in at.markdown)
all_success = " ".join(str(s.value) for s in at.success)
combined = (all_text + " " + all_success).lower()
assert "no gap" in combined or "no unresolved" in combined or "resolved" in combined