Review fixes (2 Major + 2 Minor): - MAJOR: reword the pre-existing "Executed reality" card (same detail page) off the forbidden "divergence"/"vs sim"/"decay"/"bp" jargon -> "Real trades vs the plan", "N% behind/ahead of plan", "cost to trade %". Extend the web forbidden-strings test to assert (on VISIBLE text, stripping CSS/markup) no divergence/decay/vs-sim/bare-sim/bps anywhere on the rendered page. - MAJOR: %-of-book uses GROSS exposure (sum of abs) as the denominator, so a mixed-sign defined-risk book (vrp put-credit-spread: short put + long wing) no longer renders >100%/negative/non-summing shares. Each row keeps its signed value. New mixed-sign holdings test. - MINOR: holdings value is marked at each holding's last trade price (no live mark) — surface a per-row "as of <date>" and a column caveat so a stale mark isn't over-trusted. - MINOR: an unmapped asset symbol (future vrp option contracts) falls back to a plain generic "other" instead of echoing a raw contract string. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
2.1 KiB
Python
44 lines
2.1 KiB
Python
"""display_names.py — the SINGLE internal-id -> human-name map every cockpit view uses (the plain-language
|
|
global constraint). Covers every STRATEGY_REGISTRY entry (never a raw id falls through to the template) plus
|
|
the sim-book override pills absorbed from app.py's former local `_SIM_BOOK_LABELS`, and the asset->plain-
|
|
description map used by the holdings table."""
|
|
from __future__ import annotations
|
|
|
|
from fxhnt.application.display_names import ASSET_DESCRIPTIONS, asset_description, display_name
|
|
from fxhnt.registry import STRATEGY_REGISTRY
|
|
|
|
|
|
def test_every_registry_strategy_has_a_display_name() -> None:
|
|
for sid, entry in STRATEGY_REGISTRY.items():
|
|
# multistrat/vrp are deliberately overridden with a friendlier pill label (see the next test) — every
|
|
# other registry entry must resolve to its own registry `display_name`.
|
|
if sid not in ("multistrat", "vrp"):
|
|
assert display_name(sid) == entry["display_name"]
|
|
assert display_name(sid) != sid # never the bare raw id
|
|
|
|
|
|
def test_sim_book_overrides_are_plain_language() -> None:
|
|
# The interim local pill labels from app.py's `_SIM_BOOK_LABELS` (Task 1), absorbed here.
|
|
assert display_name("multistrat") == "Multi-asset ETF portfolio"
|
|
assert display_name("vrp") == "Options income (put spreads)"
|
|
|
|
|
|
def test_unknown_id_falls_back_to_itself_never_raises() -> None:
|
|
assert display_name("not-a-real-strategy") == "not-a-real-strategy"
|
|
|
|
|
|
def test_asset_descriptions_cover_the_multistrat_instruments() -> None:
|
|
assert ASSET_DESCRIPTIONS == {
|
|
"SPY": "US stocks", "IEF": "US Treasuries", "GLD": "Gold",
|
|
"PDBC": "Commodities", "DBMF": "Managed futures",
|
|
}
|
|
for sym, desc in ASSET_DESCRIPTIONS.items():
|
|
assert asset_description(sym) == desc
|
|
|
|
|
|
def test_asset_description_unknown_symbol_falls_back_to_generic() -> None:
|
|
# An unmapped symbol (e.g. a future vrp option contract) gets a plain generic word, never a blank or an
|
|
# odd raw contract string — the symbol itself is still shown in its own column.
|
|
assert asset_description("XYZ") == "other"
|
|
assert asset_description("SPY 260130P00500000") == "other"
|