mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 14:24:31 +00:00
01a5befd87
- Removed wallet transaction and transfer logic from the wallet domain. - Introduced a new tonapi module to handle transactions and balance checks. - Updated tests to reflect the new structure and ensure functionality remains intact. - Added functionality for sending TON and USDT transfers through the tonapi module. - Improved error handling and validation for payment balances. - Cleaned up and organized imports across the codebase.
155 lines
5.8 KiB
Python
155 lines
5.8 KiB
Python
"""Verify gift search parsing and pagination handling."""
|
|
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
|
|
from pyfragment import FragmentClient, GiftsResult
|
|
|
|
FAKE_GIFTS_HTML = """
|
|
<div class="tm-catalog-grid">
|
|
<a href="/gift/plushpepe-1821?collection=all" class="tm-grid-item">
|
|
<div class="tm-grid-item-thumb">
|
|
<img src="https://nft.fragment.com/gift/plushpepe-1821.medium.jpg" class="tm-grid-thumb"/>
|
|
</div>
|
|
<div class="tm-grid-item-content">
|
|
<div class="tm-grid-item-name wide-only">
|
|
<span class="item-name">Plush Pepe</span>
|
|
<span class="item-num"> #1821</span>
|
|
</div>
|
|
<div class="tm-grid-item-desc wide-only">
|
|
<time datetime="2026-02-05T14:41:27+00:00" class="short">Feb 5 at 16:41</time>
|
|
</div>
|
|
<div class="tm-grid-item-values">
|
|
<div class="tm-grid-item-value tm-value icon-before icon-ton">88,888</div>
|
|
<div class="tm-grid-item-status tm-status-unavail">Sold</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<a href="/gift/swisswatch-7799?collection=all" class="tm-grid-item">
|
|
<div class="tm-grid-item-content">
|
|
<div class="tm-grid-item-name wide-only">
|
|
<span class="item-name">Swiss Watch</span>
|
|
<span class="item-num"> #7799</span>
|
|
</div>
|
|
<div class="tm-grid-item-desc wide-only">
|
|
<time datetime="2026-01-10T04:52:59+00:00" class="short">Jan 10 at 06:52</time>
|
|
</div>
|
|
<div class="tm-grid-item-values">
|
|
<div class="tm-grid-item-value tm-value icon-before icon-ton">13,588</div>
|
|
<div class="tm-grid-item-status tm-status-unavail">Sold</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<a class="tm-catalog-grid-more js-load-more" data-next-offset="60">Show more</a>
|
|
</div>
|
|
"""
|
|
|
|
|
|
# search_gifts result parsing tests
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_basic(client: FragmentClient) -> None:
|
|
with patch.object(client, "call", AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})):
|
|
result = await client.search_gifts()
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
assert len(result.items) == 2
|
|
assert result.items[0]["slug"] == "gift/plushpepe-1821"
|
|
assert result.items[0]["name"] == "Plush Pepe #1821"
|
|
assert result.items[0]["status"] == "Sold"
|
|
assert result.items[0]["price"] == "88888.00"
|
|
assert result.items[0]["date"] == "2026-02-05T14:41:27+00:00"
|
|
assert result.items[1]["slug"] == "gift/swisswatch-7799"
|
|
assert result.items[1]["price"] == "13588.00"
|
|
assert result.next_offset == 60
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_empty(client: FragmentClient) -> None:
|
|
with patch.object(client, "call", AsyncMock(return_value={"ok": True})):
|
|
result = await client.search_gifts(query="zzz_no_results")
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
assert result.items == []
|
|
assert result.next_offset is None
|
|
|
|
|
|
# search_gifts parameter forwarding tests
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_with_collection_and_sort(client: FragmentClient) -> None:
|
|
mock_call = AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})
|
|
with patch.object(client, "call", mock_call):
|
|
result = await client.search_gifts(collection="plushpepe", sort="price_desc", filter="sold")
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
call_data = mock_call.call_args[0][1]
|
|
assert call_data["collection"] == "plushpepe"
|
|
assert call_data["sort"] == "price_desc"
|
|
assert call_data["filter"] == "sold"
|
|
assert call_data["type"] == "gifts"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_with_offset(client: FragmentClient) -> None:
|
|
mock_call = AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})
|
|
with patch.object(client, "call", mock_call):
|
|
result = await client.search_gifts(offset=60)
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
call_data = mock_call.call_args[0][1]
|
|
assert call_data["offset"] == 60
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_with_view(client: FragmentClient) -> None:
|
|
mock_call = AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})
|
|
with patch.object(client, "call", mock_call):
|
|
result = await client.search_gifts(collection="artisanbrick", view="Model")
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
call_data = mock_call.call_args[0][1]
|
|
assert call_data["view"] == "Model"
|
|
assert call_data["collection"] == "artisanbrick"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_with_attr(client: FragmentClient) -> None:
|
|
mock_call = AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})
|
|
with patch.object(client, "call", mock_call):
|
|
result = await client.search_gifts(
|
|
collection="artisanbrick",
|
|
sort="listed",
|
|
filter="auction",
|
|
attr={
|
|
"Model": ["Delicate Wash", "Foosball", "Chocolate"],
|
|
"Backdrop": ["Celtic Blue", "Carrot Juice", "Orange"],
|
|
"Symbol": ["Crystal Ball", "Tetsubin", "Acorn"],
|
|
},
|
|
)
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
call_data = mock_call.call_args[0][1]
|
|
assert call_data["attr[Model]"] == ["Delicate Wash", "Foosball", "Chocolate"]
|
|
assert call_data["attr[Backdrop]"] == ["Celtic Blue", "Carrot Juice", "Orange"]
|
|
assert call_data["attr[Symbol]"] == ["Crystal Ball", "Tetsubin", "Acorn"]
|
|
assert call_data["collection"] == "artisanbrick"
|
|
assert call_data["sort"] == "listed"
|
|
assert call_data["filter"] == "auction"
|
|
assert call_data["type"] == "gifts"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_search_gifts_attr_not_in_data_when_none(client: FragmentClient) -> None:
|
|
mock_call = AsyncMock(return_value={"ok": True, "html": FAKE_GIFTS_HTML})
|
|
with patch.object(client, "call", mock_call):
|
|
result = await client.search_gifts()
|
|
|
|
assert isinstance(result, GiftsResult)
|
|
call_data = mock_call.call_args[0][1]
|
|
assert "view" not in call_data
|
|
assert not any(k.startswith("attr[") for k in call_data)
|