"""Endpoint tests for the FastAPI app. Network functions (Numbeo scrape, Yahoo FX) are monkeypatched at their import site in app.main, so these tests never touch the network. """ import pytest from fastapi.testclient import TestClient from app.fx import FxUnavailable from app.main import app, _fx_fmt client = TestClient(app) def test_fx_fmt_adaptive_precision(): assert _fx_fmt(0.0000730) == "0.00007300" # tiny rate keeps sig figs assert _fx_fmt(0.3174) == "0.3174" assert _fx_fmt(13698.6301) == "13,698.63" # big rate: separators, 2dp assert _fx_fmt(None) == "—" async def fake_diffs(country1, city1, country2, city2): return { "city_from": city1, "city_to": city2, "col_excl_rent": {"valuePct": 134.5, "direction": "higher"}, "rent": {"valuePct": 409.4, "direction": "higher"}, } async def fake_fx(from_currency, to_currency): return { "pair": f"{from_currency}/{to_currency}", "source": "Yahoo Finance", "latest": 0.30, "ema_30": 0.30, "ema_90": 0.31, "ema_180": 0.33, "forecast": 0.315, "trend": "down", "spot_only": False, "scale": 1, "band_low": 0.30, "band_high": 0.33, "days": 200, } @pytest.fixture def patched(monkeypatch): monkeypatch.setattr("app.main.get_percentage_diff", fake_diffs) monkeypatch.setattr("app.main.fetch_fx_ema", fake_fx) # ── GET / ───────────────────────────────────────────────────────── def test_landing_page_lists_both_tools(): r = client.get("/") assert r.status_code == 200 assert "Relocation Finance Tools" in r.text assert 'href="/relo"' in r.text assert 'href="/tax"' in r.text def test_relo_page_renders(): r = client.get("/relo") assert r.status_code == 200 assert "inferred from countries" in r.text assert "increase % of savings" in r.text # From / To each render on their own row assert r.text.count('class="loc-row"') == 2 # Countries are dropdowns populated from the currency map assert '