dotb_ai-platform/tests/test_database_error_mapping.py
hungtran24 b1f6643796 refactor: score synchronously and drop webhook/background execution
POST /v1/lead-scoring/score now evaluates in the request, applies an overall
AI deadline, and stores the completed run only after scoring. Idempotency is
kept by (app_id, account_id, request_id) with a body fingerprint.

Removes the webhook outbox, scheduler/recovery loop, app lead_scoring
permission, credential audit events, seed_demo and generate_secret scripts,
and the tests that covered them. Trims tests to behavior of the new flow.
2026-10-09 02:44:24 +07:00

48 lines
1.6 KiB
Python

from types import SimpleNamespace
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.exc import OperationalError
from ai_platform.bootstrap.app import create_app
from ai_platform.bootstrap.wiring import get_app_credential_use_cases, get_scoring_use_cases
from ai_platform.infrastructure.config.settings import Settings
@pytest.mark.parametrize("boundary", ["auth", "scoring"])
@pytest.mark.parametrize(
"error",
[
OperationalError(
"private-sql", {"credential": "private-key"}, Exception("private-storage-error")
),
ConnectionRefusedError("private-storage-error"),
],
)
def test_database_unavailability_returns_safe_503(valid_run_payload, boundary, error):
app = create_app(Settings())
async def authenticate(_raw):
return "omni-local"
async def credential_cases():
if boundary == "auth":
raise error
return SimpleNamespace(authenticate=authenticate)
async def scoring_cases():
raise error
app.dependency_overrides[get_app_credential_use_cases] = credential_cases
app.dependency_overrides[get_scoring_use_cases] = scoring_cases
# Dependencies are isolated; this test makes no DB connections or startup mutations.
client = TestClient(app)
headers = {
"Authorization": "Bearer private-key",
"Idempotency-Key": valid_run_payload["request_id"],
}
response = client.post("/v1/lead-scoring/score", headers=headers, json=valid_run_payload)
assert response.status_code == 503
assert response.json() == {"detail": "Database unavailable"}
assert "private" not in response.text