import pytest from unittest.mock import Mock, patch, MagicMock from datetime import datetime, timedelta from threading import Thread from app.scheduler import Scheduler def test_scheduler_initialization(): """Test that Scheduler initializes correctly.""" # Create a mock app mock_app = Mock() # Initialize scheduler scheduler = Scheduler(mock_app, interval_minutes=10) # Verify initialization assert scheduler.app == mock_app assert scheduler.interval == 600 # 10 minutes in seconds assert scheduler.thread is None assert scheduler.running is False def test_scheduler_init_app(): """Test that init_app method works correctly.""" # Create a mock app mock_app = Mock() mock_app.extensions = {} # Initialize scheduler scheduler = Scheduler() scheduler.init_app(mock_app) # Verify scheduler is stored in app extensions assert 'scheduler' in mock_app.extensions assert mock_app.extensions['scheduler'] == scheduler def test_scheduler_start_stop(): """Test that scheduler can be started and stopped.""" # Create a mock app mock_app = Mock() mock_app.app_context.return_value.__enter__.return_value = None mock_app.app_context.return_value.__exit__.return_value = None # Initialize scheduler scheduler = Scheduler(mock_app) # Start the scheduler with patch('app.scheduler.Scheduler._run') as mock_run: mock_run.side_effect = lambda: setattr(scheduler, 'running', False) # Stop after one iteration scheduler.start() # Give it a moment to start import time time.sleep(0.1) # Verify thread was created and started assert scheduler.thread is not None assert scheduler.running is True # Wait for the run method to complete if scheduler.thread: scheduler.thread.join(timeout=1) # Stop should be called automatically when running becomes False assert scheduler.running is False def test_scheduler_process_all_users_no_users(): """Test process_all_users with no users in database.""" # Create a mock app mock_app = Mock() mock_app.app_context.return_value.__enter__.return_value = None mock_app.app_context.return_value.__exit__.return_value = None # Initialize scheduler scheduler = Scheduler(mock_app) # Mock the User query with patch('app.scheduler.User') as mock_user: mock_user.query.all.return_value = [] # Call process_all_users with patch('app.scheduler.Scheduler.logger') as mock_logger: scheduler.process_all_users() # Verify logger was called mock_logger.info.assert_any_call("No users found for processing") def test_scheduler_process_all_users_with_users(): """Test process_all_users with users in database.""" # Create a mock app mock_app = Mock() mock_app.app_context.return_value.__enter__.return_value = None mock_app.app_context.return_value.__exit__.return_value = None # Initialize scheduler scheduler = Scheduler(mock_app) # Create mock users mock_user1 = Mock() mock_user1.id = 1 mock_user1.email = 'user1@example.com' # Mock the User query with patch('app.scheduler.User') as mock_user_class: mock_user_class.query.all.return_value = [mock_user1] # Mock the EmailProcessor with patch('app.scheduler.EmailProcessor') as mock_processor: mock_processor_instance = mock_processor.return_value mock_processor_instance.process_user_emails.return_value = { 'success_count': 5, 'error_count': 0, 'processed_folders': [] } # Call process_all_users with patch('app.scheduler.Scheduler.logger') as mock_logger: scheduler.process_all_users() # Verify processor was called mock_processor.assert_called_once_with(mock_user1) mock_processor_instance.process_user_emails.assert_called_once() # Verify logging mock_logger.info.assert_any_call("Processing emails for 1 users") mock_logger.info.assert_any_call( f"Completed processing for user {mock_user1.email}: 5 success, 0 errors, 0 folders processed" )