fix(huya): 作废订单后失效旧积分快照

This commit is contained in:
yml
2026-11-12 16:08:13 +08:00
parent 2ae90ef78f
commit 56e5d0ea1c
6 changed files with 438 additions and 2 deletions
+143 -2
View File
@@ -9,7 +9,9 @@
并确认迁移新增的复合查询索引确实落库。
"""
import json
import secrets
from datetime import UTC, datetime
from pathlib import Path
from urllib.parse import quote_plus
@@ -22,13 +24,13 @@ from sqlalchemy.orm import Session
import web.backend.database as database_module
from tests.support.db import get_mysql_credentials, get_test_engine
from web.backend.database import Base
from web.backend.models import User, WeiboAccount
from web.backend.models import AuditLog, HuyaExternalOrder, User, WeiboAccount
TESTS_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = TESTS_DIR.parent
VERSIONS_DIR = PROJECT_ROOT / "web" / "backend" / "migrations" / "versions"
HEAD_REVISION = "20261112_0077"
HEAD_REVISION = "20261112_0078"
# 迁移新增、但不声明在模型里的复合查询索引。
EXTRA_INDEXES = (
@@ -267,3 +269,142 @@ class TestMigrationSmoke:
mig_engine.dispose()
with admin_engine.begin() as conn:
conn.execute(text(f"DROP DATABASE IF EXISTS `{mig_db}`;"))
def test_0078_cleans_only_pre_void_points_snapshots(self):
creds = get_mysql_credentials()
mig_db = f"douyu_login_mig_{secrets.token_hex(4)}"
mig_url = (
f"mysql+pymysql://{quote_plus(creds['user'])}:"
f"{quote_plus(creds['password'])}@{creds['host']}:{creds['port']}/"
f"{mig_db}?charset=utf8mb4"
)
admin_engine = get_test_engine()
with admin_engine.begin() as conn:
conn.execute(
text(
f"CREATE DATABASE `{mig_db}` "
"CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;"
)
)
original_url = database_module.DATABASE_URL
mig_engine = create_engine(mig_url)
try:
database_module.DATABASE_URL = mig_url
cfg = _migration_config()
cfg.set_main_option("sqlalchemy.url", mig_url)
command.upgrade(cfg, "20261112_0077")
with Session(mig_engine) as session:
user = User(
username="migration-collab",
password_hash="hash",
role="super_admin",
is_active=True,
)
session.add(user)
session.commit()
def make_order(
order_no: str,
*,
status: str,
checked_at: datetime,
required_total: int,
surplus: int,
) -> HuyaExternalOrder:
return HuyaExternalOrder(
order_no=order_no,
shop="向日葵",
uid="1199665363355",
cookie="C" * 32,
raw_cookie="raw",
ck_status="valid",
bind_game_account="泡泡",
bind_game_role="厶婕",
gift_name="套装-芝士鼠鼠",
required_points=988,
home_images=["collab/2026/11/12/home.png"],
status=status,
points_checked_at=checked_at,
points_balance=988,
points_required_total=required_total,
points_surplus=surplus,
points_threshold=100,
points_check_reason="shortage" if surplus < 0 else "ok",
points_check_message="旧核账",
points_check_detail={"orders": []},
created_by=user.id,
updated_by=user.id,
)
stale = make_order(
"MIG-0078-STALE",
status="points_error",
checked_at=datetime(2026, 11, 12, 1, 46, tzinfo=UTC),
required_total=1976,
surplus=-988,
)
voided = make_order(
"MIG-0078-VOID",
status="void",
checked_at=datetime(2026, 11, 12, 1, 46, tzinfo=UTC),
required_total=1976,
surplus=-988,
)
current = make_order(
"MIG-0078-CURRENT",
status="recharged",
checked_at=datetime(2026, 11, 12, 7, 51, 50, tzinfo=UTC),
required_total=988,
surplus=0,
)
session.add_all([stale, voided, current])
session.commit()
session.add(
AuditLog(
user_id=user.id,
username=user.username,
action="huya:collab:status",
target=f"huya_external_order:{voided.id}",
detail=json.dumps({"to": "void"}),
success=True,
created_at=datetime(2026, 11, 12, 1, 49, 53, tzinfo=UTC),
)
)
session.commit()
command.upgrade(cfg, "20261112_0078")
with mig_engine.connect() as conn:
rows = {
row.order_no: row
for row in conn.execute(
text(
"SELECT order_no, status, points_checked_at, "
"points_required_total, points_surplus, "
"points_check_reason, points_check_detail "
"FROM huya_external_orders"
)
)
}
assert rows["MIG-0078-VOID"].status == "void"
assert rows["MIG-0078-VOID"].points_checked_at is None
assert rows["MIG-0078-VOID"].points_required_total is None
assert rows["MIG-0078-VOID"].points_check_reason == "stale_group"
assert rows["MIG-0078-STALE"].status == "to_recharge"
assert rows["MIG-0078-STALE"].points_checked_at is None
assert rows["MIG-0078-STALE"].points_required_total is None
assert rows["MIG-0078-STALE"].points_check_reason == "stale_group"
assert rows["MIG-0078-CURRENT"].status == "recharged"
assert rows["MIG-0078-CURRENT"].points_required_total == 988
assert rows["MIG-0078-CURRENT"].points_surplus == 0
assert rows["MIG-0078-CURRENT"].points_check_reason == "ok"
finally:
database_module.DATABASE_URL = original_url
mig_engine.dispose()
with admin_engine.begin() as conn:
conn.execute(text(f"DROP DATABASE IF EXISTS `{mig_db}`;"))