""" Tests for the sample locations listed in geocode.samples. Fixtures are pre-recorded snapshots of WDQS and Wikidata API responses. Generate or refresh them (requires network + DB) with: python tests/capture_fixtures.py The tests themselves only need the local PostGIS database. """ import json from pathlib import Path import pytest from geocode import samples from lookup import lat_lon_to_wikidata FIXTURES_DIR = Path(__file__).parent / "fixtures" def _load_fixture(i: int) -> dict: path = FIXTURES_DIR / f"sample_{i:02d}.json" if not path.exists(): pytest.skip(f"No fixture file — run: python tests/capture_fixtures.py {i}") return json.loads(path.read_text()) def _make_mock_wdqs(fixture: dict, name: str): """Return a mock for geocode.wikidata.wdqs that replays saved responses.""" saved = fixture["wdqs"] def mock_wdqs(query: str) -> list: if query not in saved: short = query[:120].replace("\n", " ") raise AssertionError( f"[{name}] Unexpected WDQS query (not in fixture):\n {short}…" ) return saved[query] return mock_wdqs def _make_mock_api_call(fixture: dict, name: str): """Return a mock for geocode.wikidata.api_call that replays saved responses.""" saved = fixture["api"] def mock_api_call(params: dict) -> dict: key = json.dumps(params, sort_keys=True) if key not in saved: raise AssertionError( f"[{name}] Unexpected api_call (not in fixture): {key}" ) return saved[key] return mock_api_call @pytest.mark.parametrize( "i,lat,lon,name", [(i, lat, lon, name) for i, (lat, lon, name) in enumerate(samples)], ids=[name for _, _, name in samples], ) def test_example(app_ctx, mocker, i: int, lat: float, lon: float, name: str) -> None: """Each sample location resolves to the expected Wikidata item and Commons category.""" fixture = _load_fixture(i) mocker.patch("geocode.wikidata.wdqs", side_effect=_make_mock_wdqs(fixture, name)) mocker.patch( "geocode.wikidata.api_call", side_effect=_make_mock_api_call(fixture, name) ) reply = lat_lon_to_wikidata(lat, lon) result = reply["result"] expected_qid = fixture["expected_wikidata"] assert result.get("wikidata") == expected_qid, ( f"{name}: wikidata mismatch — expected {expected_qid!r}, " f"got {result.get('wikidata')!r}" ) expected_cat = fixture["expected_commons_cat"] if expected_cat: commons = result.get("commons_cat") assert isinstance(commons, dict), ( f"{name}: expected commons_cat={expected_cat!r} but result has none" ) assert commons["title"] == expected_cat, ( f"{name}: commons_cat mismatch — expected {expected_cat!r}, " f"got {commons['title']!r}" ) else: assert not result.get("commons_cat"), ( f"{name}: expected no commons_cat but got {result.get('commons_cat')!r}" )