| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | 
							- import contextvars
 - import threading
 - from typing import Optional
 - 
 - import pytest
 - from flask import Flask
 - from flask_login import LoginManager, UserMixin, current_user, login_user
 - 
 - from libs.flask_utils import preserve_flask_contexts
 - 
 - 
 - class User(UserMixin):
 -     """Simple User class for testing."""
 - 
 -     def __init__(self, id: str):
 -         self.id = id
 - 
 -     def get_id(self) -> str:
 -         return self.id
 - 
 - 
 - @pytest.fixture
 - def login_app(app: Flask) -> Flask:
 -     """Set up a Flask app with flask-login."""
 -     # Set a secret key for the app
 -     app.config["SECRET_KEY"] = "test-secret-key"
 - 
 -     login_manager = LoginManager()
 -     login_manager.init_app(app)
 - 
 -     @login_manager.user_loader
 -     def load_user(user_id: str) -> Optional[User]:
 -         if user_id == "test_user":
 -             return User("test_user")
 -         return None
 - 
 -     return app
 - 
 - 
 - @pytest.fixture
 - def test_user() -> User:
 -     """Create a test user."""
 -     return User("test_user")
 - 
 - 
 - def test_current_user_not_accessible_across_threads(login_app: Flask, test_user: User):
 -     """
 -     Test that current_user is not accessible in a different thread without preserve_flask_contexts.
 - 
 -     This test demonstrates that without the preserve_flask_contexts, we cannot access
 -     current_user in a different thread, even with app_context.
 -     """
 -     # Log in the user in the main thread
 -     with login_app.test_request_context():
 -         login_user(test_user)
 -         assert current_user.is_authenticated
 -         assert current_user.id == "test_user"
 - 
 -         # Store the result of the thread execution
 -         result = {"user_accessible": True, "error": None}
 - 
 -         # Define a function to run in a separate thread
 -         def check_user_in_thread():
 -             try:
 -                 # Try to access current_user in a different thread with app_context
 -                 with login_app.app_context():
 -                     # This should fail because current_user is not accessible across threads
 -                     # without preserve_flask_contexts
 -                     result["user_accessible"] = current_user.is_authenticated
 -             except Exception as e:
 -                 result["error"] = str(e)  # type: ignore
 - 
 -         # Run the function in a separate thread
 -         thread = threading.Thread(target=check_user_in_thread)
 -         thread.start()
 -         thread.join()
 - 
 -         # Verify that we got an error or current_user is not authenticated
 -         assert result["error"] is not None or (result["user_accessible"] is not None and not result["user_accessible"])
 - 
 - 
 - def test_current_user_accessible_with_preserve_flask_contexts(login_app: Flask, test_user: User):
 -     """
 -     Test that current_user is accessible in a different thread with preserve_flask_contexts.
 - 
 -     This test demonstrates that with the preserve_flask_contexts, we can access
 -     current_user in a different thread.
 -     """
 -     # Log in the user in the main thread
 -     with login_app.test_request_context():
 -         login_user(test_user)
 -         assert current_user.is_authenticated
 -         assert current_user.id == "test_user"
 - 
 -         # Save the context variables
 -         context_vars = contextvars.copy_context()
 - 
 -         # Store the result of the thread execution
 -         result = {"user_accessible": False, "user_id": None, "error": None}
 - 
 -         # Define a function to run in a separate thread
 -         def check_user_in_thread_with_manager():
 -             try:
 -                 # Use preserve_flask_contexts to access current_user in a different thread
 -                 with preserve_flask_contexts(login_app, context_vars):
 -                     from flask_login import current_user
 - 
 -                     if current_user:
 -                         result["user_accessible"] = True
 -                         result["user_id"] = current_user.id
 -                     else:
 -                         result["user_accessible"] = False
 -             except Exception as e:
 -                 result["error"] = str(e)  # type: ignore
 - 
 -         # Run the function in a separate thread
 -         thread = threading.Thread(target=check_user_in_thread_with_manager)
 -         thread.start()
 -         thread.join()
 - 
 -         # Verify that current_user is accessible and has the correct ID
 -         assert result["error"] is None
 -         assert result["user_accessible"] is True
 -         assert result["user_id"] == "test_user"
 
 
  |