Files
planeMapper/tests/provisioning/test_location.py
Matt Edholm 6231e3157e Implement story 1.4: location resolution ICAO and address
Adds location.resolve() with ICAO CSV lookup and Nominatim geocoding,
POST /find-location portal route with inline confirmation/error display,
and full test coverage with mocked network calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:46:31 -04:00

56 lines
1.8 KiB
Python

from unittest.mock import MagicMock, patch
import pytest
from planemapper.provisioning.location import resolve
def test_icao_lookup_hit_egll() -> None:
lat, lon, name = resolve("EGLL")
assert isinstance(lat, float)
assert isinstance(lon, float)
assert isinstance(name, str)
assert 50.0 < lat < 52.0 # Heathrow is ~51.47°N
assert -1.0 < lon < 0.0 # and ~0.46°W
def test_icao_lookup_case_insensitive() -> None:
lat, lon, name = resolve("egll")
assert lat != 0.0
def test_icao_lookup_miss_raises_value_error() -> None:
with pytest.raises(ValueError, match="ICAO code not found"):
resolve("ZZZZ")
def test_nominatim_success() -> None:
mock_resp = MagicMock()
mock_resp.json.return_value = [
{"lat": "51.5", "lon": "-0.1", "display_name": "London, England"}
]
with patch("planemapper.provisioning.location.requests.get", return_value=mock_resp):
lat, lon, name = resolve("OX1 1AA")
assert lat == 51.5
assert lon == -0.1
assert name == "London, England"
def test_nominatim_empty_raises_value_error() -> None:
mock_resp = MagicMock()
mock_resp.json.return_value = []
with patch("planemapper.provisioning.location.requests.get", return_value=mock_resp):
with pytest.raises(ValueError, match="Location not found"):
resolve("nonsense query that returns nothing")
def test_nominatim_called_with_user_agent() -> None:
mock_resp = MagicMock()
mock_resp.json.return_value = [{"lat": "51.5", "lon": "-0.1", "display_name": "London"}]
with patch(
"planemapper.provisioning.location.requests.get", return_value=mock_resp
) as mock_get:
resolve("London")
call_kwargs = mock_get.call_args
assert "User-Agent" in call_kwargs.kwargs.get("headers", {})