- Implemented tests for ScheduledTaskRepository covering task creation, retrieval, filtering, and status updates. - Developed tests for SchedulerService including task creation, cancellation, user task retrieval, and maintenance jobs. - Created tests for TaskHandlerRegistry to validate task execution for various types, including credit recharge and sound playback. - Ensured proper error handling and edge cases in task execution scenarios. - Added fixtures and mocks to facilitate isolated testing of services and repositories.
220 lines
7.2 KiB
Python
220 lines
7.2 KiB
Python
"""Tests for scheduled task model."""
|
|
|
|
import uuid
|
|
from datetime import datetime, timedelta
|
|
|
|
import pytest
|
|
|
|
from app.models.scheduled_task import (
|
|
RecurrenceType,
|
|
ScheduledTask,
|
|
TaskStatus,
|
|
TaskType,
|
|
)
|
|
|
|
|
|
class TestScheduledTaskModel:
|
|
"""Test cases for scheduled task model."""
|
|
|
|
def test_task_creation(self):
|
|
"""Test basic task creation."""
|
|
task = ScheduledTask(
|
|
name="Test Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
)
|
|
|
|
assert task.name == "Test Task"
|
|
assert task.task_type == TaskType.CREDIT_RECHARGE
|
|
assert task.status == TaskStatus.PENDING
|
|
assert task.timezone == "UTC"
|
|
assert task.recurrence_type == RecurrenceType.NONE
|
|
assert task.parameters == {}
|
|
assert task.user_id is None
|
|
assert task.executions_count == 0
|
|
assert task.is_active is True
|
|
|
|
def test_task_with_user(self):
|
|
"""Test task creation with user association."""
|
|
user_id = uuid.uuid4()
|
|
task = ScheduledTask(
|
|
name="User Task",
|
|
task_type=TaskType.PLAY_SOUND,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
user_id=user_id,
|
|
)
|
|
|
|
assert task.user_id == user_id
|
|
assert not task.is_system_task()
|
|
|
|
def test_system_task(self):
|
|
"""Test system task (no user association)."""
|
|
task = ScheduledTask(
|
|
name="System Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
)
|
|
|
|
assert task.user_id is None
|
|
assert task.is_system_task()
|
|
|
|
def test_recurring_task(self):
|
|
"""Test recurring task properties."""
|
|
task = ScheduledTask(
|
|
name="Recurring Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
recurrence_type=RecurrenceType.DAILY,
|
|
recurrence_count=5,
|
|
)
|
|
|
|
assert task.is_recurring()
|
|
assert task.should_repeat()
|
|
|
|
def test_non_recurring_task(self):
|
|
"""Test non-recurring task properties."""
|
|
task = ScheduledTask(
|
|
name="One-shot Task",
|
|
task_type=TaskType.PLAY_SOUND,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
recurrence_type=RecurrenceType.NONE,
|
|
)
|
|
|
|
assert not task.is_recurring()
|
|
assert not task.should_repeat()
|
|
|
|
def test_infinite_recurring_task(self):
|
|
"""Test infinitely recurring task."""
|
|
task = ScheduledTask(
|
|
name="Infinite Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
recurrence_type=RecurrenceType.DAILY,
|
|
recurrence_count=None, # Infinite
|
|
)
|
|
|
|
assert task.is_recurring()
|
|
assert task.should_repeat()
|
|
|
|
# Even after many executions
|
|
task.executions_count = 100
|
|
assert task.should_repeat()
|
|
|
|
def test_recurring_task_execution_limit(self):
|
|
"""Test recurring task with execution limit."""
|
|
task = ScheduledTask(
|
|
name="Limited Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
recurrence_type=RecurrenceType.DAILY,
|
|
recurrence_count=3,
|
|
)
|
|
|
|
assert task.should_repeat()
|
|
|
|
# After 3 executions, should not repeat
|
|
task.executions_count = 3
|
|
assert not task.should_repeat()
|
|
|
|
# After more than limit, still should not repeat
|
|
task.executions_count = 5
|
|
assert not task.should_repeat()
|
|
|
|
def test_task_expiration(self):
|
|
"""Test task expiration."""
|
|
# Non-expired task
|
|
task = ScheduledTask(
|
|
name="Valid Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
expires_at=datetime.utcnow() + timedelta(hours=2),
|
|
)
|
|
assert not task.is_expired()
|
|
|
|
# Expired task
|
|
expired_task = ScheduledTask(
|
|
name="Expired Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
expires_at=datetime.utcnow() - timedelta(hours=1),
|
|
)
|
|
assert expired_task.is_expired()
|
|
|
|
# Task with no expiration
|
|
no_expiry_task = ScheduledTask(
|
|
name="No Expiry Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
)
|
|
assert not no_expiry_task.is_expired()
|
|
|
|
def test_task_with_parameters(self):
|
|
"""Test task with custom parameters."""
|
|
parameters = {
|
|
"sound_id": str(uuid.uuid4()),
|
|
"volume": 80,
|
|
"repeat": True,
|
|
}
|
|
|
|
task = ScheduledTask(
|
|
name="Parametrized Task",
|
|
task_type=TaskType.PLAY_SOUND,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
parameters=parameters,
|
|
)
|
|
|
|
assert task.parameters == parameters
|
|
assert task.parameters["sound_id"] == parameters["sound_id"]
|
|
assert task.parameters["volume"] == 80
|
|
assert task.parameters["repeat"] is True
|
|
|
|
def test_task_with_timezone(self):
|
|
"""Test task with custom timezone."""
|
|
task = ScheduledTask(
|
|
name="NY Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
timezone="America/New_York",
|
|
)
|
|
|
|
assert task.timezone == "America/New_York"
|
|
|
|
def test_task_with_cron_expression(self):
|
|
"""Test task with cron expression."""
|
|
cron_expr = "0 9 * * 1-5" # 9 AM on weekdays
|
|
|
|
task = ScheduledTask(
|
|
name="Cron Task",
|
|
task_type=TaskType.CREDIT_RECHARGE,
|
|
scheduled_at=datetime.utcnow() + timedelta(hours=1),
|
|
recurrence_type=RecurrenceType.CRON,
|
|
cron_expression=cron_expr,
|
|
)
|
|
|
|
assert task.recurrence_type == RecurrenceType.CRON
|
|
assert task.cron_expression == cron_expr
|
|
assert task.is_recurring()
|
|
|
|
def test_task_status_enum_values(self):
|
|
"""Test all task status enum values."""
|
|
assert TaskStatus.PENDING == "pending"
|
|
assert TaskStatus.RUNNING == "running"
|
|
assert TaskStatus.COMPLETED == "completed"
|
|
assert TaskStatus.FAILED == "failed"
|
|
assert TaskStatus.CANCELLED == "cancelled"
|
|
|
|
def test_task_type_enum_values(self):
|
|
"""Test all task type enum values."""
|
|
assert TaskType.CREDIT_RECHARGE == "credit_recharge"
|
|
assert TaskType.PLAY_SOUND == "play_sound"
|
|
assert TaskType.PLAY_PLAYLIST == "play_playlist"
|
|
|
|
def test_recurrence_type_enum_values(self):
|
|
"""Test all recurrence type enum values."""
|
|
assert RecurrenceType.NONE == "none"
|
|
assert RecurrenceType.HOURLY == "hourly"
|
|
assert RecurrenceType.DAILY == "daily"
|
|
assert RecurrenceType.WEEKLY == "weekly"
|
|
assert RecurrenceType.MONTHLY == "monthly"
|
|
assert RecurrenceType.YEARLY == "yearly"
|
|
assert RecurrenceType.CRON == "cron" |