mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 06:14:29 +00:00
feat: add unit tests for balance checks, giveaway stars, and premium methods; validate float inputs for winners and amounts
This commit is contained in:
@@ -4,11 +4,17 @@ from contextlib import contextmanager
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from tonutils.exceptions import ProviderResponseError
|
||||
|
||||
from pyfragment.types import TransactionError, WalletError
|
||||
from pyfragment.utils.wallet import process_transaction
|
||||
from tests.shared import VALID_SEED
|
||||
|
||||
|
||||
def _provider_error(code: int, message: str = "error") -> ProviderResponseError:
|
||||
return ProviderResponseError(code=code, message=message, endpoint="api.tonapi.io")
|
||||
|
||||
|
||||
TRANSACTION_DATA = {
|
||||
"transaction": {
|
||||
"messages": [
|
||||
@@ -94,3 +100,34 @@ async def test_one_nanoton_below_minimum_raises() -> None:
|
||||
async def test_invalid_payload_raises() -> None:
|
||||
with pytest.raises(TransactionError):
|
||||
await process_transaction(_make_client(), {"transaction": {}})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_balance_check_failed_raises_wallet_error() -> None:
|
||||
wallet = _make_wallet(balance_nanotons=1_000_000_000)
|
||||
wallet.refresh = AsyncMock(side_effect=RuntimeError("network timeout"))
|
||||
with _patch_wallet(wallet):
|
||||
with pytest.raises(WalletError, match="balance"):
|
||||
await process_transaction(_make_client(), TRANSACTION_DATA)
|
||||
wallet.transfer.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rate_limit_retries_and_succeeds() -> None:
|
||||
wallet = _make_wallet(balance_nanotons=1_000_000_000)
|
||||
wallet.transfer = AsyncMock(side_effect=[_provider_error(429, "rate limited"), MagicMock(normalized_hash="abc123")])
|
||||
with _patch_wallet(wallet), patch("pyfragment.utils.wallet.clean_decode", return_value=""):
|
||||
result = await process_transaction(_make_client(), TRANSACTION_DATA)
|
||||
assert result == "abc123"
|
||||
assert wallet.transfer.call_count == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_duplicate_seqno_raises_after_retries() -> None:
|
||||
wallet = _make_wallet(balance_nanotons=1_000_000_000)
|
||||
err = _provider_error(406, "Duplicate msg_seqno")
|
||||
wallet.transfer = AsyncMock(side_effect=[err, err, err])
|
||||
with _patch_wallet(wallet), patch("pyfragment.utils.wallet.clean_decode", return_value=""):
|
||||
with pytest.raises(TransactionError, match="seqno"):
|
||||
await process_transaction(_make_client(), TRANSACTION_DATA)
|
||||
assert wallet.transfer.call_count == 3
|
||||
|
||||
@@ -90,6 +90,18 @@ async def test_giveaway_stars_amount_too_high(client: FragmentClient) -> None:
|
||||
await client.giveaway_stars("@channel", winners=1, amount=1_000_001)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_giveaway_stars_float_winners(client: FragmentClient) -> None:
|
||||
with pytest.raises(ConfigurationError):
|
||||
await client.giveaway_stars("@channel", winners=1.5, amount=500) # type: ignore[arg-type]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_giveaway_stars_float_amount(client: FragmentClient) -> None:
|
||||
with pytest.raises(ConfigurationError):
|
||||
await client.giveaway_stars("@channel", winners=1, amount=500.5) # type: ignore[arg-type]
|
||||
|
||||
|
||||
# Stars giveaway mocked tests
|
||||
|
||||
|
||||
|
||||
@@ -78,6 +78,12 @@ async def test_giveaway_premium_winners_too_high(client: FragmentClient) -> None
|
||||
await client.giveaway_premium("@channel", winners=24_001, months=3)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_giveaway_premium_float_winners(client: FragmentClient) -> None:
|
||||
with pytest.raises(ConfigurationError):
|
||||
await client.giveaway_premium("@channel", winners=2.5, months=3) # type: ignore[arg-type]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_giveaway_premium_invalid_months(client: FragmentClient) -> None:
|
||||
with pytest.raises(ConfigurationError):
|
||||
|
||||
Reference in New Issue
Block a user