diff --git a/application/account_facts_publisher.py b/application/account_facts_publisher.py index 68ed7c8..5e24af5 100644 --- a/application/account_facts_publisher.py +++ b/application/account_facts_publisher.py @@ -191,6 +191,10 @@ def build_firstrade_account_snapshot( if not isinstance(balances, Mapping): raise AccountFactsPublishError("snapshot_invalid") currency = balances.get("currency") + # Firstrade US equity balance payloads often omit an ISO currency field; the + # rest of this platform already treats Firstrade cash as USD. + if currency is None: + currency = "USD" if not isinstance(currency, str) or not _CURRENCY_RE.fullmatch(currency): raise AccountFactsPublishError("provider_currency_unavailable") provider_equity = balances.get("provider_equity") diff --git a/tests/test_account_facts_publisher.py b/tests/test_account_facts_publisher.py index a725ea7..127e5ae 100644 --- a/tests/test_account_facts_publisher.py +++ b/tests/test_account_facts_publisher.py @@ -73,8 +73,17 @@ def test_builds_fixed_snapshot_with_only_provider_equity_and_cash(): assert "buying_power" not in repr(payload) -@pytest.mark.parametrize("value", [None, "", "usd", "US", "USDX", "USD " ]) -def test_rejects_missing_or_invalid_provider_currency(value): +def test_defaults_missing_provider_currency_to_usd(): + data = observation() + data["balances"]["currency"] = None + payload = build_firstrade_account_snapshot( + data, load_account_facts_publish_config(config()), account_scope="us" + ) + assert payload["broker_reported_balances"][0]["currency"] == "USD" + + +@pytest.mark.parametrize("value", ["", "usd", "US", "USDX", "USD "]) +def test_rejects_invalid_provider_currency(value): data = observation() data["balances"]["currency"] = value