feat: update README and pyproject description; enhance test docstrings for clarity and consistency

This commit is contained in:
bohd4nx
2026-03-21 17:51:19 +02:00
parent 6e4d4da740
commit 327ca35190
13 changed files with 44 additions and 43 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<h1 style="margin-top: 24px;">Fragment API</h1> <h1 style="margin-top: 24px;">Fragment API</h1>
<p style="font-size: 18px; margin-bottom: 24px;"> <p style="font-size: 18px; margin-bottom: 24px;">
<b>Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance.</b> <b>Async Python client for the Fragment.com API — buy Telegram Stars and Premium, run giveaways, top up TON Ads balance, and manage anonymous numbers.</b>
</p> </p>
[![PyPI version](https://img.shields.io/pypi/v/pyfragment?style=flat&color=blue)](https://pypi.org/project/pyfragment/) [![PyPI version](https://img.shields.io/pypi/v/pyfragment?style=flat&color=blue)](https://pypi.org/project/pyfragment/)
+1 -1
View File
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "pyfragment" name = "pyfragment"
version = "2026.0.2" 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" readme = "README.md"
license = { text = "MIT" } license = { text = "MIT" }
requires-python = ">=3.12" requires-python = ">=3.12"
+1 -1
View File
@@ -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 import re
+1 -1
View File
@@ -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 import json
+1 -2
View File
@@ -1,5 +1,4 @@
"""Tests for get_fragment_hash() — fetches a valid lowercase hex hash """Tests for get_fragment_hash() — API hash extraction from Fragment page source."""
from the fragment.com/stars/buy page source."""
import re import re
+1 -1
View File
@@ -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 contextlib import contextmanager
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock, patch
+1 -1
View File
@@ -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 from unittest.mock import AsyncMock, patch
+1 -1
View File
@@ -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 from unittest.mock import AsyncMock, patch
+1 -1
View File
@@ -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 from unittest.mock import AsyncMock, patch
+2 -5
View File
@@ -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 from unittest.mock import AsyncMock, MagicMock, patch
import pytest import pytest
from pyfragment import FragmentClient, WalletInfo from pyfragment import FragmentClient, WalletInfo
from tests.shared import FAKE_ADDRESS, FAKE_BALANCE_NANOTON
FAKE_ADDRESS = "UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5"
FAKE_BALANCE_NANOTON = 1_500_000_000 # 1.5 TON
# Wallet mocked tests # Wallet mocked tests
+2 -5
View File
@@ -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 from unittest.mock import AsyncMock, patch
import pytest import pytest
from pyfragment import FragmentClient from pyfragment import FragmentClient
from tests.shared import FAKE_HASH from tests.shared import FAKE_HASH, FAKE_RESPONSE
FAKE_RESPONSE = {"status": "ok", "data": {"value": 42}}
# client.call() mocked tests # client.call() mocked tests
+2 -18
View File
@@ -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 from unittest.mock import AsyncMock, patch
import pytest import pytest
from pyfragment import AnonymousNumberError, FragmentClient, LoginCodeResult, TerminateSessionsResult from pyfragment import AnonymousNumberError, FragmentClient, LoginCodeResult, TerminateSessionsResult
from tests.shared import FAKE_HASH from tests.shared import FAKE_HASH, FAKE_HTML_NO_CODE, FAKE_HTML_WITH_CODE, FAKE_TERMINATE_HASH
FAKE_HTML_WITH_CODE = """
<table>
<tr>
<td class="table-cell-value">12345</td>
</tr>
<tr>
<td>session data</td>
</tr>
</table>
"""
FAKE_HTML_NO_CODE = "<table><tr><td>no code here</td></tr></table>"
FAKE_TERMINATE_HASH = "terminate_hash_abc123"
# get_login_code tests # get_login_code tests
+29 -5
View File
@@ -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 from typing import Any
# Shared test credentials # Credentials and config
VALID_SEED: str = "abandon " * 23 + "about" VALID_SEED: str = "abandon " * 23 + "about"
VALID_API_KEY: str = "A" * 68 VALID_API_KEY: str = "A" * 68
VALID_COOKIES: dict[str, str] = { VALID_COOKIES: dict[str, str] = {
@@ -13,11 +17,31 @@ VALID_COOKIES: dict[str, str] = {
"stel_ton_token": "x", "stel_ton_token": "x",
} }
# Fake values for mocked tests # Generic test data
FAKE_HASH: str = "abc123" FAKE_HASH: str = "abc123"
FAKE_RECIPIENT: str = "recipient_token" FAKE_RECIPIENT: str = "recipient_token"
FAKE_REQ_ID: str = "req_42" FAKE_REQ_ID: str = "req_42"
FAKE_TX_HASH: str = "deadbeef" * 8 FAKE_TX_HASH: str = "deadbeef" * 8
FAKE_ACCOUNT: dict[str, Any] = {"address": "0:abc", "publicKey": "pub", "chain": "-239", "walletStateInit": "base64=="} 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": ""}]}} 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 = """
<table>
<tr>
<td class="table-cell-value">12345</td>
</tr>
<tr>
<td>session data</td>
</tr>
</table>
"""
FAKE_HTML_NO_CODE: str = "<table><tr><td>no code here</td></tr></table>"
FAKE_TERMINATE_HASH: str = "terminate_hash_abc123"