这一批提交包含: 1. 配置项敏感字段标记与测试用例修复 2. 路由绑定乐观锁支持与静态路径校验 3. 微信WOC插件能力适配与新增单元测试 4. 多个适配器的接口对齐与测试补全 5. 新增定时任务清理处理器与依赖注入容器测试 6. 错误码体系扩展与整合测试 7. 删除临时验证脚本与代码清理
132 lines
3.6 KiB
Python
132 lines
3.6 KiB
Python
"""yuxi.channels.adapters.masking_adapter 单元测试。
|
||
|
||
覆盖 ``MaskingAdapter`` 的 ``maskFull`` / ``maskPartial`` /
|
||
``isSensitiveKey`` 方法,使用 ``patch`` 替换 ``CryptoHelper``,
|
||
不依赖真实加解密配置。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from unittest.mock import MagicMock, patch
|
||
|
||
import pytest
|
||
from yuxi.channels.adapters.masking_adapter import MaskingAdapter
|
||
|
||
pytestmark = pytest.mark.unit
|
||
|
||
|
||
def _make_helper() -> MagicMock:
|
||
"""构造 CryptoHelper 桩。"""
|
||
helper = MagicMock()
|
||
helper.mask_full = MagicMock(return_value="***")
|
||
helper.mask_partial = MagicMock(return_value="abcd***")
|
||
helper.is_sensitive_key = MagicMock(return_value=True)
|
||
return helper
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestMaskingAdapterConstruction:
|
||
def test_init_loads_crypto_helper(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
|
||
# Act
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Assert
|
||
assert adapter._helper is helper
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestMaskingAdapterMaskFull:
|
||
def test_mask_full_delegates_to_helper(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Act
|
||
result = adapter.maskFull("secret-value")
|
||
|
||
# Assert
|
||
helper.mask_full.assert_called_once_with("secret-value")
|
||
assert result == "***"
|
||
|
||
def test_mask_full_passes_any_value_type(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
helper.mask_full.return_value = {"masked": True}
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Act
|
||
result = adapter.maskFull({"key": "value"})
|
||
|
||
# Assert
|
||
helper.mask_full.assert_called_once_with({"key": "value"})
|
||
assert result == {"masked": True}
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestMaskingAdapterMaskPartial:
|
||
def test_mask_partial_delegates_to_helper(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Act
|
||
result = adapter.maskPartial("token-value")
|
||
|
||
# Assert
|
||
helper.mask_partial.assert_called_once_with("token-value")
|
||
assert result == "abcd***"
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestMaskingAdapterIsSensitiveKey:
|
||
def test_is_sensitive_key_delegates_to_helper(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Act
|
||
result = adapter.isSensitiveKey("api_key")
|
||
|
||
# Assert
|
||
helper.is_sensitive_key.assert_called_once_with("api_key")
|
||
assert result is True
|
||
|
||
def test_is_sensitive_key_returns_false_for_non_sensitive(self):
|
||
# Arrange
|
||
helper = _make_helper()
|
||
helper.is_sensitive_key.return_value = False
|
||
with patch(
|
||
"yuxi.channels.adapters.masking_adapter.get_crypto_helper",
|
||
return_value=helper,
|
||
):
|
||
adapter = MaskingAdapter()
|
||
|
||
# Act
|
||
result = adapter.isSensitiveKey("display_name")
|
||
|
||
# Assert
|
||
assert result is False
|