Skip to content

Commit 5781d0d

Browse files
SCRUMUXcursoragent
andcommitted
test: mock credit reserve in premium tier integration test
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 17fa454 commit 5781d0d

1 file changed

Lines changed: 11 additions & 18 deletions

File tree

tests/test_api/test_analyze_ab.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@
1313

1414
from __future__ import annotations
1515

16-
import asyncio
1716
import io
1817
from unittest.mock import AsyncMock, MagicMock, patch
1918

2019
from PIL import Image
21-
from sqlalchemy import select
2220

2321
from src.config import settings
24-
from src.models.db import User
2522

2623
_CONSENT_HEADERS = {
2724
"X-Consent-Data-Processing": "1",
@@ -60,20 +57,11 @@ def _auth(token: str) -> dict[str, str]:
6057
return {"Authorization": f"Bearer {token}", **_CONSENT_HEADERS}
6158

6259

63-
def _grant_credits(client, telegram_id: int, credits: int = 10) -> None:
64-
"""Premium tier reserves 5 credits — seed balance for integration tests."""
65-
66-
async def _run() -> None:
67-
sessionmaker = client.app.state.db_sessionmaker
68-
async with sessionmaker() as db:
69-
row = await db.execute(
70-
select(User).where(User.telegram_id == telegram_id)
71-
)
72-
user = row.scalar_one()
73-
user.image_credits = credits
74-
await db.commit()
75-
76-
asyncio.run(_run())
60+
async def _stub_credit_reserve(user, db, *, amount: int = 1):
61+
"""Bypass DB credit checks — this test asserts tier context, not billing."""
62+
user._credit_reserved = True
63+
user._credits_remaining = max(0, int(getattr(user, "image_credits", 1) or 1) - amount)
64+
return user
7765

7866

7967
class _TaskCtxCapture:
@@ -260,16 +248,22 @@ def test_analyze_standard_tier_when_ab_flag_off(
260248
assert "image_refine" not in ctx
261249

262250

251+
@patch("src.api.deps.reserve_additional_credit", new_callable=AsyncMock)
252+
@patch("src.api.deps._reserve_credit_for", new_callable=AsyncMock)
263253
@patch("src.api.v1.analyze._get_arq", new_callable=AsyncMock)
264254
@patch("src.api.v1.analyze.get_storage")
265255
def test_analyze_premium_tier_when_ab_flag_off(
266256
mock_get_storage,
267257
mock_get_arq,
258+
mock_reserve_first,
259+
mock_reserve_extra,
268260
client,
269261
monkeypatch,
270262
):
271263
"""v1.77 — Premium must persist high + clarity even when AB flag is off."""
272264
monkeypatch.setattr(settings, "ab_test_enabled", False)
265+
mock_reserve_first.side_effect = _stub_credit_reserve
266+
mock_reserve_extra.side_effect = _stub_credit_reserve
273267
storage = MagicMock()
274268
storage.upload = AsyncMock(return_value="inputs/u/k.jpg")
275269
mock_get_storage.return_value = storage
@@ -278,7 +272,6 @@ def test_analyze_premium_tier_when_ab_flag_off(
278272
mock_get_arq.return_value = pool
279273

280274
token = _register_user(client, telegram_id=999108)
281-
_grant_credits(client, telegram_id=999108, credits=10)
282275
with _TaskCtxCapture() as cap:
283276
r = client.post(
284277
"/api/v1/analyze",

0 commit comments

Comments
 (0)