feat(backend): complete modular monolith with ledger, fastapi and websocket
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,76 @@
|
||||
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
|
||||
Reference in New Issue
Block a user