62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""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)
|