Switch FX rates to Frankfurter
This commit is contained in:
parent
a369c44ae9
commit
fc82cf280a
2 changed files with 184 additions and 12 deletions
|
|
@ -19,7 +19,7 @@ class TestReadCachedRates:
|
|||
assert result == {}
|
||||
|
||||
def test_read_cached_rates_valid_file(self) -> None:
|
||||
"""Test reading valid cached rates file."""
|
||||
"""Test reading valid exchangerate.host cached rates file."""
|
||||
currencies = ["USD", "EUR", "JPY"]
|
||||
data = {
|
||||
"quotes": {
|
||||
|
|
@ -46,6 +46,37 @@ class TestReadCachedRates:
|
|||
finally:
|
||||
os.unlink(filepath)
|
||||
|
||||
def test_read_cached_rates_frankfurter_file(self) -> None:
|
||||
"""Test reading valid Frankfurter cached rates file."""
|
||||
currencies = ["USD", "EUR", "JPY"]
|
||||
data = [
|
||||
{"date": "2026-06-20", "base": "GBP", "quote": "USD", "rate": 1.25},
|
||||
{"date": "2026-06-20", "base": "GBP", "quote": "EUR", "rate": 1.15},
|
||||
{"date": "2026-06-20", "base": "GBP", "quote": "JPY", "rate": 150.0},
|
||||
{
|
||||
"date": "2026-06-20",
|
||||
"base": "GBP",
|
||||
"quote": "CAD",
|
||||
"rate": 1.70,
|
||||
}, # Not requested
|
||||
]
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
json.dump(data, f)
|
||||
filepath = f.name
|
||||
|
||||
try:
|
||||
result = read_cached_rates(filepath, currencies)
|
||||
|
||||
assert len(result) == 3
|
||||
assert result["USD"] == Decimal("1.25")
|
||||
assert result["EUR"] == Decimal("1.15")
|
||||
assert result["JPY"] == Decimal("150.0")
|
||||
assert "CAD" not in result # Not requested
|
||||
|
||||
finally:
|
||||
os.unlink(filepath)
|
||||
|
||||
def test_read_cached_rates_missing_currencies(self) -> None:
|
||||
"""Test with some currencies missing from data."""
|
||||
currencies = ["USD", "EUR", "CHF"] # CHF not in data
|
||||
|
|
@ -158,8 +189,8 @@ class TestReadCachedRates:
|
|||
os.unlink(filepath)
|
||||
|
||||
|
||||
def test_get_rates_uses_older_valid_cache_when_latest_attempt_is_usage_limit() -> None:
|
||||
"""A usage-limit API response should not replace usable cached rates."""
|
||||
def test_get_rates_ignores_old_usage_limit_attempt_when_using_frankfurter() -> None:
|
||||
"""An old provider usage-limit response should not block Frankfurter refreshes."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
fx_dir = os.path.join(temp_dir, "fx")
|
||||
os.mkdir(fx_dir)
|
||||
|
|
@ -200,8 +231,31 @@ def test_get_rates_uses_older_valid_cache_when_latest_attempt_is_usage_limit() -
|
|||
) as mock_client:
|
||||
mock_datetime.now.return_value = datetime(2026, 6, 20, 12, 35)
|
||||
mock_datetime.strptime.side_effect = datetime.strptime
|
||||
mock_response = (
|
||||
mock_client.return_value.__enter__.return_value.get.return_value
|
||||
)
|
||||
mock_response.text = json.dumps(
|
||||
[
|
||||
{
|
||||
"date": "2026-06-20",
|
||||
"base": "GBP",
|
||||
"quote": "EUR",
|
||||
"rate": 1.16,
|
||||
},
|
||||
{
|
||||
"date": "2026-06-20",
|
||||
"base": "GBP",
|
||||
"quote": "USD",
|
||||
"rate": 1.26,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
result = get_rates(config)
|
||||
|
||||
assert result == {"USD": Decimal("1.25"), "EUR": Decimal("1.15")}
|
||||
mock_client.assert_not_called()
|
||||
assert result == {"USD": Decimal("1.26"), "EUR": Decimal("1.16")}
|
||||
mock_client.return_value.__enter__.return_value.get.assert_called_once_with(
|
||||
"https://api.frankfurter.dev/v2/rates",
|
||||
params={"base": "GBP", "quotes": "EUR,USD"},
|
||||
timeout=10,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue