mirror of
https://github.com/vibe-existing/pyfragment.git
synced 2026-07-25 06:54:31 +00:00
refactor: update methods to include show_sender parameter and clean up tests
This commit is contained in:
@@ -28,12 +28,4 @@ jobs:
|
|||||||
COOKIES_JSON: ${{ secrets.COOKIES_JSON }}
|
COOKIES_JSON: ${{ secrets.COOKIES_JSON }}
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
if: github.ref != 'refs/heads/master'
|
|
||||||
run: pytest --ignore=tests/003_test_integration.py
|
|
||||||
|
|
||||||
- name: Run tests (master — full suite)
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
run: pytest
|
run: pytest
|
||||||
env:
|
|
||||||
SEED: ${{ secrets.SEED }}
|
|
||||||
API_KEY: ${{ secrets.API_KEY }}
|
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ async def main():
|
|||||||
result = await topup_ton("@username", 10)
|
result = await topup_ton("@username", 10)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
# Gift 6 months of Telegram Premium
|
# Gift 6 months of Telegram Premium (anonymous — recipient won't see sender)
|
||||||
result = await buy_premium("@username", 6)
|
result = await buy_premium("@username", 6, show_sender=False)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
# Buy 500 Stars for @username
|
# Buy 500 Stars for @username
|
||||||
@@ -170,11 +170,11 @@ asyncio.run(main())
|
|||||||
|
|
||||||
### Supported Operations
|
### Supported Operations
|
||||||
|
|
||||||
| Operation | Function | Parameters | Limits |
|
| Operation | Function | Parameters | Limits |
|
||||||
| ------------------ | ------------------------------- | ---------------------- | ------------------- |
|
| ------------------ | ----------------------------------------------------- | ----------------------------------- | ------------------- |
|
||||||
| **TON Topup** | `topup_ton(username, amount)` | Username, TON amount | 1–1,000,000,000 TON |
|
| **TON Topup** | `topup_ton(username, amount, show_sender=True)` | Username, TON amount, show sender | 1–1,000,000,000 TON |
|
||||||
| **Premium Gift** | `buy_premium(username, months)` | Username, duration | 3, 6, or 12 months |
|
| **Premium Gift** | `buy_premium(username, months, show_sender=True)` | Username, duration, show sender | 3, 6, or 12 months |
|
||||||
| **Stars Purchase** | `buy_stars(username, amount)` | Username, Stars amount | 50–1,000,000 Stars |
|
| **Stars Purchase** | `buy_stars(username, amount, show_sender=True)` | Username, Stars amount, show sender | 50–1,000,000 Stars |
|
||||||
|
|
||||||
Usernames can be passed with or without `@`.
|
Usernames can be passed with or without `@`.
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from app.core.constants import (
|
|||||||
PREMIUM_PAGE,
|
PREMIUM_PAGE,
|
||||||
STARS_PAGE,
|
STARS_PAGE,
|
||||||
WALLET_CLASSES,
|
WALLET_CLASSES,
|
||||||
|
WalletVersion,
|
||||||
)
|
)
|
||||||
from app.core.cookies import load_cookies
|
from app.core.cookies import load_cookies
|
||||||
from app.core.exceptions import (
|
from app.core.exceptions import (
|
||||||
@@ -27,6 +28,7 @@ __all__ = [
|
|||||||
"PREMIUM_PAGE",
|
"PREMIUM_PAGE",
|
||||||
"STARS_PAGE",
|
"STARS_PAGE",
|
||||||
"WALLET_CLASSES",
|
"WALLET_CLASSES",
|
||||||
|
"WalletVersion",
|
||||||
"ConfigError",
|
"ConfigError",
|
||||||
"CookiesError",
|
"CookiesError",
|
||||||
"FragmentError",
|
"FragmentError",
|
||||||
|
|||||||
+1
-4
@@ -1,17 +1,14 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Literal
|
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from app.core.constants import SUPPORTED_WALLET_VERSIONS
|
from app.core.constants import SUPPORTED_WALLET_VERSIONS, WalletVersion
|
||||||
from app.core.exceptions import ConfigError
|
from app.core.exceptions import ConfigError
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
WalletVersion = Literal["V4R2", "V5R1"]
|
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
SEED: str
|
SEED: str
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
|
from typing import Literal, get_args
|
||||||
|
|
||||||
from tonutils.contracts.wallet import WalletV4R2, WalletV5R1
|
from tonutils.contracts.wallet import WalletV4R2, WalletV5R1
|
||||||
|
|
||||||
# Supported TON wallet contract versions
|
# Single source of truth for supported wallet versions
|
||||||
SUPPORTED_WALLET_VERSIONS: set[str] = {"V4R2", "V5R1"}
|
WalletVersion = Literal["V4R2", "V5R1"]
|
||||||
|
SUPPORTED_WALLET_VERSIONS: frozenset[str] = frozenset(get_args(WalletVersion))
|
||||||
|
|
||||||
# Wallet class map — used to resolve the correct contract from WALLET_VERSION
|
# Wallet class map — used to resolve the correct contract from WALLET_VERSION
|
||||||
WALLET_CLASSES: dict[str, type] = {"V4R2": WalletV4R2, "V5R1": WalletV5R1}
|
WALLET_CLASSES: dict[str, type] = {"V4R2": WalletV4R2, "V5R1": WalletV5R1}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ async def init_gift_premium(
|
|||||||
return req_id
|
return req_id
|
||||||
|
|
||||||
|
|
||||||
async def buy_premium(username: str, months: int) -> dict:
|
async def buy_premium(username: str, months: int, show_sender: bool = True) -> dict:
|
||||||
if months not in (3, 6, 12):
|
if months not in (3, 6, 12):
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
@@ -120,7 +120,7 @@ async def buy_premium(username: str, months: int) -> dict:
|
|||||||
"device": DEVICE,
|
"device": DEVICE,
|
||||||
"transaction": 1,
|
"transaction": 1,
|
||||||
"id": req_id,
|
"id": req_id,
|
||||||
"show_sender": 1,
|
"show_sender": int(show_sender),
|
||||||
"method": "getGiftPremiumLink",
|
"method": "getGiftPremiumLink",
|
||||||
}
|
}
|
||||||
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ async def init_buy_stars(
|
|||||||
return req_id
|
return req_id
|
||||||
|
|
||||||
|
|
||||||
async def buy_stars(username: str, amount: int) -> dict:
|
async def buy_stars(username: str, amount: int, show_sender: bool = True) -> dict:
|
||||||
if not isinstance(amount, int) or amount < 50:
|
if not isinstance(amount, int) or amount < 50:
|
||||||
return {"success": False, "error": "Amount must be an integer >= 50 stars."}
|
return {"success": False, "error": "Amount must be an integer >= 50 stars."}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ async def buy_stars(username: str, amount: int) -> dict:
|
|||||||
"device": DEVICE,
|
"device": DEVICE,
|
||||||
"transaction": 1,
|
"transaction": 1,
|
||||||
"id": req_id,
|
"id": req_id,
|
||||||
"show_sender": 1,
|
"show_sender": int(show_sender),
|
||||||
"method": "getBuyStarsLink",
|
"method": "getBuyStarsLink",
|
||||||
}
|
}
|
||||||
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
||||||
|
|||||||
+2
-2
@@ -79,7 +79,7 @@ async def init_ads_topup(
|
|||||||
return req_id
|
return req_id
|
||||||
|
|
||||||
|
|
||||||
async def topup_ton(username: str, amount: int) -> dict:
|
async def topup_ton(username: str, amount: int, show_sender: bool = True) -> dict:
|
||||||
if not isinstance(amount, int) or amount < 1:
|
if not isinstance(amount, int) or amount < 1:
|
||||||
return {"success": False, "error": "Amount must be an integer >= 1 TON."}
|
return {"success": False, "error": "Amount must be an integer >= 1 TON."}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ async def topup_ton(username: str, amount: int) -> dict:
|
|||||||
"device": DEVICE,
|
"device": DEVICE,
|
||||||
"transaction": 1,
|
"transaction": 1,
|
||||||
"id": req_id,
|
"id": req_id,
|
||||||
"show_sender": 1,
|
"show_sender": int(show_sender),
|
||||||
"method": "getAdsTopupLink",
|
"method": "getAdsTopupLink",
|
||||||
}
|
}
|
||||||
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
transaction = await execute_transaction_request(client, HEADERS, account, tx_data, fragment_hash)
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ async def topup_ton_example():
|
|||||||
logger.info("Starting TON topup example")
|
logger.info("Starting TON topup example")
|
||||||
|
|
||||||
# @bohd4nx - target username, 100 - TON amount (integer 1-1000000000 (one billion))
|
# @bohd4nx - target username, 100 - TON amount (integer 1-1000000000 (one billion))
|
||||||
result = await topup_ton("@bohd4nx", 100)
|
# show_sender=True — recipient sees who sent the topup
|
||||||
|
result = await topup_ton("@bohd4nx", 100, show_sender=True)
|
||||||
|
|
||||||
if result["success"]:
|
if result["success"]:
|
||||||
pass # Transaction successful, details are logged in the method
|
pass # Transaction successful, details are logged in the method
|
||||||
@@ -23,7 +24,8 @@ async def buy_premium_example():
|
|||||||
logger.info("Starting Premium purchase example")
|
logger.info("Starting Premium purchase example")
|
||||||
|
|
||||||
# @bohd4nx - target username, 12 - months duration (3, 6, or 12 only)
|
# @bohd4nx - target username, 12 - months duration (3, 6, or 12 only)
|
||||||
result = await buy_premium("@bohd4nx", 12)
|
# show_sender=True — recipient sees who gifted the Premium
|
||||||
|
result = await buy_premium("@bohd4nx", 12, show_sender=True)
|
||||||
|
|
||||||
if result["success"]:
|
if result["success"]:
|
||||||
pass # Transaction successful, details are logged in the method
|
pass # Transaction successful, details are logged in the method
|
||||||
@@ -35,7 +37,8 @@ async def buy_stars_example():
|
|||||||
logger.info("Starting Stars purchase example")
|
logger.info("Starting Stars purchase example")
|
||||||
|
|
||||||
# @bohd4nx - target username, 1000000 - stars amount (integer 50-1000000 (one million))
|
# @bohd4nx - target username, 1000000 - stars amount (integer 50-1000000 (one million))
|
||||||
result = await buy_stars("@bohd4nx", 1000000)
|
# show_sender=True — recipient sees who sent the Stars
|
||||||
|
result = await buy_stars("@bohd4nx", 1000000, show_sender=True)
|
||||||
|
|
||||||
if result["success"]:
|
if result["success"]:
|
||||||
pass # Transaction successful, details are logged in the method
|
pass # Transaction successful, details are logged in the method
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
"""End-to-end integration test: buy 50 Stars for @bohd4nx.
|
|
||||||
|
|
||||||
Requires cookies.json and a valid .env (API_KEY + SEED).
|
|
||||||
Auto-skipped when cookies or config are unavailable (e.g. CI without secrets).
|
|
||||||
"""
|
|
||||||
|
|
||||||
from app.methods.stars import buy_stars
|
|
||||||
|
|
||||||
|
|
||||||
async def test_buy_stars_e2e(cookies, tests_config):
|
|
||||||
result = await buy_stars("@bohd4nx", 50)
|
|
||||||
assert result["success"] is True, result.get("error")
|
|
||||||
assert result["data"]["transaction_id"]
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from app.core.config import config
|
|
||||||
from app.core.cookies import load_cookies
|
from app.core.cookies import load_cookies
|
||||||
from app.core.exceptions import CookiesError
|
from app.core.exceptions import CookiesError
|
||||||
|
|
||||||
@@ -12,11 +11,3 @@ def cookies():
|
|||||||
return load_cookies()
|
return load_cookies()
|
||||||
except CookiesError as exc:
|
except CookiesError as exc:
|
||||||
pytest.skip(f"Cookies unavailable — {exc}")
|
pytest.skip(f"Cookies unavailable — {exc}")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def tests_config():
|
|
||||||
"""Require a fully configured environment (SEED + API_KEY); skip otherwise."""
|
|
||||||
if config is None:
|
|
||||||
pytest.skip("Config unavailable — set SEED and API_KEY in .env or environment")
|
|
||||||
return config
|
|
||||||
|
|||||||
Reference in New Issue
Block a user