Files
fxhnt/tests/integration/test_web.py
jgrusewski 33b36f8eb8 chore(surfer): relabel combined as crypto-momentum book + retire equity-factor sleeves
- combined relabeled 'Crypto momentum book (vestigial trend overlay)': the engine is validated
  crypto momentum; the futures-trend leg riding the crypto spine has no edge and never gates.
- Retired eqfactor_long/eqfactor_tilt (US-equity price-factors — weakly-held, edge never
  established) + their orphaned shared eqfactor_scores asset. Strategy classes stay in
  equity_factor_strategy.py. _seed_registry prunes stale rows automatically.

Cockpit fleet now = 4 tracks: 2 validated crypto edges (xsfunding, unlock) + the crypto-momentum
book + the 60/40 benchmark. 7 Dagster assets. Tests updated (labels + retarget to surviving
tracks); full suite 511 passed, mypy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 22:53:03 +02:00

74 lines
2.8 KiB
Python

"""Web smoke: routes return 200 and render the seeded fleet + a strategy detail + healthz."""
from __future__ import annotations
import datetime as dt
from fastapi.testclient import TestClient
from fxhnt.adapters.persistence.forward_nav import ForwardNavRepo
from fxhnt.adapters.web.app import create_app
from fxhnt.application.forward_models import BacktestSummary
from fxhnt.application.forward_models import ForwardNavRow as Row
from fxhnt.application.forward_models import ForwardSummary
def _client() -> TestClient:
repo = ForwardNavRepo("sqlite://")
repo.migrate()
at = dt.datetime(2026, 6, 14, 23, 30)
repo.upsert_rows([Row("combined", "2026-06-05", 0.01, 1.01),
Row("combined", "2026-06-06", 0.0099, 1.0201)], at)
repo.upsert_summary(ForwardSummary("combined", "2026-06-06", 2, 1.0201, 0.0201, 1.2, -0.01),
"WAIT", "2/20 forward days", at)
repo.upsert_backtest_summary(BacktestSummary(
"xsfunding", "2026-05-30", cagr=0.12, ann_vol=0.18, sharpe=0.85, max_drawdown=-0.22,
passed=True, dsr=0.61, is_sharpe=0.9, oos_sharpe=0.7, pvalue=0.03), at)
return TestClient(create_app(repo))
def test_healthz() -> None:
assert _client().get("/healthz").status_code == 200
def test_cockpit_lists_fleet() -> None:
r = _client().get("/")
assert r.status_code == 200
assert "Crypto momentum book" in r.text and "WAIT" in r.text
def test_cockpit_shows_backtest_verdict_column() -> None:
r = _client().get("/")
assert r.status_code == 200
assert "backtest" in r.text # column header present
assert "badge PASS" in r.text # eqfactor_long verdict rendered
assert "DSR" in r.text
def test_cockpit_has_responsive_markup() -> None:
r = _client().get("/")
assert r.status_code == 200
assert 'class="fleet"' in r.text # fleet table marked for card reflow
assert 'data-label="Sharpe"' in r.text # per-cell labels for mobile card view
def test_strategy_detail_renders_backtest_verdict() -> None:
r = _client().get("/strategy/xsfunding")
assert r.status_code == 200
assert "backtest verdict" in r.text # verdict block header present
assert "badge PASS" in r.text # PASS badge rendered
assert "DSR" in r.text # backtest metric label present
def test_strategy_detail_renders() -> None:
r = _client().get("/strategy/combined")
assert r.status_code == 200 and "2026-06-06" in r.text
assert "weekly" in r.text and "rolling mean" in r.text # period-aware section present
def test_strategy_detail_unknown_404() -> None:
assert _client().get("/strategy/nope").status_code == 404
def test_factory_route_ok() -> None:
assert _client().get("/factory").status_code == 200