Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .streamlit/config.dark.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[server]
headless = true
enableCORS = false
enableCORS = true
enableXsrfProtection = true

[browser]
Expand All @@ -13,4 +13,3 @@ backgroundColor = "#222222"
secondaryBackgroundColor = "#1E1E1E"
textColor = "#D0CDE8"
font = "sans serif"

3 changes: 1 addition & 2 deletions .streamlit/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[server]
headless = true
enableCORS = false
enableCORS = true
Comment thread
suung marked this conversation as resolved.
enableXsrfProtection = true

[browser]
Expand All @@ -14,4 +14,3 @@ secondaryBackgroundColor = "#FFFFFF"
textColor = "#170843"
font = "sans serif"


2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "report-analyst"
version = "0.8.0rc"
description = "Open Sustainability Analyst - benchmark evaluation, error analysis, and dataset loading for retrieval evaluation"
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.10"
dependencies = [
"pandas",
"numpy",
Expand Down
6 changes: 4 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ importlib_metadata==7.2.1
importlib_resources==6.5.2
iniconfig==2.0.0
isort==6.0.1
itsdangerous==2.2.0
Jinja2==3.1.6
jiter==0.8.2
joblib==1.4.2
Expand Down Expand Up @@ -183,7 +184,7 @@ sqlean.py==3.47.0
sqlite-vec==0.1.6
sqlite-vss==0.1.2
starlette==1.3.1
streamlit==1.54.0
streamlit==1.62.0
streamlit-card==1.0.2
streamlit-option-menu==0.4.0
striprtf==0.0.26
Expand All @@ -202,10 +203,11 @@ typing_extensions==4.12.2
tzdata==2025.1
tzlocal==5.2
urllib3==2.7.0
uvicorn==0.27.1
uvicorn==0.52.4
uvloop==0.21.0
validators==0.34.0
vectors==1.0.0
watchdog==6.0.0
watchfiles==1.0.4
websocket-client==1.8.0
websockets==15.0.1
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
if path not in sys.path:
sys.path.insert(0, path)


@pytest.fixture(scope="session")
def streamlit_app_path():
"""Return the Streamlit app path used by AppTest."""
return project_root / "report_analyst" / "streamlit_app.py"


# Make report_analyst_jobs import optional (ImportError or transitive env/deps failures)
try:
from report_analyst_jobs.event_router import EventRouter
Expand Down
22 changes: 12 additions & 10 deletions tests/test_settings_enterprise_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
from streamlit.testing.v1 import AppTest


def test_enterprise_mode_message_only_when_checked():
def test_enterprise_mode_message_only_when_checked(streamlit_app_path):
"""Test that enterprise mode message only shows when checkbox is checked"""
# Run without USE_S3_UPLOAD env var to test checkbox behavior
with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False):
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Navigate to Settings page
Expand All @@ -40,8 +40,9 @@ def test_enterprise_mode_message_only_when_checked():

# After unchecking, the message should NOT appear
page_text = str(at)
if "Enterprise mode enabled" in page_text:
assert False, "Enterprise mode message should not appear when checkbox is unchecked"
assert (
"Enterprise mode enabled" not in page_text
), "Enterprise mode message should not appear when checkbox is unchecked"

# Now check the checkbox
checkbox.set_value(True)
Expand All @@ -51,11 +52,11 @@ def test_enterprise_mode_message_only_when_checked():
assert checkbox.value is True, "Checkbox should be checked"


def test_enterprise_mode_checkbox_state_persistence():
def test_enterprise_mode_checkbox_state_persistence(streamlit_app_path):
"""Test that checkbox state persists correctly across reruns"""
# Run without USE_S3_UPLOAD env var to test checkbox behavior
with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False):
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Navigate to Settings
Expand All @@ -79,21 +80,22 @@ def test_enterprise_mode_checkbox_state_persistence():

# Check that enterprise mode message is NOT shown when unchecked
page_text = str(at)
if "Enterprise mode enabled" in page_text:
assert False, "Enterprise mode message should NOT appear when checkbox is unchecked"
assert (
"Enterprise mode enabled" not in page_text
), "Enterprise mode message should NOT appear when checkbox is unchecked"

# Rerun - state should persist
at.run(timeout=10)
assert checkbox.value is False, "Checkbox should remain False after rerun"


def test_enterprise_mode_env_var_detection():
def test_enterprise_mode_env_var_detection(streamlit_app_path):
"""Test that the app correctly detects USE_S3_UPLOAD env var"""
# This test verifies the env var detection logic works
# When USE_S3_UPLOAD=true is in env, session state should be True
env_value = os.getenv("USE_S3_UPLOAD", "false").lower() == "true"

at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Navigate to Settings
Expand Down
10 changes: 6 additions & 4 deletions tests/test_streamlit_app_analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ def test_process_document_with_all_keywords():
# os.environ["TEMP_DIR"] = str(temp_dir)


def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_app_temp):
def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_app_temp, streamlit_app_path):
report_analyzer, calls = mocked_report_analyzer

assert test_pdf_in_app_temp.exists()

at = AppTest.from_file(str(PROJECT_ROOT / "report_analyst/streamlit_app.py"))
at = AppTest.from_file(streamlit_app_path)
at.session_state["nav_page"] = "Report Analyst"
at.session_state["analyzer"] = report_analyzer

