Add endpoint to get a single trade by ID
This commit is contained in:
parent
04192799ab
commit
0c75583930
2 changed files with 96 additions and 0 deletions
|
|
@ -565,6 +565,29 @@ async def get_my_trades(
|
||||||
return [_to_exchange_response(ex, current_user.email) for ex in exchanges]
|
return [_to_exchange_response(ex, current_user.email) for ex in exchanges]
|
||||||
|
|
||||||
|
|
||||||
|
@trades_router.get("/{exchange_id}", response_model=ExchangeResponse)
|
||||||
|
async def get_my_trade(
|
||||||
|
exchange_id: int,
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
current_user: User = Depends(require_permission(Permission.VIEW_OWN_EXCHANGES)),
|
||||||
|
) -> ExchangeResponse:
|
||||||
|
"""Get a specific trade by ID. User can only access their own trades."""
|
||||||
|
result = await db.execute(
|
||||||
|
select(Exchange).where(
|
||||||
|
and_(Exchange.id == exchange_id, Exchange.user_id == current_user.id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
exchange = result.scalar_one_or_none()
|
||||||
|
|
||||||
|
if not exchange:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Trade not found or you don't have permission to view it.",
|
||||||
|
)
|
||||||
|
|
||||||
|
return _to_exchange_response(exchange, current_user.email)
|
||||||
|
|
||||||
|
|
||||||
@trades_router.post("/{exchange_id}/cancel", response_model=ExchangeResponse)
|
@trades_router.post("/{exchange_id}/cancel", response_model=ExchangeResponse)
|
||||||
async def cancel_my_trade(
|
async def cancel_my_trade(
|
||||||
exchange_id: int,
|
exchange_id: int,
|
||||||
|
|
|
||||||
|
|
@ -646,6 +646,79 @@ class TestUserTrades:
|
||||||
assert len(data) == 2
|
assert len(data) == 2
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetMyTrade:
|
||||||
|
"""Test getting a single trade by ID."""
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_get_my_trade_success(self, client_factory, regular_user, admin_user):
|
||||||
|
"""Can get own trade by ID."""
|
||||||
|
target_date = await setup_availability_and_price(client_factory, admin_user)
|
||||||
|
|
||||||
|
with mock_price_fetcher(20000.0):
|
||||||
|
async with client_factory.create(cookies=regular_user["cookies"]) as client:
|
||||||
|
# Create a trade
|
||||||
|
create_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 create_response.status_code == 200
|
||||||
|
trade_id = create_response.json()["id"]
|
||||||
|
|
||||||
|
# Get the trade
|
||||||
|
get_response = await client.get(f"/api/trades/{trade_id}")
|
||||||
|
|
||||||
|
assert get_response.status_code == 200
|
||||||
|
data = get_response.json()
|
||||||
|
assert data["id"] == trade_id
|
||||||
|
assert data["direction"] == "buy"
|
||||||
|
assert data["bitcoin_transfer_method"] == "onchain"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_cannot_get_other_user_trade(
|
||||||
|
self, client_factory, regular_user, alt_regular_user, admin_user
|
||||||
|
):
|
||||||
|
"""Cannot get another user's trade."""
|
||||||
|
target_date = await setup_availability_and_price(client_factory, admin_user)
|
||||||
|
|
||||||
|
with mock_price_fetcher(20000.0):
|
||||||
|
# First user creates a trade
|
||||||
|
async with client_factory.create(cookies=regular_user["cookies"]) as client:
|
||||||
|
create_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 create_response.status_code == 200
|
||||||
|
trade_id = create_response.json()["id"]
|
||||||
|
|
||||||
|
# Second user tries to get it
|
||||||
|
async with client_factory.create(
|
||||||
|
cookies=alt_regular_user["cookies"]
|
||||||
|
) as client:
|
||||||
|
get_response = await client.get(f"/api/trades/{trade_id}")
|
||||||
|
|
||||||
|
assert get_response.status_code == 404
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_get_nonexistent_trade_returns_404(
|
||||||
|
self, client_factory, regular_user
|
||||||
|
):
|
||||||
|
"""Getting a nonexistent trade returns 404."""
|
||||||
|
async with client_factory.create(cookies=regular_user["cookies"]) as client:
|
||||||
|
response = await client.get("/api/trades/99999")
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
class TestCancelTrade:
|
class TestCancelTrade:
|
||||||
"""Test cancelling trades."""
|
"""Test cancelling trades."""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue