ForcePilot/backend/test/unit/channels/contract/dtos/test_ack.py
Kris 08617091dc refactor: 整理项目包结构与导入路径
- 新增多个业务域的__init__.py模块文件,规范包导出结构
- 调整多个DTO文件的导入路径,统一模块组织方式
- 移除测试文件中多余的空行与导入语句
- 优化部分业务模块的包层级划分
2026-07-18 02:04:03 +08:00

123 lines
3.3 KiB
Python

"""ack.py DTO 单元测试。
覆盖 ``AckPolicy`` / ``AckStage`` 枚举与 ``AckDecision`` 的字段赋值、
不可变语义与 ``__post_init__`` 校验逻辑。
"""
from __future__ import annotations
import dataclasses
import pytest
from yuxi.channels.contract.dtos.messaging.ack import (
AckDecision,
AckPolicy,
AckStage,
)
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
@pytest.mark.unit
class TestAckPolicy:
"""ACK 策略枚举测试。"""
def test_enum_values_are_correct(self):
# Arrange
# Act
# Assert
assert AckPolicy.AFTER_RECORD == "after_record"
assert AckPolicy.AFTER_AGENT_DISPATCH == "after_agent_dispatch"
assert AckPolicy.AFTER_PERSIST == "after_persist"
assert AckPolicy.MANUAL == "manual"
def test_enum_inherits_from_str(self):
# Arrange
# Act
# Assert
assert issubclass(AckPolicy, str)
assert isinstance(AckPolicy.MANUAL, str)
def test_enum_has_four_members(self):
# Arrange
# Act
members = list(AckPolicy)
# Assert
assert len(members) == 4
@pytest.mark.unit
class TestAckStage:
"""ACK 阶段枚举测试。"""
def test_enum_values_are_correct(self):
# Arrange
# Act
# Assert
assert AckStage.RECORD == "record"
assert AckStage.DISPATCH == "dispatch"
assert AckStage.PERSIST == "persist"
assert AckStage.MANUAL == "manual"
def test_enum_inherits_from_str(self):
# Arrange
# Act
# Assert
assert issubclass(AckStage, str)
assert isinstance(AckStage.RECORD, str)
def test_enum_has_four_members(self):
# Arrange
# Act
members = list(AckStage)
# Assert
assert len(members) == 4
@pytest.mark.unit
class TestAckDecision:
"""ACK 决策 DTO 测试。"""
def test_fields_are_assigned(self):
# Arrange
# Act
decision = AckDecision(decision="ack", stage=AckStage.RECORD)
# Assert
assert decision.decision == "ack"
assert decision.stage is AckStage.RECORD
assert decision.idempotency_key is None
def test_with_idempotency_key(self):
# Arrange
# Act
decision = AckDecision(
decision="nack",
stage=AckStage.DISPATCH,
idempotency_key="idem-1",
)
# Assert
assert decision.idempotency_key == "idem-1"
@pytest.mark.parametrize("action", ["ack", "nack", "retry", "pending"])
def test_valid_decisions(self, action):
# Arrange
# Act
decision = AckDecision(decision=action, stage=AckStage.RECORD)
# Assert
assert decision.decision == action
def test_invalid_decision_raises_validation_error(self):
# Arrange
# Act / Assert - decision 不在合法取值集合中
with pytest.raises(ValidationError) as exc_info:
AckDecision(decision="invalid", stage=AckStage.RECORD) # type: ignore[arg-type]
assert exc_info.value.field == "decision"
def test_is_frozen(self):
# Arrange
decision = AckDecision(decision="ack", stage=AckStage.RECORD)
# Act / Assert
with pytest.raises(dataclasses.FrozenInstanceError):
decision.decision = "nack" # type: ignore[misc]