"""Coordinate validation at the HTTP boundary.""" from unittest.mock import Mock import pytest import lookup @pytest.mark.parametrize("parameter", ["lat", "lon"]) @pytest.mark.parametrize( "value", [ "", "-4.177.'),(\"abcd", "55.7644)\"'.,(abcd", "55.7644 AND EXTRACTVALUE(1,CONCAT(0x7e,1))", "55.7644 AND 1=CAST('abc' AS NUMERIC)", "56°5'58.56\"N trailing text", "nan", "inf", "-inf", "1e999", "181", ], ) def test_invalid_coordinates_return_400(monkeypatch, parameter, value): """Malformed coordinates never reach the geocoding lookup.""" monkeypatch.setattr(lookup.database.session, "execute", Mock()) geocode_lookup = Mock() monkeypatch.setattr(lookup, "lat_lon_to_wikidata", geocode_lookup) args = {"lat": "55.7644", "lon": "-4.177", parameter: value} response = lookup.app.test_client().get("/", query_string=args) assert response.status_code == 400 assert response.get_json()["error"] geocode_lookup.assert_not_called() @pytest.mark.parametrize( "lat, lon, expected", [ ("55.7644", "-4.177", (55.7644, -4.177)), ("56°6'0\"N", "3°30'0\"W", (56.1, -3.5)), ("-90", "180", (-90.0, 180.0)), ], ) def test_valid_coordinates_reach_lookup(monkeypatch, lat, lon, expected): """Decimal, DMS, and boundary coordinates retain their behavior.""" monkeypatch.setattr(lookup.database.session, "execute", Mock()) monkeypatch.setattr(lookup, "logging_enabled", False) geocode_lookup = Mock(return_value={"result": {"ok": True}}) monkeypatch.setattr(lookup, "lat_lon_to_wikidata", geocode_lookup) response = lookup.app.test_client().get( "/", query_string={"lat": lat, "lon": lon, "needs_commons": "false"} ) assert response.status_code == 200 assert response.get_json() == {"ok": True} geocode_lookup.assert_called_once_with(*expected, needs_commons=False)