Add validation to prevent booking two trades on the same day
This commit is contained in:
parent
8948e3533f
commit
04192799ab
2 changed files with 59 additions and 0 deletions
|
|
@ -378,6 +378,28 @@ async def create_exchange(
|
||||||
slot_date = request.slot_start.date()
|
slot_date = request.slot_start.date()
|
||||||
validate_date_in_range(slot_date, context="book")
|
validate_date_in_range(slot_date, context="book")
|
||||||
|
|
||||||
|
# Check if user already has a trade on this date
|
||||||
|
existing_trade_query = select(Exchange).where(
|
||||||
|
and_(
|
||||||
|
Exchange.user_id == current_user.id,
|
||||||
|
Exchange.slot_start >= datetime.combine(slot_date, time.min, tzinfo=UTC),
|
||||||
|
Exchange.slot_start
|
||||||
|
< datetime.combine(slot_date, time.max, tzinfo=UTC) + timedelta(days=1),
|
||||||
|
Exchange.status == ExchangeStatus.BOOKED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
existing_trade_result = await db.execute(existing_trade_query)
|
||||||
|
existing_trade = existing_trade_result.scalar_one_or_none()
|
||||||
|
|
||||||
|
if existing_trade:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail=(
|
||||||
|
f"You already have a trade booked on {slot_date.strftime('%Y-%m-%d')}. "
|
||||||
|
f"Only one trade per day is allowed. Trade ID: {existing_trade.id}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Validate direction
|
# Validate direction
|
||||||
try:
|
try:
|
||||||
direction = TradeDirection(request.direction)
|
direction = TradeDirection(request.direction)
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,43 @@ class TestCreateExchange:
|
||||||
assert response.status_code == 409
|
assert response.status_code == 409
|
||||||
assert "already been booked" in response.json()["detail"]
|
assert "already been booked" in response.json()["detail"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_cannot_book_two_trades_same_day(
|
||||||
|
self, client_factory, regular_user, admin_user
|
||||||
|
):
|
||||||
|
"""Cannot book two trades on the same day."""
|
||||||
|
target_date = await setup_availability_and_price(client_factory, admin_user)
|
||||||
|
|
||||||
|
with mock_price_fetcher(20000.0):
|
||||||
|
# First trade
|
||||||
|
async with client_factory.create(cookies=regular_user["cookies"]) as client:
|
||||||
|
response = await client.post(
|
||||||
|
"/api/exchange",
|
||||||
|
json={
|
||||||
|
"slot_start": f"{target_date}T09:00:00Z",
|
||||||
|
"direction": "buy",
|
||||||
|
"bitcoin_transfer_method": "onchain",
|
||||||
|
"eur_amount": 10000,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
# Try to book another trade on the same day
|
||||||
|
async with client_factory.create(cookies=regular_user["cookies"]) as client:
|
||||||
|
response = await client.post(
|
||||||
|
"/api/exchange",
|
||||||
|
json={
|
||||||
|
"slot_start": f"{target_date}T10:00:00Z",
|
||||||
|
"direction": "sell",
|
||||||
|
"bitcoin_transfer_method": "lightning",
|
||||||
|
"eur_amount": 20000,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert "already have a trade booked" in response.json()["detail"]
|
||||||
|
assert "Trade ID:" in response.json()["detail"]
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_invalid_direction_rejected(
|
async def test_invalid_direction_rejected(
|
||||||
self, client_factory, regular_user, admin_user
|
self, client_factory, regular_user, admin_user
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue