1. 删除了 test/unit/external_systems/framework/ 下的废弃空测试目录 2. 修复多处测试断言逻辑、参数传递与测试数据构造 3. 新增日志级别、缓存令牌、流事件等DTO单元测试 4. 补充路由绑定、会话仓储、outbox仓储的测试覆盖 5. 更新测试用例中的异常类型、参数校验与业务逻辑断言
241 lines
7.1 KiB
Python
241 lines
7.1 KiB
Python
"""mention.py DTO 单元测试。
|
|
|
|
覆盖 ``MentionType`` / ``ImplicitMentionKind`` / ``MentionTargetKind`` 枚举
|
|
与 ``MentionTarget`` / ``MentionContext`` / ``InboundMentionPolicy`` /
|
|
``InboundMentionFact`` / ``MentionDecision`` 的字段赋值、默认值、不可变
|
|
语义与 ``__post_init__`` 校验逻辑。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
|
|
import pytest
|
|
from yuxi.channels.contract.dtos.mention import (
|
|
ImplicitMentionKind,
|
|
InboundMentionFact,
|
|
InboundMentionPolicy,
|
|
MentionContext,
|
|
MentionDecision,
|
|
MentionTarget,
|
|
MentionTargetKind,
|
|
MentionType,
|
|
)
|
|
from yuxi.channels.contract.errors import ValidationError
|
|
|
|
pytestmark = pytest.mark.unit
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMentionType:
|
|
"""提及类型枚举测试。"""
|
|
|
|
def test_enum_values_are_correct(self):
|
|
assert MentionType.EXPLICIT == "explicit"
|
|
assert MentionType.IMPLICIT == "implicit"
|
|
assert MentionType.NONE == "none"
|
|
|
|
def test_enum_inherits_from_str(self):
|
|
assert issubclass(MentionType, str)
|
|
|
|
def test_enum_has_three_members(self):
|
|
assert len(list(MentionType)) == 3
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestImplicitMentionKind:
|
|
"""隐式提及类型枚举测试。"""
|
|
|
|
def test_enum_values_are_correct(self):
|
|
assert ImplicitMentionKind.REPLY_TO_BOT == "reply_to_bot"
|
|
assert ImplicitMentionKind.QUOTED_BOT == "quoted_bot"
|
|
assert ImplicitMentionKind.BOT_THREAD_PARTICIPANT == "bot_thread_participant"
|
|
assert ImplicitMentionKind.NATIVE == "native"
|
|
|
|
def test_enum_has_four_members(self):
|
|
assert len(list(ImplicitMentionKind)) == 4
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMentionTargetKind:
|
|
"""提及目标类型枚举测试。"""
|
|
|
|
def test_enum_values_are_correct(self):
|
|
assert MentionTargetKind.USER == "user"
|
|
assert MentionTargetKind.AGENT == "agent"
|
|
assert MentionTargetKind.BOT == "bot"
|
|
|
|
def test_enum_has_three_members(self):
|
|
assert len(list(MentionTargetKind)) == 3
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMentionTarget:
|
|
"""提及目标 DTO 测试。"""
|
|
|
|
def test_fields_are_assigned(self):
|
|
# Arrange
|
|
# Act
|
|
target = MentionTarget(id="user-1", kind=MentionTargetKind.USER)
|
|
# Assert
|
|
assert target.id == "user-1"
|
|
assert target.kind is MentionTargetKind.USER
|
|
assert target.display_name is None
|
|
|
|
def test_with_display_name(self):
|
|
# Arrange
|
|
# Act
|
|
target = MentionTarget(id="agent-1", kind=MentionTargetKind.AGENT, display_name="助手")
|
|
# Assert
|
|
assert target.display_name == "助手"
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
target = MentionTarget(id="user-1", kind=MentionTargetKind.USER)
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
target.id = "other" # type: ignore[misc]
|
|
|
|
def test_empty_id_raises_validation_error(self):
|
|
# Arrange
|
|
# Act / Assert
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
MentionTarget(id="", kind=MentionTargetKind.USER)
|
|
assert exc_info.value.field == "id"
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMentionContext:
|
|
"""提及上下文 DTO 测试。"""
|
|
|
|
def test_required_fields_are_assigned(self):
|
|
# Arrange
|
|
# Act
|
|
ctx = MentionContext(type=MentionType.EXPLICIT)
|
|
# Assert
|
|
assert ctx.type is MentionType.EXPLICIT
|
|
assert ctx.mentioned_users == ()
|
|
assert ctx.implicit_kind is None
|
|
assert ctx.mentioned_targets == ()
|
|
assert ctx.target_agent_ids == ()
|
|
|
|
def test_with_all_fields(self):
|
|
# Arrange
|
|
target = MentionTarget(id="agent-1", kind=MentionTargetKind.AGENT)
|
|
# Act
|
|
ctx = MentionContext(
|
|
type=MentionType.IMPLICIT,
|
|
mentioned_users=("user-1",),
|
|
implicit_kind=ImplicitMentionKind.REPLY_TO_BOT,
|
|
mentioned_targets=(target,),
|
|
target_agent_ids=("agent-1",),
|
|
)
|
|
# Assert
|
|
assert ctx.mentioned_users == ("user-1",)
|
|
assert ctx.implicit_kind is ImplicitMentionKind.REPLY_TO_BOT
|
|
assert ctx.mentioned_targets == (target,)
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
ctx = MentionContext(type=MentionType.NONE)
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
ctx.type = MentionType.EXPLICIT # type: ignore[misc]
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestInboundMentionPolicy:
|
|
"""入站提及策略 DTO 测试。"""
|
|
|
|
def test_defaults_are_correct(self):
|
|
# Arrange
|
|
# Act
|
|
policy = InboundMentionPolicy()
|
|
# Assert
|
|
assert policy.allowed_implicit_kinds == ()
|
|
|
|
def test_with_kinds(self):
|
|
# Arrange
|
|
# Act
|
|
policy = InboundMentionPolicy(
|
|
allowed_implicit_kinds=(ImplicitMentionKind.REPLY_TO_BOT,)
|
|
)
|
|
# Assert
|
|
assert policy.allowed_implicit_kinds == (ImplicitMentionKind.REPLY_TO_BOT,)
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
policy = InboundMentionPolicy()
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
policy.allowed_implicit_kinds = () # type: ignore[misc]
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestInboundMentionFact:
|
|
"""入站提及事实 DTO 测试。"""
|
|
|
|
def test_required_fields_are_assigned(self):
|
|
# Arrange
|
|
# Act
|
|
fact = InboundMentionFact(
|
|
can_detect=True, is_mentioned=True, has_any_mention=True
|
|
)
|
|
# Assert
|
|
assert fact.can_detect is True
|
|
assert fact.is_mentioned is True
|
|
assert fact.has_any_mention is True
|
|
assert fact.implicit_kinds == ()
|
|
|
|
def test_with_implicit_kinds(self):
|
|
# Arrange
|
|
# Act
|
|
fact = InboundMentionFact(
|
|
can_detect=True,
|
|
is_mentioned=True,
|
|
has_any_mention=True,
|
|
implicit_kinds=(ImplicitMentionKind.NATIVE,),
|
|
)
|
|
# Assert
|
|
assert fact.implicit_kinds == (ImplicitMentionKind.NATIVE,)
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
fact = InboundMentionFact(can_detect=False, is_mentioned=False, has_any_mention=False)
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
fact.can_detect = True # type: ignore[misc]
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMentionDecision:
|
|
"""提及决策 DTO 测试。"""
|
|
|
|
def test_defaults_are_correct(self):
|
|
# Arrange
|
|
# Act
|
|
decision = MentionDecision()
|
|
# Assert
|
|
assert decision.bypass_mention_requirement is False
|
|
assert decision.skip_message is False
|
|
assert decision.is_mentioned is False
|
|
|
|
def test_custom_values(self):
|
|
# Arrange
|
|
# Act
|
|
decision = MentionDecision(
|
|
bypass_mention_requirement=True,
|
|
skip_message=False,
|
|
is_mentioned=True,
|
|
)
|
|
# Assert
|
|
assert decision.bypass_mention_requirement is True
|
|
assert decision.is_mentioned is True
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
decision = MentionDecision()
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
decision.skip_message = True # type: ignore[misc]
|