feat: Add dashboard charts with interactivity and basic authentication support
This commit is contained in:
@@ -134,11 +134,15 @@ async def test_dashboard_page_and_fragment_and_sse(tmp_path) -> None:
|
||||
overview = await client.get("/dashboard/fragment/overview")
|
||||
overview_stream = await client.get("/dashboard/stream/overview")
|
||||
controls = await client.get("/dashboard/fragment/controls")
|
||||
charts = await client.get("/dashboard/fragment/charts")
|
||||
|
||||
assert page.status_code == 200
|
||||
assert "EventSource" in page.text
|
||||
assert "alpinejs" in page.text.lower()
|
||||
assert "Chart.js" in page.text or "chart.umd.min.js" in page.text
|
||||
assert 'hx-get="/dashboard/fragment/metrics"' in page.text
|
||||
assert 'hx-get="/dashboard/fragment/controls"' in page.text
|
||||
assert 'hx-get="/dashboard/fragment/charts"' in page.text
|
||||
|
||||
assert fragment.status_code == 200
|
||||
assert "Realized P&L" in fragment.text
|
||||
@@ -170,6 +174,11 @@ async def test_dashboard_page_and_fragment_and_sse(tmp_path) -> None:
|
||||
assert "Paper trading mode" in controls.text
|
||||
assert "Trade capital USD" in controls.text
|
||||
|
||||
assert charts.status_code == 200
|
||||
assert "Opportunity Trend" in charts.text
|
||||
assert "opportunity-chart" in charts.text
|
||||
assert "Hide chart" in charts.text or "Show chart" in charts.text
|
||||
|
||||
|
||||
async def test_dashboard_controls_update_runtime_state_and_config(tmp_path) -> None:
|
||||
app = create_app(Settings(DUCKDB_PATH=tmp_path / "controls.duckdb"))
|
||||
@@ -210,3 +219,27 @@ async def test_dashboard_controls_update_runtime_state_and_config(tmp_path) -> N
|
||||
assert app.state.settings.max_trade_capital_usd == 300.0
|
||||
assert app.state.settings.max_concurrent_trades == 4
|
||||
assert app.state.settings.paper_trading_mode is True
|
||||
|
||||
|
||||
async def test_dashboard_requires_basic_auth_when_configured(tmp_path) -> None:
|
||||
app = create_app(
|
||||
Settings(
|
||||
DUCKDB_PATH=tmp_path / "auth.duckdb",
|
||||
DASHBOARD_AUTH_USERNAME="admin",
|
||||
DASHBOARD_AUTH_PASSWORD="secret",
|
||||
)
|
||||
)
|
||||
|
||||
transport = httpx.ASGITransport(app=app)
|
||||
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
unauthenticated = await client.get("/dashboard/fragment/overview")
|
||||
authenticated = await client.get(
|
||||
"/dashboard/fragment/overview",
|
||||
auth=("admin", "secret"),
|
||||
)
|
||||
health = await client.get("/health")
|
||||
|
||||
assert unauthenticated.status_code == 401
|
||||
assert unauthenticated.headers["www-authenticate"] == 'Basic realm="Arbitrade Dashboard"'
|
||||
assert authenticated.status_code == 200
|
||||
assert health.status_code == 200
|
||||
|
||||
Reference in New Issue
Block a user