Expand Down Expand Up @@ -107,12 +107,14 @@ def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_
assert any(expander.label == "PDF Viewer with Chunks" for expander in at.expander)


def test_reanalyze_button_forces_recompute_without_cache_lookup(mocked_report_analyzer, test_pdf_in_app_temp):
def test_reanalyze_button_forces_recompute_without_cache_lookup(
mocked_report_analyzer, test_pdf_in_app_temp, streamlit_app_path
):
report_analyzer, calls = mocked_report_analyzer

assert test_pdf_in_app_temp.exists()

at = AppTest.from_file(str(PROJECT_ROOT / "report_analyst/streamlit_app.py"))
at = AppTest.from_file(streamlit_app_path)
at.session_state["nav_page"] = "Report Analyst"
at.session_state["analyzer"] = report_analyzer

Expand Down
56 changes: 28 additions & 28 deletions tests/test_streamlit_app_backend_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from streamlit.testing.v1 import AppTest


def test_backend_integration_availability():
def test_backend_integration_availability(streamlit_app_path):
"""Test that backend integration features are available"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# The app should load without errors, indicating backend integration is available
Expand All @@ -18,9 +18,9 @@ def test_backend_integration_availability():
# This is verified by the app loading successfully with backend integration


def test_backend_configuration_display():
def test_backend_configuration_display(streamlit_app_path):
"""Test backend configuration display"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend configuration elements
Expand All @@ -30,9 +30,9 @@ def test_backend_configuration_display():
assert not at.exception


def test_backend_flow_orchestrator():
def test_backend_flow_orchestrator(streamlit_app_path):
"""Test backend flow orchestrator functionality"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check that backend flow orchestrator is properly integrated
Expand All @@ -41,9 +41,9 @@ def test_backend_flow_orchestrator():
assert not at.exception


def test_backend_analysis_workflow():
def test_backend_analysis_workflow(streamlit_app_path):
"""Test backend analysis workflow integration"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend analysis workflow elements
Expand All @@ -53,9 +53,9 @@ def test_backend_analysis_workflow():
assert not at.exception


def test_backend_error_handling():
def test_backend_error_handling(streamlit_app_path):
"""Test backend integration error handling"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Backend integration should handle errors gracefully
Expand All @@ -64,9 +64,9 @@ def test_backend_error_handling():
assert not at.exception


def test_backend_fallback_behavior():
def test_backend_fallback_behavior(streamlit_app_path):
"""Test backend integration fallback behavior"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Backend integration should have proper fallback behavior
Expand All @@ -76,9 +76,9 @@ def test_backend_fallback_behavior():
assert not at.exception


def test_backend_config_status():
def test_backend_config_status(streamlit_app_path):
"""Test backend configuration status display"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend configuration status elements
Expand All @@ -88,9 +88,9 @@ def test_backend_config_status():
assert not at.exception


def test_backend_processing_result():
def test_backend_processing_result(streamlit_app_path):
"""Test backend processing result handling"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check that backend processing results are handled properly
Expand All @@ -99,9 +99,9 @@ def test_backend_processing_result():
assert not at.exception


def test_backend_analysis_result():
def test_backend_analysis_result(streamlit_app_path):
"""Test backend analysis result integration"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend analysis result handling
Expand All @@ -110,9 +110,9 @@ def test_backend_analysis_result():
assert not at.exception


def test_backend_integration_imports():
def test_backend_integration_imports(streamlit_app_path):
"""Test that backend integration imports work correctly"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Backend integration imports should work without errors
Expand All @@ -121,9 +121,9 @@ def test_backend_integration_imports():
assert not at.exception


def test_backend_flow_selection():
def test_backend_flow_selection(streamlit_app_path):
"""Test backend flow selection functionality"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend flow selection elements
Expand All @@ -133,9 +133,9 @@ def test_backend_flow_selection():
assert not at.exception


def test_backend_local_analysis():
def test_backend_local_analysis(streamlit_app_path):
"""Test backend local analysis functionality"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Check for backend local analysis capabilities
Expand All @@ -144,9 +144,9 @@ def test_backend_local_analysis():
assert not at.exception


def test_backend_integration_compatibility():
def test_backend_integration_compatibility(streamlit_app_path):
"""Test backend integration compatibility with main app"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10)

# Backend integration should be compatible with the main app
Expand All @@ -164,11 +164,11 @@ def test_backend_integration_compatibility():
assert not at.exception


def test_backend_resource_full_roundtrip():
def test_backend_resource_full_roundtrip(streamlit_app_path):
"""Test full roundtrip: list backend resources, select, retrieve chunks, analyze"""
from unittest.mock import Mock, patch

at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)

# Mock backend configuration
mock_backend_config = Mock()
Expand Down
8 changes: 4 additions & 4 deletions tests/test_streamlit_app_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
from streamlit.testing.v1 import AppTest


def test_app_loads():
def test_app_loads(streamlit_app_path):
"""Test that streamlit_app.py loads without errors"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
at.run(timeout=10) # Increase timeout
assert not at.exception


def test_app_title_and_layout():
def test_app_title_and_layout(streamlit_app_path):
"""Test app displays correct title and basic layout"""
at = AppTest.from_file("report_analyst/streamlit_app.py")
at = AppTest.from_file(streamlit_app_path)
# Navigate to Report Analyst page where title is displayed
at.session_state["nav_page"] = "Report Analyst"
at.run(timeout=10) # Increase timeout
Expand Down
Loading
Loading