""" Test session management functionality. """ from datetime import datetime import pytest from freezegun import freeze_time from local_deep_research.web.auth.session_manager import SessionManager class TestSessionManager: """Test the SessionManager class.""" @pytest.fixture def session_manager(self): """Create a SessionManager instance.""" return SessionManager() def test_create_session(self, session_manager): """Test creating a new session.""" session_id = session_manager.create_session("testuser") assert session_id is not None assert len(session_id) > 20 # Should be a long random string assert session_id in session_manager.sessions session_data = session_manager.sessions[session_id] assert session_data["username"] == "testuser" assert session_data["remember_me"] is False assert isinstance(session_data["created_at"], datetime) assert isinstance(session_data["last_access"], datetime) def test_create_session_with_remember_me(self, session_manager): """Test creating a session with remember me enabled.""" session_id = session_manager.create_session( "testuser", remember_me=True ) session_data = session_manager.sessions[session_id] assert session_data["remember_me"] is True def test_validate_session_valid(self, session_manager): """Test validating a valid session.""" session_id = session_manager.create_session("testuser") username = session_manager.validate_session(session_id) assert username == "testuser" # Check that last_access was updated session_data = session_manager.sessions[session_id] assert session_data["last_access"] > session_data["created_at"] def test_validate_session_invalid(self, session_manager): """Test validating an invalid session.""" username = session_manager.validate_session("invalid-session-id") assert username is None def test_session_timeout(self, session_manager): """Test that sessions timeout after the specified period.""" with freeze_time("2024-01-01 12:00:00") as frozen_time: session_id = session_manager.create_session("testuser") # Session should be valid immediately assert session_manager.validate_session(session_id) == "testuser" # Move time forward by 1 hour 59 minutes frozen_time.move_to("2024-01-01 13:59:00") assert session_manager.validate_session(session_id) == "testuser" # Move time forward by 2 hours 1 minute from last access (13:59) # So we need to go to 16:00 for timeout (13:59 + 2:01) frozen_time.move_to("2024-01-01 16:00:00") assert session_manager.validate_session(session_id) is None # Session should be removed assert session_id not in session_manager.sessions def test_remember_me_timeout(self, session_manager): """Test that remember me sessions have longer timeout.""" with freeze_time("2024-01-01 12:00:00") as frozen_time: session_id = session_manager.create_session( "testuser", remember_me=True ) # Move forward 2 days - should still be valid frozen_time.move_to("2024-01-03 12:00:00") assert session_manager.validate_session(session_id) == "testuser" # Move forward 29 days from start - should still be valid frozen_time.move_to("2024-01-30 12:00:00") assert session_manager.validate_session(session_id) == "testuser" # Move forward 30 days + 1 minute from last access (Jan 30) # So we need to go to March 1 for timeout frozen_time.move_to("2024-03-01 12:01:00") assert session_manager.validate_session(session_id) is None def test_destroy_session(self, session_manager): """Test destroying a session.""" session_id = session_manager.create_session("testuser") assert session_id in session_manager.sessions session_manager.destroy_session(session_id) assert session_id not in session_manager.sessions # Destroying non-existent session should not raise error session_manager.destroy_session("non-existent") def test_cleanup_expired_sessions(self, session_manager): """Test cleaning up expired sessions.""" with freeze_time("2024-01-01 12:00:00") as frozen_time: # Create multiple sessions session1 = session_manager.create_session("user1") session2 = session_manager.create_session("user2", remember_me=True) frozen_time.move_to("2024-01-01 13:00:00") session3 = session_manager.create_session("user3") # Move forward 2.5 hours frozen_time.move_to("2024-01-01 15:30:00") # Cleanup session_manager.cleanup_expired_sessions() # Session 1 should be expired (created 3.5 hours ago) assert session1 not in session_manager.sessions # Session 2 should still exist (remember me) assert session2 in session_manager.sessions # Session 3 should be expired (created 2.5 hours ago) assert session3 not in session_manager.sessions def test_get_active_sessions_count(self, session_manager): """Test getting count of active sessions.""" assert session_manager.get_active_sessions_count() == 0 session_manager.create_session("user1") session_manager.create_session("user2") assert session_manager.get_active_sessions_count() == 2 # Add expired session with freeze_time("2024-01-01 12:00:00") as frozen_time: session_manager.create_session("user3") frozen_time.move_to("2024-01-01 15:00:00") # Should cleanup expired sessions and return correct count assert session_manager.get_active_sessions_count() == 2 def test_get_user_sessions(self, session_manager): """Test getting all sessions for a user.""" # Create multiple sessions for same user session1 = session_manager.create_session("testuser") session2 = session_manager.create_session("testuser", remember_me=True) # Create session for different user session_manager.create_session("otheruser") user_sessions = session_manager.get_user_sessions("testuser") assert len(user_sessions) == 2 # Check session info session_ids = [s["session_id"] for s in user_sessions] assert session1[:8] + "..." in session_ids assert session2[:8] + "..." in session_ids # Check remember_me flags remember_flags = [s["remember_me"] for s in user_sessions] assert False in remember_flags assert True in remember_flags