ForcePilot/backend/test/unit/channels/contract/dtos/test_queue.py

114 lines
3.0 KiB
Python
Raw Normal View History

"""queue.py DTO 单元测试。
覆盖 ``EnqueueCmd`` / ``JobId`` / ``JobStatus`` 的字段赋值默认值
不可变语义与 ``__post_init__`` 校验逻辑
"""
from __future__ import annotations
import dataclasses
from datetime import datetime
from typing import Any
import pytest
from yuxi.channels.contract.dtos.queue import (
EnqueueCmd,
JobId,
JobStatus,
)
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
@pytest.mark.unit
class TestEnqueueCmd:
"""入队命令 DTO 测试。"""
def test_required_fields_are_assigned(self):
# Arrange
payload: dict[str, Any] = {"task": "send"}
# Act
cmd = EnqueueCmd(task_name="send_message", payload=payload)
# Assert
assert cmd.task_name == "send_message"
assert cmd.payload is payload
assert cmd.scheduled_at is None
assert cmd.idempotency_key is None
def test_with_optional_fields(self):
# Arrange
now = datetime(2026, 1, 1, 12, 0, 0)
# Act
cmd = EnqueueCmd(
task_name="send_message",
payload={},
scheduled_at=now,
idempotency_key="idem-1",
)
# Assert
assert cmd.scheduled_at is now
assert cmd.idempotency_key == "idem-1"
def test_is_frozen(self):
# Arrange
cmd = EnqueueCmd(task_name="send_message", payload={})
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
cmd.task_name = "other" # type: ignore[misc]
def test_empty_task_name_raises_validation_error(self):
# Arrange
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
EnqueueCmd(task_name="", payload={})
assert exc_info.value.field == "task_name"
@pytest.mark.unit
class TestJobId:
"""任务 ID DTO 测试。"""
def test_value_is_assigned(self):
# Arrange
# Act
job_id = JobId(value="job-1")
# Assert
assert job_id.value == "job-1"
def test_is_frozen(self):
# Arrange
job_id = JobId(value="job-1")
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
job_id.value = "other" # type: ignore[misc]
@pytest.mark.unit
class TestJobStatus:
"""任务状态枚举测试。"""
def test_enum_values_are_correct(self):
# Arrange
# Act
# Assert
assert JobStatus.QUEUED == "queued"
assert JobStatus.RUNNING == "running"
assert JobStatus.COMPLETED == "completed"
assert JobStatus.FAILED == "failed"
assert JobStatus.CANCELLED == "cancelled"
def test_enum_inherits_from_str(self):
# Arrange
# Act
# Assert
assert issubclass(JobStatus, str)
assert isinstance(JobStatus.QUEUED, str)
def test_enum_has_five_members(self):
# Arrange
# Act
members = list(JobStatus)
# Assert
assert len(members) == 5