feat: implement mvp with email-first login flow and langgraph architecture

This commit is contained in:
Yunxiao Xu
2026-02-09 23:22:30 -08:00
parent af227d40e6
commit 5a943b902a
79 changed files with 8200 additions and 1 deletions

83
tests/test_app_auth.py Normal file
View File

@@ -0,0 +1,83 @@
import pytest
from unittest.mock import MagicMock, patch
from streamlit.testing.v1 import AppTest
from ea_chatbot.auth import AuthType
@pytest.fixture
def mock_history_manager_instance():
# We need to patch before the AppTest loads the module
with patch("ea_chatbot.history.manager.HistoryManager") as mock_cls:
instance = mock_cls.return_value
yield instance
def test_auth_ui_flow_step1_to_password(mock_history_manager_instance):
"""Test UI transition from Step 1 (email) to Step 2a (password) for LOCAL user."""
# Patch BEFORE creating AppTest
mock_user = MagicMock()
mock_user.password_hash = "hashed_password"
mock_history_manager_instance.get_user.return_value = mock_user
at = AppTest.from_file("src/ea_chatbot/app.py")
at.run()
# Step 1: Identification
assert at.session_state["login_step"] == "email"
at.text_input[0].set_value("local@example.com")
at.button[0].click().run()
# Verify transition to password step
assert at.session_state["login_step"] == "login_password"
assert at.session_state["login_email"] == "local@example.com"
assert "Welcome back" in at.info[0].value
def test_auth_ui_flow_step1_to_register(mock_history_manager_instance):
"""Test UI transition from Step 1 (email) to Step 2b (registration) for NEW user."""
mock_history_manager_instance.get_user.return_value = None
at = AppTest.from_file("src/ea_chatbot/app.py")
at.run()
# Step 1: Identification
at.text_input[0].set_value("new@example.com")
at.button[0].click().run()
# Verify transition to registration step
assert at.session_state["login_step"] == "register_details"
assert at.session_state["login_email"] == "new@example.com"
assert "Create an account" in at.info[0].value
def test_auth_ui_flow_step1_to_oidc(mock_history_manager_instance):
"""Test UI transition from Step 1 (email) to Step 2c (OIDC) for OIDC user."""
# Mock history_manager.get_user to return a user WITHOUT a password
mock_user = MagicMock()
mock_user.password_hash = None
mock_history_manager_instance.get_user.return_value = mock_user
at = AppTest.from_file("src/ea_chatbot/app.py")
at.run()
# Step 1: Identification
at.text_input[0].set_value("oidc@example.com")
at.button[0].click().run()
# Verify transition to OIDC step
assert at.session_state["login_step"] == "oidc_login"
assert at.session_state["login_email"] == "oidc@example.com"
assert "configured for Single Sign-On" in at.info[0].value
def test_auth_ui_flow_back_button(mock_history_manager_instance):
"""Test that the 'Back' button returns to Step 1."""
at = AppTest.from_file("src/ea_chatbot/app.py")
# Simulate being on Step 2a
at.session_state["login_step"] = "login_password"
at.session_state["login_email"] = "local@example.com"
at.run()
# Click Back (index 1 in Step 2a)
at.button[1].click().run()
# Verify return to email step
assert at.session_state["login_step"] == "email"