--- /data/files/bmw/stocklab-audit-remediation-20260911-020000-SL006-SL007-FIX3/app/tests/test_eodhd_adapter.py.before-sl006-fix3 2026-09-10 22:03:33.751538391 +0300 +++ /data/files/bmw/stocklab-audit-remediation-20260911-020000-SL006-SL007-FIX3/app/tests/test_eodhd_adapter.py 2026-09-10 22:03:33.775538595 +0300 @@ -145,8 +145,94 @@ assert raised + +def _prime_eodhd_price_currency(adapter, currency="EUR"): + """Test helper: emulate production profile resolution before price ingestion.""" + adapter._profile_currency = currency + assert adapter._profile_currency == currency + + # --- get_prices -------------------------------------------------------------------------------- +def test_get_prices_requires_profile_currency(): + from datetime import date as date_cls + from app.adapters.base import ProviderNotFoundError + + def handler(request: httpx.Request) -> httpx.Response: + raise AssertionError("HTTP must not be called without provider currency") + + adapter = EODHDAdapter( + api_key="fake", + transport=_mock_transport(handler), + ) + + try: + adapter.get_prices( + "AAPL", + date_cls(2025, 9, 1), + date_cls(2025, 9, 30), + ) + except ProviderNotFoundError: + return + + raise AssertionError("get_prices() accepted missing provider currency") + + +def test_get_prices_uses_currency_from_company_profile(): + from datetime import date as date_cls + + def handler(request: httpx.Request) -> httpx.Response: + path = request.url.path + + if path.endswith("/fundamentals/AAPL"): + return httpx.Response( + 200, + json={ + "General": { + "Name": "Apple Inc.", + "Exchange": "XNAS", + "CountryISO": "US", + "Sector": "Technology", + "Industry": "Consumer Electronics", + "CurrencyCode": "EUR", + "ISIN": "US0378331005", + } + }, + ) + + if path.endswith("/eod/AAPL"): + return httpx.Response( + 200, + json=[ + { + "date": "2025-09-30", + "close": 228.2, + } + ], + ) + + raise AssertionError(f"unexpected path {path}") + + adapter = EODHDAdapter( + api_key="fake", + transport=_mock_transport(handler), + ) + + profile = adapter.get_company_profile("AAPL") + + assert profile.currency == "EUR" + assert adapter._profile_currency == "EUR" + + bars = adapter.get_prices( + "AAPL", + date_cls(2025, 9, 1), + date_cls(2025, 9, 30), + ) + + assert len(bars) == 1 + assert bars[0].currency == "EUR" + + def test_get_prices_parses_valid_bars(): from datetime import date as date_cls @@ -155,6 +241,7 @@ return httpx.Response(200, json=FAKE_EOD_RESPONSE) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert len(bars) == 1 assert bars[0].close == 228.2 @@ -172,6 +259,7 @@ return httpx.Response(200, json=[{"date": "2025-09-30", "close": 228.2}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert len(bars) == 1 assert bars[0].open is None @@ -195,6 +283,7 @@ return httpx.Response(200, json=[{"date": "2025-09-30", "close": "not-a-number"}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert bars == [] report = adapter.last_price_validation @@ -211,6 +300,7 @@ return httpx.Response(200, json=[{"date": "2025-09-30", "close": "227.5"}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert len(bars) == 1 and bars[0].close == 227.5 @@ -222,6 +312,7 @@ return httpx.Response(200, json=[]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert bars == [] @@ -241,6 +332,7 @@ ]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 10, 1)) assert [b.close for b in bars] == [227.0, 229.0] report = adapter.last_price_validation @@ -256,6 +348,7 @@ return httpx.Response(200, json=[{"close": 227.0}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) assert adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) == [] assert any("no date" in i.reason for i in adapter.last_price_validation.errors) @@ -267,6 +360,7 @@ return httpx.Response(200, json=[{"date": "2025-09-30", "close": -5.0}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) assert adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) == [] assert any("strictly positive" in i.reason for i in adapter.last_price_validation.errors) @@ -280,6 +374,7 @@ return httpx.Response(200, json=[{"date": "2025-09-30", "close": 227.0, "volume": -100}]) adapter = EODHDAdapter(api_key="fake", transport=_mock_transport(handler)) + _prime_eodhd_price_currency(adapter) bars = adapter.get_prices("AAPL", date_cls(2025, 9, 1), date_cls(2025, 9, 30)) assert len(bars) == 1 and bars[0].close == 227.0 and bars[0].volume is None assert any("volume cannot be negative" in i.reason