feat: 添加 points_audit_ledger 及 JSON 字段 Pydantic Schema 约束
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import time
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
from sqlalchemy import text
|
||||
|
||||
from core.config.settings import config
|
||||
from core.db.session import AsyncSessionLocal
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def api_base_url() -> str:
|
||||
return os.environ.get("ERYAO_TEST_BASE_URL", "http://localhost:5775")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def test_verify_code() -> str:
|
||||
return os.environ.get("ERYAO_TEST__CODE", "123456")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def unique_test_email() -> str:
|
||||
base_email = os.environ.get("ERYAO_TEST__EMAIL", "test@example.com").strip().lower()
|
||||
if "@" in base_email:
|
||||
name, domain = base_email.split("@", 1)
|
||||
else:
|
||||
name, domain = base_email, "example.com"
|
||||
return f"{name}+it{int(time.time() * 1000)}@{domain}"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_identity(unique_test_email: str, test_verify_code: str) -> dict[str, str]:
|
||||
return {"email": unique_test_email, "code": test_verify_code}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def api_client(api_base_url: str) -> AsyncIterator[httpx.AsyncClient]:
|
||||
async with httpx.AsyncClient(base_url=api_base_url, timeout=30.0) as client:
|
||||
try:
|
||||
health = await client.get("/health")
|
||||
if health.status_code != 200:
|
||||
pytest.skip(f"API not ready: /health={health.status_code}")
|
||||
except Exception as exc:
|
||||
pytest.skip(f"API unavailable: {exc}")
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def db_cleanup() -> AsyncIterator[list[str]]:
|
||||
emails: list[str] = []
|
||||
yield emails
|
||||
|
||||
if not emails:
|
||||
return
|
||||
|
||||
hmac_key = config.points_policy.register_bonus_hmac_key.get_secret_value().strip()
|
||||
email_hashes = [
|
||||
hmac.new(
|
||||
hmac_key.encode("utf-8"), email.encode("utf-8"), hashlib.sha256
|
||||
).hexdigest()
|
||||
for email in emails
|
||||
]
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
await session.execute(
|
||||
text(
|
||||
"DELETE FROM points_audit_ledger WHERE lower(coalesce(user_email_snapshot, '')) = ANY(:emails)"
|
||||
),
|
||||
{"emails": emails},
|
||||
)
|
||||
await session.execute(
|
||||
text(
|
||||
"DELETE FROM register_bonus_claims WHERE email_hash = ANY(:email_hashes)"
|
||||
),
|
||||
{"email_hashes": email_hashes},
|
||||
)
|
||||
await session.execute(
|
||||
text("DELETE FROM auth.users WHERE lower(email) = ANY(:emails)"),
|
||||
{"emails": emails},
|
||||
)
|
||||
await session.commit()
|
||||
Reference in New Issue
Block a user