- Updated type hints from List/Optional to list/None for better readability and consistency across the codebase. - Refactored import statements for better organization and clarity. - Enhanced the ScheduledTaskBase schema to use modern type hints. - Cleaned up unnecessary comments and whitespace in various files. - Improved error handling and logging in task execution handlers. - Updated test cases to reflect changes in type hints and ensure compatibility with the new structure.
219 lines
7.2 KiB
Python
219 lines
7.2 KiB
Python
"""Tests for scheduled task model."""
|
|
|
|
import uuid
|
|
from datetime import datetime, timedelta
|
|
|
|
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"
|