feat: update payment method options and validation across purchase and giveaway examples; add AlreadySubscribedError exception handling

This commit is contained in:
bohd4nx
2026-05-29 23:14:59 +03:00
parent afaa42776b
commit 695430744a
14 changed files with 109 additions and 28 deletions
+17 -7
View File
@@ -7,6 +7,14 @@ import pytest
import pyfragment.domains.giveaways.giveaway as _giveaway_stars_mod
import pyfragment.domains.purchases.purchase as _purchase_stars_mod
from pyfragment import ConfigurationError, FragmentClient, StarsGiveawayResult, StarsResult, UserNotFoundError
from pyfragment.core.constants.limits import (
STARS_GIVEAWAY_MAX,
STARS_GIVEAWAY_MIN,
STARS_PURCHASE_MAX,
STARS_PURCHASE_MIN,
STARS_WINNERS_MAX,
STARS_WINNERS_MIN,
)
from pyfragment.models.enums import PaymentMethod
from tests.shared import FAKE_ACCOUNT, FAKE_RECIPIENT, FAKE_REQ_ID, FAKE_TRANSACTION, FAKE_TX_HASH
@@ -16,13 +24,13 @@ from tests.shared import FAKE_ACCOUNT, FAKE_RECIPIENT, FAKE_REQ_ID, FAKE_TRANSAC
@pytest.mark.asyncio
async def test_purchase_stars_amount_too_low(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.purchase_stars("@user", amount=49)
await client.purchase_stars("@user", amount=STARS_PURCHASE_MIN - 1)
@pytest.mark.asyncio
async def test_purchase_stars_amount_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.purchase_stars("@user", amount=1_000_001)
await client.purchase_stars("@user", amount=STARS_PURCHASE_MAX + 1)
@pytest.mark.asyncio
@@ -114,25 +122,25 @@ async def test_purchase_stars_user_not_found(client: FragmentClient) -> None:
@pytest.mark.asyncio
async def test_giveaway_stars_winners_too_low(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_stars("@channel", winners=0, amount=500)
await client.giveaway_stars("@channel", winners=STARS_WINNERS_MIN - 1, amount=STARS_GIVEAWAY_MIN)
@pytest.mark.asyncio
async def test_giveaway_stars_winners_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_stars("@channel", winners=6, amount=500)
await client.giveaway_stars("@channel", winners=STARS_WINNERS_MAX + 1, amount=STARS_GIVEAWAY_MIN)
@pytest.mark.asyncio
async def test_giveaway_stars_amount_too_low(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_stars("@channel", winners=1, amount=499)
await client.giveaway_stars("@channel", winners=STARS_WINNERS_MIN, amount=STARS_GIVEAWAY_MIN - 1)
@pytest.mark.asyncio
async def test_giveaway_stars_amount_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_stars("@channel", winners=1, amount=1_000_001)
await client.giveaway_stars("@channel", winners=STARS_WINNERS_MIN, amount=STARS_GIVEAWAY_MAX + 1)
@pytest.mark.asyncio
@@ -166,6 +174,7 @@ async def test_giveaway_stars_success(client: FragmentClient) -> None:
side_effect=[
{"found": {"recipient": FAKE_RECIPIENT}},
{},
{},
{"req_id": FAKE_REQ_ID},
FAKE_TRANSACTION,
]
@@ -189,6 +198,7 @@ async def test_giveaway_stars_passes_payment_method(client: FragmentClient) -> N
side_effect=[
{"found": {"recipient": FAKE_RECIPIENT}},
{},
{},
{"req_id": FAKE_REQ_ID},
FAKE_TRANSACTION,
]
@@ -201,7 +211,7 @@ async def test_giveaway_stars_passes_payment_method(client: FragmentClient) -> N
):
await client.giveaway_stars("@channel", winners=3, amount=1000, payment_method=PaymentMethod.USDT_TON)
init_call = call_mock.await_args_list[2]
init_call = call_mock.await_args_list[3]
assert init_call.args[0] == "initGiveawayStarsRequest"
assert init_call.args[1]["payment_method"] == "usdt_ton"
assert proc_mock.await_args is not None
+27 -4
View File
@@ -7,6 +7,8 @@ import pytest
import pyfragment.domains.giveaways.giveaway as _giveaway_premium_mod
import pyfragment.domains.purchases.purchase as _purchase_premium_mod
from pyfragment import ConfigurationError, FragmentClient, PremiumGiveawayResult, PremiumResult, UserNotFoundError
from pyfragment.core.constants.limits import PREMIUM_MONTHS_VALID, PREMIUM_WINNERS_MAX, PREMIUM_WINNERS_MIN
from pyfragment.exceptions import AlreadySubscribedError
from pyfragment.models.enums import PaymentMethod
from tests.shared import FAKE_ACCOUNT, FAKE_RECIPIENT, FAKE_REQ_ID, FAKE_TRANSACTION, FAKE_TX_HASH
@@ -22,7 +24,7 @@ async def test_purchase_premium_invalid_months(client: FragmentClient) -> None:
@pytest.mark.asyncio
async def test_purchase_premium_months_zero(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.purchase_premium("@user", months=0)
await client.purchase_premium("@user", months=min(PREMIUM_MONTHS_VALID) - 1)
@pytest.mark.asyncio
@@ -85,6 +87,25 @@ async def test_purchase_premium_passes_payment_method(client: FragmentClient) ->
assert proc_mock.await_args.kwargs["payment_method"] == "usdt_ton"
@pytest.mark.asyncio
async def test_purchase_premium_already_subscribed_raises(client: FragmentClient) -> None:
with (
patch.object(
client,
"call",
AsyncMock(
side_effect=[
{"found": {"recipient": FAKE_RECIPIENT}},
{}, # updatePremiumState
{"error": "This account is already subscribed to Telegram Premium."},
]
),
),
):
with pytest.raises(AlreadySubscribedError):
await client.purchase_premium("@user", months=6)
@pytest.mark.asyncio
@pytest.mark.parametrize("query", ["@user", "monk", "https://t.me/monk"])
async def test_purchase_premium_accepts_query_formats(client: FragmentClient, query: str) -> None:
@@ -111,13 +132,13 @@ async def test_purchase_premium_user_not_found(client: FragmentClient) -> None:
@pytest.mark.asyncio
async def test_giveaway_premium_winners_too_low(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_premium("@channel", winners=0, months=3)
await client.giveaway_premium("@channel", winners=PREMIUM_WINNERS_MIN - 1, months=3)
@pytest.mark.asyncio
async def test_giveaway_premium_winners_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.giveaway_premium("@channel", winners=24_001, months=3)
await client.giveaway_premium("@channel", winners=PREMIUM_WINNERS_MAX + 1, months=3)
@pytest.mark.asyncio
@@ -151,6 +172,7 @@ async def test_giveaway_premium_success(client: FragmentClient) -> None:
side_effect=[
{"found": {"recipient": FAKE_RECIPIENT}},
{},
{},
{"req_id": FAKE_REQ_ID},
FAKE_TRANSACTION,
]
@@ -174,6 +196,7 @@ async def test_giveaway_premium_passes_payment_method(client: FragmentClient) ->
side_effect=[
{"found": {"recipient": FAKE_RECIPIENT}},
{},
{},
{"req_id": FAKE_REQ_ID},
FAKE_TRANSACTION,
]
@@ -186,7 +209,7 @@ async def test_giveaway_premium_passes_payment_method(client: FragmentClient) ->
):
await client.giveaway_premium("@channel", winners=10, months=6, payment_method=PaymentMethod.USDT_TON)
init_call = call_mock.await_args_list[2]
init_call = call_mock.await_args_list[3]
assert init_call.args[0] == "initGiveawayPremiumRequest"
assert init_call.args[1]["payment_method"] == "usdt_ton"
assert proc_mock.await_args is not None
+3 -2
View File
@@ -6,6 +6,7 @@ import pytest
import pyfragment.domains.ads.tonup as _topup_ton_mod
from pyfragment import AdsTopupResult, ConfigurationError, FragmentClient, UserNotFoundError
from pyfragment.core.constants.limits import TON_TOPUP_MAX, TON_TOPUP_MIN
from tests.shared import FAKE_ACCOUNT, FAKE_RECIPIENT, FAKE_REQ_ID, FAKE_TRANSACTION, FAKE_TX_HASH
# Topup TON validation tests
@@ -14,13 +15,13 @@ from tests.shared import FAKE_ACCOUNT, FAKE_RECIPIENT, FAKE_REQ_ID, FAKE_TRANSAC
@pytest.mark.asyncio
async def test_topup_ton_amount_zero(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.topup_ton("@user", amount=0)
await client.topup_ton("@user", amount=TON_TOPUP_MIN - 1)
@pytest.mark.asyncio
async def test_topup_ton_amount_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.topup_ton("@user", amount=1_000_000_001)
await client.topup_ton("@user", amount=TON_TOPUP_MAX + 1)
@pytest.mark.asyncio
+3 -2
View File
@@ -6,6 +6,7 @@ import pytest
import pyfragment.domains.ads.recharge as _recharge_ads_mod
from pyfragment import AdsRechargeResult, ConfigurationError, FragmentClient
from pyfragment.core.constants.limits import TON_TOPUP_MAX, TON_TOPUP_MIN
from tests.shared import FAKE_ACCOUNT, FAKE_ADS_ACCOUNT, FAKE_REQ_ID, FAKE_TRANSACTION, FAKE_TX_HASH
# recharge_ads validation tests
@@ -14,13 +15,13 @@ from tests.shared import FAKE_ACCOUNT, FAKE_ADS_ACCOUNT, FAKE_REQ_ID, FAKE_TRANS
@pytest.mark.asyncio
async def test_recharge_ads_amount_zero(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.recharge_ads(FAKE_ADS_ACCOUNT, amount=0)
await client.recharge_ads(FAKE_ADS_ACCOUNT, amount=TON_TOPUP_MIN - 1)
@pytest.mark.asyncio
async def test_recharge_ads_amount_too_high(client: FragmentClient) -> None:
with pytest.raises(ConfigurationError):
await client.recharge_ads(FAKE_ADS_ACCOUNT, amount=1_000_000_001)
await client.recharge_ads(FAKE_ADS_ACCOUNT, amount=TON_TOPUP_MAX + 1)
@pytest.mark.asyncio