"""Tests for Story 5.3: Participant Session. As a logged-in participant, I want to access my dashboard and manage my session. """ from datetime import datetime, timedelta from src.models.exchange import Exchange from src.models.participant import Participant class TestStory53ParticipantSession: """Test suite for Story 5.3: Participant Session.""" def test_participant_dashboard_requires_login(self, client, db): """Test that dashboard redirects to request access if not logged in.""" future_close_date = datetime.utcnow() + timedelta(days=7) future_exchange_date = datetime.utcnow() + timedelta(days=14) exchange = Exchange( slug="test123", name="Test Exchange", budget="$30", max_participants=10, registration_close_date=future_close_date, exchange_date=future_exchange_date, timezone="America/New_York", state=Exchange.STATE_REGISTRATION_OPEN, ) db.session.add(exchange) db.session.commit() # Try to access dashboard without login response = client.get( f"/participant/exchange/{exchange.id}", follow_redirects=False, ) # Should redirect or show error assert response.status_code in [302, 403] def test_logged_in_participant_sees_dashboard(self, client, db): """Test that logged-in participant can access dashboard.""" future_close_date = datetime.utcnow() + timedelta(days=7) future_exchange_date = datetime.utcnow() + timedelta(days=14) exchange = Exchange( slug="test123", name="Test Exchange", budget="$30", max_participants=10, registration_close_date=future_close_date, exchange_date=future_exchange_date, timezone="America/New_York", state=Exchange.STATE_REGISTRATION_OPEN, ) db.session.add(exchange) db.session.flush() participant = Participant( exchange_id=exchange.id, name="John Doe", email="john@example.com", reminder_enabled=True, ) db.session.add(participant) db.session.commit() # Log in as participant with client.session_transaction() as sess: sess["user_id"] = participant.id sess["user_type"] = "participant" sess["exchange_id"] = exchange.id # Access dashboard response = client.get(f"/participant/exchange/{exchange.id}") # Should show dashboard assert response.status_code == 200 assert b"Test Exchange" in response.data assert b"John Doe" in response.data def test_participant_can_logout(self, client, db): """Test that participant can log out.""" future_close_date = datetime.utcnow() + timedelta(days=7) future_exchange_date = datetime.utcnow() + timedelta(days=14) exchange = Exchange( slug="test123", name="Test Exchange", budget="$30", max_participants=10, registration_close_date=future_close_date, exchange_date=future_exchange_date, timezone="America/New_York", state=Exchange.STATE_REGISTRATION_OPEN, ) db.session.add(exchange) db.session.flush() participant = Participant( exchange_id=exchange.id, name="Jane Smith", email="jane@example.com", reminder_enabled=True, ) db.session.add(participant) db.session.commit() # Log in with client.session_transaction() as sess: sess["user_id"] = participant.id sess["user_type"] = "participant" sess["exchange_id"] = exchange.id # Logout response = client.post("/participant/logout", follow_redirects=True) # Should show success message assert response.status_code == 200 assert b"logged out" in response.data def test_participant_cannot_access_other_exchange(self, client, db): """Test that participant cannot access another exchange's dashboard.""" future_close_date = datetime.utcnow() + timedelta(days=7) future_exchange_date = datetime.utcnow() + timedelta(days=14) # Create two exchanges exchange1 = Exchange( slug="exchange1", name="Exchange 1", budget="$30", max_participants=10, registration_close_date=future_close_date, exchange_date=future_exchange_date, timezone="America/New_York", state=Exchange.STATE_REGISTRATION_OPEN, ) exchange2 = Exchange( slug="exchange2", name="Exchange 2", budget="$40", max_participants=10, registration_close_date=future_close_date, exchange_date=future_exchange_date, timezone="America/New_York", state=Exchange.STATE_REGISTRATION_OPEN, ) db.session.add(exchange1) db.session.add(exchange2) db.session.flush() # Create participant for exchange1 participant = Participant( exchange_id=exchange1.id, name="Alice", email="alice@example.com", reminder_enabled=True, ) db.session.add(participant) db.session.commit() # Log in as participant for exchange1 with client.session_transaction() as sess: sess["user_id"] = participant.id sess["user_type"] = "participant" sess["exchange_id"] = exchange1.id # Try to access exchange2's dashboard response = client.get(f"/participant/exchange/{exchange2.id}") # Should be forbidden assert response.status_code == 403 def test_participant_required_decorator_works(self, client): """Test that participant_required decorator protects routes.""" # Try to access protected route without login response = client.get("/participant/exchange/999") # Should redirect or show error assert response.status_code in [302, 403]