50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
"""验证日志脱敏边界,不需要 PySide6 或真机。"""
|
|||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
import tempfile
|
||
|
|
import unittest
|
||
|
|
|
||
|
|
|
||
|
|
CLIENT_ROOT = Path(__file__).resolve().parents[1]
|
||
|
|
sys.path.insert(0, str(CLIENT_ROOT / "src"))
|
||
|
|
|
||
|
|
from cmbuyer_client.logging_policy import configure_application_logger, redact_text
|
||
|
|
from cmbuyer_client.runtime import RuntimePaths
|
||
|
|
|
||
|
|
|
||
|
|
class LoggingPolicyTests(unittest.TestCase):
|
||
|
|
def test_redact_text_hides_required_sensitive_values(self) -> None:
|
||
|
|
message = (
|
||
|
|
"token=secret-value authorization: Bearer-value "
|
||
|
|
"address='浙江省杭州市' phone=13800138000 payment=card-value"
|
||
|
|
)
|
||
|
|
|
||
|
|
redacted = redact_text(message)
|
||
|
|
|
||
|
|
for raw_value in ("secret-value", "Bearer-value", "浙江省杭州市", "13800138000", "card-value"):
|
||
|
|
self.assertNotIn(raw_value, redacted)
|
||
|
|
self.assertIn("token=[已隐藏]", redacted)
|
||
|
|
|
||
|
|
def test_file_handler_writes_only_redacted_text(self) -> None:
|
||
|
|
with tempfile.TemporaryDirectory() as directory:
|
||
|
|
paths = RuntimePaths.from_root(Path(directory))
|
||
|
|
logger = configure_application_logger(paths)
|
||
|
|
try:
|
||
|
|
logger.info("token=not-for-log phone=13900139000 payment=not-for-log")
|
||
|
|
|
||
|
|
for handler in logger.handlers:
|
||
|
|
handler.flush()
|
||
|
|
content = (paths.logs / "client.log").read_text(encoding="utf-8")
|
||
|
|
finally:
|
||
|
|
# Windows 不允许在 FileHandler 持有文件时删除临时目录。
|
||
|
|
for handler in tuple(logger.handlers):
|
||
|
|
logger.removeHandler(handler)
|
||
|
|
handler.close()
|
||
|
|
|
||
|
|
self.assertNotIn("not-for-log", content)
|
||
|
|
self.assertNotIn("13900139000", content)
|
||
|
|
self.assertIn("[已隐藏]", content)
|