"""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"