113 lines
3.1 KiB
Python
113 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
import httpx
|
|
|
|
from arbitrade.api.app import create_app
|
|
from arbitrade.config.settings import Settings
|
|
|
|
|
|
def _seed_metrics_data(app) -> None:
|
|
store = app.state.store
|
|
started = datetime.now(UTC)
|
|
finished = started + timedelta(seconds=20)
|
|
with store.connect() as conn:
|
|
conn.execute(
|
|
"""
|
|
INSERT INTO trades (
|
|
trade_ref,
|
|
started_at,
|
|
finished_at,
|
|
status,
|
|
realized_pnl,
|
|
estimated_pnl,
|
|
capital_used,
|
|
cycle,
|
|
leg_count
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
""",
|
|
[
|
|
"trade-1",
|
|
started,
|
|
finished,
|
|
"filled",
|
|
15.0,
|
|
10.0,
|
|
100.0,
|
|
"USD->BTC->ETH->USD",
|
|
3,
|
|
],
|
|
)
|
|
conn.execute(
|
|
"""
|
|
INSERT INTO opportunities (
|
|
detected_at,
|
|
cycle,
|
|
gross_pct,
|
|
net_pct,
|
|
est_profit,
|
|
executed
|
|
) VALUES (?, ?, ?, ?, ?, ?)
|
|
""",
|
|
[started, "USD->BTC->ETH->USD", 4.0, 3.0, 0.03, True],
|
|
)
|
|
conn.execute(
|
|
"""
|
|
INSERT INTO orders (
|
|
trade_ref,
|
|
order_ref,
|
|
leg_index,
|
|
pair,
|
|
side,
|
|
volume,
|
|
user_ref,
|
|
status,
|
|
filled_volume,
|
|
avg_price,
|
|
raw_response,
|
|
recorded_at
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
""",
|
|
[
|
|
"trade-1",
|
|
"order-1",
|
|
0,
|
|
"BTC/USD",
|
|
"buy",
|
|
2.0,
|
|
100,
|
|
"closed",
|
|
2.0,
|
|
100.0,
|
|
"{}",
|
|
started,
|
|
],
|
|
)
|
|
|
|
|
|
async def test_dashboard_page_and_fragment_and_sse(tmp_path) -> None:
|
|
app = create_app(
|
|
Settings(_env_file=None, DUCKDB_PATH=tmp_path / "dash.duckdb"))
|
|
_seed_metrics_data(app)
|
|
|
|
transport = httpx.ASGITransport(app=app)
|
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
|
page = await client.get("/")
|
|
fragment = await client.get("/dashboard/fragment/metrics")
|
|
stream = await client.get("/dashboard/stream/metrics")
|
|
|
|
assert page.status_code == 200
|
|
assert "EventSource" in page.text
|
|
assert 'hx-get="/dashboard/fragment/metrics"' in page.text
|
|
|
|
assert fragment.status_code == 200
|
|
assert "Realized P&L" in fragment.text
|
|
assert "15.00 USD" in fragment.text
|
|
assert "100.0%" in fragment.text
|
|
|
|
assert stream.status_code == 200
|
|
assert stream.headers["content-type"].startswith("text/event-stream")
|
|
assert "event: metrics" in stream.text
|
|
assert "Realized P&L" in stream.text
|