1. 删除了 test/unit/external_systems/framework/ 下的废弃空测试目录 2. 修复多处测试断言逻辑、参数传递与测试数据构造 3. 新增日志级别、缓存令牌、流事件等DTO单元测试 4. 补充路由绑定、会话仓储、outbox仓储的测试覆盖 5. 更新测试用例中的异常类型、参数校验与业务逻辑断言
145 lines
4.1 KiB
Python
145 lines
4.1 KiB
Python
"""identity.py DTO 单元测试。
|
|
|
|
覆盖 ``UnifiedIdentityId`` / ``IdentityConfidence`` /
|
|
``IdentityResolveResult`` / ``IdentityProviderConfig`` /
|
|
``IdentityResolveCmd`` 的字段赋值、默认值、不可变语义与
|
|
``__post_init__`` 校验逻辑。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
|
|
import pytest
|
|
from yuxi.channels.contract.dtos.channel import ChannelType
|
|
from yuxi.channels.contract.dtos.identity import (
|
|
IdentityConfidence,
|
|
IdentityProviderConfig,
|
|
IdentityResolveCmd,
|
|
IdentityResolveResult,
|
|
UnifiedIdentityId,
|
|
)
|
|
from yuxi.channels.contract.errors import ValidationError
|
|
|
|
pytestmark = pytest.mark.unit
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestUnifiedIdentityId:
|
|
"""统一身份 ID DTO 测试。"""
|
|
|
|
def test_value_is_assigned(self):
|
|
# Act
|
|
identity_id = UnifiedIdentityId(value="uid-001")
|
|
# Assert
|
|
assert identity_id.value == "uid-001"
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
identity_id = UnifiedIdentityId(value="uid-001")
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
identity_id.value = "other" # type: ignore[misc]
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestIdentityConfidence:
|
|
"""身份置信度枚举测试。"""
|
|
|
|
def test_str_values(self):
|
|
assert IdentityConfidence.HIGH == "high"
|
|
assert IdentityConfidence.MEDIUM == "medium"
|
|
assert IdentityConfidence.LOW == "low"
|
|
|
|
def test_rank_ordering(self):
|
|
# Assert
|
|
assert IdentityConfidence.LOW._rank < IdentityConfidence.MEDIUM._rank
|
|
assert IdentityConfidence.MEDIUM._rank < IdentityConfidence.HIGH._rank
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestIdentityResolveResult:
|
|
"""身份解析结果 DTO 测试。"""
|
|
|
|
def test_fields_are_assigned_with_defaults(self):
|
|
# Act
|
|
result = IdentityResolveResult(
|
|
unified_identity_id=UnifiedIdentityId(value="uid-1"),
|
|
identity_type="email",
|
|
confidence=0.95,
|
|
)
|
|
# Assert
|
|
assert result.metadata is None
|
|
assert result.resolved_user_id is None
|
|
assert result.channel_type is None
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
result = IdentityResolveResult(
|
|
unified_identity_id=UnifiedIdentityId(value="uid-1"),
|
|
identity_type="email",
|
|
confidence=0.5,
|
|
)
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
result.confidence = 0.9 # type: ignore[misc]
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestIdentityProviderConfig:
|
|
"""身份提供者配置 DTO 测试。"""
|
|
|
|
def test_defaults(self):
|
|
# Act
|
|
config = IdentityProviderConfig(name="phone_resolver")
|
|
# Assert
|
|
assert config.enabled is True
|
|
assert config.priority == 100
|
|
assert config.config is None
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestIdentityResolveCmd:
|
|
"""身份解析命令 DTO 测试。"""
|
|
|
|
def test_valid_construction(self):
|
|
# Act
|
|
cmd = IdentityResolveCmd(
|
|
channel_type=ChannelType("wechat"),
|
|
peer_id="peer-1",
|
|
account_id="acc-1",
|
|
)
|
|
# Assert
|
|
assert cmd.metadata is None
|
|
|
|
def test_is_frozen(self):
|
|
# Arrange
|
|
cmd = IdentityResolveCmd(
|
|
channel_type=ChannelType("wechat"),
|
|
peer_id="peer-1",
|
|
account_id="acc-1",
|
|
)
|
|
# Act / Assert
|
|
with pytest.raises(dataclasses.FrozenInstanceError):
|
|
cmd.peer_id = "other" # type: ignore[misc]
|
|
|
|
def test_empty_peer_id_raises(self):
|
|
# Act / Assert
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
IdentityResolveCmd(
|
|
channel_type=ChannelType("wechat"),
|
|
peer_id="",
|
|
account_id="acc-1",
|
|
)
|
|
assert exc_info.value.field == "peer_id"
|
|
|
|
def test_empty_account_id_raises(self):
|
|
# Act / Assert
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
IdentityResolveCmd(
|
|
channel_type=ChannelType("wechat"),
|
|
peer_id="peer-1",
|
|
account_id="",
|
|
)
|
|
assert exc_info.value.field == "account_id"
|