"""Tests for scheduler service.""" from unittest.mock import AsyncMock, patch import pytest from sqlmodel.ext.asyncio.session import AsyncSession from app.services.scheduler import SchedulerService class TestSchedulerService: """Test scheduler service functionality.""" @pytest.fixture def mock_db_session_factory(self): """Create a mock database session factory.""" session = AsyncMock(spec=AsyncSession) return lambda: session @pytest.fixture def scheduler_service(self, mock_db_session_factory): """Create a scheduler service instance for testing.""" return SchedulerService(mock_db_session_factory) @pytest.mark.asyncio async def test_start_scheduler(self, scheduler_service) -> None: """Test starting the scheduler service.""" with patch.object(scheduler_service.scheduler, "add_job") as mock_add_job, \ patch.object(scheduler_service.scheduler, "start") as mock_start: await scheduler_service.start() # Verify job was added mock_add_job.assert_called_once_with( scheduler_service._daily_credit_recharge, "cron", hour=0, minute=0, id="daily_credit_recharge", name="Daily Credit Recharge", replace_existing=True, ) # Verify scheduler was started mock_start.assert_called_once() @pytest.mark.asyncio async def test_stop_scheduler(self, scheduler_service) -> None: """Test stopping the scheduler service.""" with patch.object(scheduler_service.scheduler, "shutdown") as mock_shutdown: await scheduler_service.stop() mock_shutdown.assert_called_once() @pytest.mark.asyncio async def test_daily_credit_recharge_success(self, scheduler_service) -> None: """Test successful daily credit recharge task.""" mock_stats = { "total_users": 10, "recharged_users": 8, "skipped_users": 2, "total_credits_added": 500, } with patch.object(scheduler_service.credit_service, "recharge_all_users_credits") as mock_recharge: mock_recharge.return_value = mock_stats await scheduler_service._daily_credit_recharge() mock_recharge.assert_called_once() @pytest.mark.asyncio async def test_daily_credit_recharge_failure(self, scheduler_service) -> None: """Test daily credit recharge task with failure.""" with patch.object(scheduler_service.credit_service, "recharge_all_users_credits") as mock_recharge: mock_recharge.side_effect = Exception("Database error") # Should not raise exception, just log it await scheduler_service._daily_credit_recharge() mock_recharge.assert_called_once()