diff --git a/README.md b/README.md index 34ecbf6..490b3a8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

Fragment API

- Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance. + Async Python client for the Fragment.com API — buy Telegram Stars and Premium, run giveaways, top up TON Ads balance, and manage anonymous numbers.

[![PyPI version](https://img.shields.io/pypi/v/pyfragment?style=flat&color=blue)](https://pypi.org/project/pyfragment/) diff --git a/pyproject.toml b/pyproject.toml index c422aa6..47c9cbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "pyfragment" version = "2026.0.2" -description = "Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance." +description = "Async Python client for the Fragment.com API — buy Telegram Stars and Premium, run giveaways, top up TON Ads balance, and manage anonymous numbers." readme = "README.md" license = { text = "MIT" } requires-python = ">=3.12" diff --git a/tests/001_test_decode.py b/tests/001_test_decode.py index 0b59b82..8a60ac3 100644 --- a/tests/001_test_decode.py +++ b/tests/001_test_decode.py @@ -1,4 +1,4 @@ -"""Tests for clean_decode() — BOC-encoded Fragment payloads decode to UTF-8.""" +"""Tests for clean_decode() — TON BOC payload decoding.""" import re diff --git a/tests/002_test_client.py b/tests/002_test_client.py index 8e5607e..16ced03 100644 --- a/tests/002_test_client.py +++ b/tests/002_test_client.py @@ -1,4 +1,4 @@ -"""Unit tests for FragmentClient — init validation and cookie parsing (no network calls).""" +"""Unit tests for FragmentClient — initialization, validation, and cookie parsing.""" import json diff --git a/tests/003_test_hash.py b/tests/003_test_hash.py index bb883ba..d11f05c 100644 --- a/tests/003_test_hash.py +++ b/tests/003_test_hash.py @@ -1,5 +1,4 @@ -"""Tests for get_fragment_hash() — fetches a valid lowercase hex hash -from the fragment.com/stars/buy page source.""" +"""Tests for get_fragment_hash() — API hash extraction from Fragment page source.""" import re diff --git a/tests/004_test_balance.py b/tests/004_test_balance.py index 5201db6..185ba30 100644 --- a/tests/004_test_balance.py +++ b/tests/004_test_balance.py @@ -1,4 +1,4 @@ -"""Unit tests for process_transaction() — balance checks before broadcast.""" +"""Unit tests for process_transaction() — balance validation and broadcast retry logic.""" from contextlib import contextmanager from unittest.mock import AsyncMock, MagicMock, patch diff --git a/tests/005_test_stars.py b/tests/005_test_stars.py index c3a38b8..0a87f94 100644 --- a/tests/005_test_stars.py +++ b/tests/005_test_stars.py @@ -1,4 +1,4 @@ -"""Unit tests for purchase_stars and giveaway_stars — validation and mocked network calls.""" +"""Unit tests for Stars methods — purchase_stars and giveaway_stars.""" from unittest.mock import AsyncMock, patch diff --git a/tests/006_test_premium.py b/tests/006_test_premium.py index 6e06a22..0a0b11e 100644 --- a/tests/006_test_premium.py +++ b/tests/006_test_premium.py @@ -1,4 +1,4 @@ -"""Unit tests for purchase_premium and giveaway_premium — validation and mocked network calls.""" +"""Unit tests for Premium methods — purchase_premium and giveaway_premium.""" from unittest.mock import AsyncMock, patch diff --git a/tests/007_test_topup.py b/tests/007_test_topup.py index 3cad838..2b491bc 100644 --- a/tests/007_test_topup.py +++ b/tests/007_test_topup.py @@ -1,4 +1,4 @@ -"""Unit tests for topup_ton — validation and mocked network calls.""" +"""Unit tests for topup_ton — TON Ads balance top-up.""" from unittest.mock import AsyncMock, patch diff --git a/tests/008_test_wallet.py b/tests/008_test_wallet.py index b4279dd..d13c081 100644 --- a/tests/008_test_wallet.py +++ b/tests/008_test_wallet.py @@ -1,14 +1,11 @@ -"""Unit tests for get_wallet — mocked network calls.""" +"""Unit tests for get_wallet() — wallet address and TON balance lookup.""" from unittest.mock import AsyncMock, MagicMock, patch import pytest from pyfragment import FragmentClient, WalletInfo - -FAKE_ADDRESS = "UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5" -FAKE_BALANCE_NANOTON = 1_500_000_000 # 1.5 TON - +from tests.shared import FAKE_ADDRESS, FAKE_BALANCE_NANOTON # Wallet mocked tests diff --git a/tests/009_test_call.py b/tests/009_test_call.py index 42be933..14b6b59 100644 --- a/tests/009_test_call.py +++ b/tests/009_test_call.py @@ -1,14 +1,11 @@ -"""Unit tests for client.call() — raw Fragment API request.""" +"""Unit tests for FragmentClient.call() — raw Fragment API access.""" from unittest.mock import AsyncMock, patch import pytest from pyfragment import FragmentClient -from tests.shared import FAKE_HASH - -FAKE_RESPONSE = {"status": "ok", "data": {"value": 42}} - +from tests.shared import FAKE_HASH, FAKE_RESPONSE # client.call() mocked tests diff --git a/tests/010_test_number.py b/tests/010_test_number.py index 4138b4f..bdcdb02 100644 --- a/tests/010_test_number.py +++ b/tests/010_test_number.py @@ -1,27 +1,11 @@ -"""Unit tests for number methods — get_login_code, toggle_login_codes, terminate_sessions.""" +"""Unit tests for anonymous number methods — login codes and session management.""" from unittest.mock import AsyncMock, patch import pytest from pyfragment import AnonymousNumberError, FragmentClient, LoginCodeResult, TerminateSessionsResult -from tests.shared import FAKE_HASH - -FAKE_HTML_WITH_CODE = """ - - - - - - - -
12345
session data
-""" - -FAKE_HTML_NO_CODE = "
no code here
" - -FAKE_TERMINATE_HASH = "terminate_hash_abc123" - +from tests.shared import FAKE_HASH, FAKE_HTML_NO_CODE, FAKE_HTML_WITH_CODE, FAKE_TERMINATE_HASH # get_login_code tests diff --git a/tests/shared.py b/tests/shared.py index 042095b..183ca6d 100644 --- a/tests/shared.py +++ b/tests/shared.py @@ -1,9 +1,13 @@ -"""Shared test constants — imported by all test modules that need them.""" +"""Shared test constants for the pyfragment test suite. + +pyfragment is an async Python client for Fragment.com — purchase Telegram Premium +and Stars, run Stars and Premium giveaways for channels, top up TON Ads balance, +and manage anonymous numbers, all through a clean typed API. +""" from typing import Any -# Shared test credentials - +# Credentials and config VALID_SEED: str = "abandon " * 23 + "about" VALID_API_KEY: str = "A" * 68 VALID_COOKIES: dict[str, str] = { @@ -13,11 +17,31 @@ VALID_COOKIES: dict[str, str] = { "stel_ton_token": "x", } -# Fake values for mocked tests - +# Generic test data FAKE_HASH: str = "abc123" FAKE_RECIPIENT: str = "recipient_token" FAKE_REQ_ID: str = "req_42" FAKE_TX_HASH: str = "deadbeef" * 8 FAKE_ACCOUNT: dict[str, Any] = {"address": "0:abc", "publicKey": "pub", "chain": "-239", "walletStateInit": "base64=="} FAKE_TRANSACTION: dict[str, Any] = {"transaction": {"messages": [{"address": "0:abc", "amount": "100000000", "payload": ""}]}} + +# client.call() +FAKE_RESPONSE: dict[str, Any] = {"status": "ok", "data": {"value": 42}} + +# get_wallet() +FAKE_ADDRESS: str = "UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5" +FAKE_BALANCE_NANOTON: int = 1_500_000_000 # 1.5 TON + +# Anonymous number +FAKE_HTML_WITH_CODE: str = """ + + + + + + + +
12345
session data
+""" +FAKE_HTML_NO_CODE: str = "
no code here
" +FAKE_TERMINATE_HASH: str = "terminate_hash_abc123"