refactor(api): TOML 配置 SSOT、统一错误契约、Auth/事务加固与可观测性 (#33)
配置 SSOT(TOML + .env) 统一错误契约 Auth 与事务边界 Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client 可观测性(OpenTelemetry + LGTM)
This commit is contained in:
@@ -7,6 +7,8 @@ import pytest
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
|
||||
from app.core.dependencies import get_current_user
|
||||
from app.core.errors import register_exception_handlers
|
||||
from app.core.middleware import RequestIdMiddleware
|
||||
from app.features.auth.deps import get_auth_service
|
||||
from app.features.auth.router import router as auth_router
|
||||
from app.features.payment.deps import get_payment_order_service
|
||||
@@ -22,6 +24,8 @@ async def test_wechat_notify_returns_fixed_message_on_service_error() -> None:
|
||||
raise RuntimeError("wechat_sdk_secret_123")
|
||||
|
||||
app = FastAPI()
|
||||
app.add_middleware(RequestIdMiddleware)
|
||||
register_exception_handlers(app)
|
||||
app.include_router(payment_router)
|
||||
app.dependency_overrides[get_payment_order_service] = lambda: BoomOrderService()
|
||||
|
||||
@@ -62,12 +66,9 @@ async def test_avatar_upload_500_detail_sanitized(
|
||||
return_value="https://test-bucket.cos.ap-shanghai.myqcloud.com/avatars/user-contract-test/abc.jpg"
|
||||
)
|
||||
monkeypatch.setattr(deps, "get_object_storage", lambda: mock_storage)
|
||||
monkeypatch.setattr(settings, "tencent_cos_secret_id", "sid", raising=False)
|
||||
monkeypatch.setattr(settings, "tencent_cos_secret_key", "sk", raising=False)
|
||||
monkeypatch.setattr(settings, "tencent_secret_id", "sid", raising=False)
|
||||
monkeypatch.setattr(settings, "tencent_secret_key", "sk", raising=False)
|
||||
monkeypatch.setattr(settings, "tencent_cos_bucket", "test-bucket", raising=False)
|
||||
monkeypatch.setattr(
|
||||
settings, "tencent_cos_region", "ap-shanghai", raising=False
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
settings,
|
||||
"tencent_cos_base_url",
|
||||
@@ -76,22 +77,25 @@ async def test_avatar_upload_500_detail_sanitized(
|
||||
)
|
||||
|
||||
class BoomAuth:
|
||||
async def update_avatar_url(self, user_id: str, avatar_url: str):
|
||||
async def upload_avatar(self, user_id, file_content, content_type, **kwargs):
|
||||
raise RuntimeError("db_connection_secret_xyz")
|
||||
|
||||
app = FastAPI()
|
||||
app.add_middleware(RequestIdMiddleware)
|
||||
register_exception_handlers(app)
|
||||
app.include_router(auth_router)
|
||||
app.dependency_overrides[get_current_user] = lambda: fake_user
|
||||
app.dependency_overrides[get_auth_service] = lambda: BoomAuth()
|
||||
|
||||
transport = ASGITransport(app=app)
|
||||
transport = ASGITransport(app=app, raise_app_exceptions=False)
|
||||
files = {"file": ("a.jpg", BytesIO(_minimal_jpeg_bytes()), "image/jpeg")}
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
r = await client.post("/api/auth/me/avatar", files=files)
|
||||
|
||||
assert r.status_code == 500
|
||||
body = r.json()
|
||||
detail = body.get("detail", "")
|
||||
assert detail == "处理图片失败,请重试"
|
||||
assert "secret" not in str(detail).lower()
|
||||
assert body.get("error_code") == "INTERNAL_ERROR"
|
||||
message = body.get("message", "")
|
||||
assert message == "服务器内部错误"
|
||||
assert "secret" not in str(message).lower()
|
||||
assert "db_connection" not in r.text
|
||||
|
||||
Reference in New Issue
Block a user