77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
import pytest
|
|
import pytest_asyncio
|
|
from decimal import Decimal
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
|
|
from app.models.entities import Base, LedgerEntryType
|
|
from app.domains.ledger.service import LedgerService, InsufficientBalanceError
|
|
|
|
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
|
|
|
|
@pytest_asyncio.fixture
|
|
async def test_session():
|
|
engine = create_async_engine(TEST_DATABASE_URL, echo=False)
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
|
|
session_maker = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
|
|
async with session_maker() as session:
|
|
yield session
|
|
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.drop_all)
|
|
await engine.dispose()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_ledger_deposit_flow(test_session: AsyncSession):
|
|
ledger = LedgerService(test_session)
|
|
user = "0x6cddF384792C77219fc25C454Cfe264757842830"
|
|
|
|
# 1. 初始余额为 0
|
|
bal = await ledger.get_or_create_balance(user)
|
|
assert bal.available_balance == Decimal("0")
|
|
|
|
# 2. 存入 1000 WUSD
|
|
entry = await ledger.record_deposit(user, Decimal("1000"), "0xtx1")
|
|
assert entry.entry_type == LedgerEntryType.DEPOSIT
|
|
assert entry.amount == Decimal("1000")
|
|
assert entry.balance_after == Decimal("1000")
|
|
|
|
bal = await ledger.get_or_create_balance(user)
|
|
assert bal.available_balance == Decimal("1000")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_ledger_trade_and_insufficient_balance(test_session: AsyncSession):
|
|
ledger = LedgerService(test_session)
|
|
user = "0x6cddF384792C77219fc25C454Cfe264757842830"
|
|
|
|
# 充值 500 WUSD
|
|
await ledger.record_deposit(user, Decimal("500"), "0xtx1")
|
|
|
|
# 尝试买入 600 WUSD (超额报错)
|
|
with pytest.raises(InsufficientBalanceError):
|
|
await ledger.record_trade(
|
|
address=user,
|
|
market_address="0xmarket1",
|
|
order_id="order_1",
|
|
side="BUY",
|
|
amount=Decimal("600"),
|
|
fee=Decimal("3.6")
|
|
)
|
|
|
|
# 成功买入 100 WUSD (扣除 100 + 0.6 手续费)
|
|
entry = await ledger.record_trade(
|
|
address=user,
|
|
market_address="0xmarket1",
|
|
order_id="order_2",
|
|
side="BUY",
|
|
amount=Decimal("100"),
|
|
fee=Decimal("0.6")
|
|
)
|
|
assert entry.entry_type == LedgerEntryType.TRADE_BUY
|
|
assert entry.amount == Decimal("-100.6")
|
|
assert entry.balance_after == Decimal("399.4")
|
|
|
|
# 验证不可变流水历史条数
|
|
history = await ledger.list_user_ledger(user)
|
|
assert len(history) == 2
|