"""Feishu failures must not copy private response bodies into logs.""" import logging from unittest.mock import AsyncMock import pytest from app.approval import feishu_client as module from app.approval.feishu_client import FeishuApprovalClient from app.core.exceptions import AppException class _Response: def __init__(self, payload: dict): self._payload = payload def json(self) -> dict: return self._payload class _AsyncClient: payload: dict = {} def __init__(self, **_kwargs): pass async def __aenter__(self): return self async def __aexit__(self, *_args): return None async def request(self, *_args, **_kwargs): return _Response(self.payload) @pytest.mark.asyncio async def test_request_logs_no_dynamic_fields_and_redacts_surfaced_message( monkeypatch, caplog, ): secret = "SecretKey=private-directory-value" _AsyncClient.payload = {"code": 40001, "msg": secret, "private": secret} monkeypatch.setattr(module.httpx, "AsyncClient", _AsyncClient) client = FeishuApprovalClient(app_id="cli_test", app_secret="secret") client.get_tenant_access_token = AsyncMock(return_value="token") with caplog.at_level(logging.WARNING), pytest.raises(AppException) as caught: await client._request("POST", "/users", json_body={"private": secret}) assert secret not in caplog.text assert secret not in caught.value.message assert "POST" not in caplog.text assert "/users" not in caplog.text assert "40001" not in caplog.text assert "non-zero response" in caplog.text assert "40001" in caught.value.message @pytest.mark.asyncio async def test_benign_error_log_does_not_include_private_message(monkeypatch, caplog): secret = "private-user-attribute" _AsyncClient.payload = {"code": 1390007, "msg": secret, "data": {"ok": True}} monkeypatch.setattr(module.httpx, "AsyncClient", _AsyncClient) client = FeishuApprovalClient(app_id="cli_test", app_secret="secret") client.get_tenant_access_token = AsyncMock(return_value="token") with caplog.at_level(logging.INFO): result = await client._request( "POST", "/subscribe", benign_error_codes={1390007}, ) assert result == {"ok": True} assert secret not in caplog.text assert "POST" not in caplog.text assert "/subscribe" not in caplog.text assert "1390007" not in caplog.text