diff --git a/tests/test_inactivity_reset.py b/tests/test_inactivity_reset.py index 053ef96..5499ae1 100644 --- a/tests/test_inactivity_reset.py +++ b/tests/test_inactivity_reset.py @@ -3,7 +3,8 @@ from __future__ import annotations from datetime import date, datetime, timedelta, timezone -from sqlalchemy import select +import pytest +from sqlalchemy import delete, select, update from app.db.session import SessionLocal from app.models.inactivity import InactivityNotificationLog, InactivityResetLog @@ -63,6 +64,24 @@ from app.repositories import wallet as wallet_repo _PHONE_SEQ = [0] +@pytest.fixture(autouse=True) +def _isolate_inactivity_state(): + """本文件的测试都做全表扫描 + 全局计数,而 SQLite 测试库 session 级共享、无逐用例回滚 + (commit 后的 rollback 是 no-op),故先把可能泄漏的余额清零 + 清掉活跃事件/审计行, + 保证每个用例干净起步。不删 User(零余额用户不会被扫描选中,避免跨文件/外键影响)。""" + db = SessionLocal() + try: + db.execute(update(CoinAccount).values( + coin_balance=0, cash_balance_cents=0, invite_cash_balance_cents=0)) + for model in (AnalyticsEvent, CouponPromptEngagement, + InactivityResetLog, InactivityNotificationLog): + db.execute(delete(model)) + db.commit() + finally: + db.close() + yield + + def _new_user(db, *, created_at, coin=0, cash=0, invite=0) -> int: """直接建一个 User + CoinAccount,created_at 可控。返回 user_id。""" _PHONE_SEQ[0] += 1 @@ -130,17 +149,12 @@ def test_log_notifier_returns_placeholder(caplog) -> None: def test_run_reset_clears_three_buckets_and_writes_audit_and_flows() -> None: - from sqlalchemy import select, update + from sqlalchemy import select from app.models.wallet import CoinAccount, CoinTransaction, CashTransaction, InviteCashTransaction from app.repositories import inactivity db = SessionLocal() try: - # 清掉前序测试遗留的余额(session-scoped DB,前测 commit 后 rollback 是 no-op) - db.execute(update(CoinAccount).values(coin_balance=0, cash_balance_cents=0, - invite_cash_balance_cents=0)) - db.commit() - today = date(2026, 2, 1) # 末次活跃 = created_at 基线 = 1/10(距 today 22 天 → 应清) old = _new_user(db, created_at=datetime(2026, 1, 10, tzinfo=timezone.utc),