The crawler subdirectory was the only active project. Moving it to the repo root simplifies paths and removes the unnecessary nesting. The vqa/ and immoweb/ directories were legacy/unused and have been removed. Updated .drone.yml, .gitignore, .claude/ docs, and skills to reflect the new flat structure.
67 lines
2.6 KiB
Python
67 lines
2.6 KiB
Python
"""Unit tests for rec/routing.py."""
|
|
import os
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
import pytest
|
|
|
|
from rec.routing import TravelMode, transit_route, ROUTES_API_URL, ROUTES_FIELD_MASK
|
|
from rec.exceptions import RoutingApiError
|
|
|
|
|
|
class TestTravelMode:
|
|
def test_enum_values(self) -> None:
|
|
assert TravelMode.TRANSIT == "TRANSIT"
|
|
assert TravelMode.BICYCLE == "BICYCLE"
|
|
assert TravelMode.WALK == "WALK"
|
|
assert TravelMode.DRIVE == "DRIVE"
|
|
|
|
def test_enum_has_four_members(self) -> None:
|
|
assert len(TravelMode) == 4
|
|
|
|
|
|
class TestTransitRoute:
|
|
@patch("rec.routing.requests.post")
|
|
@patch("rec.routing.nextMonday")
|
|
def test_success_response(self, mock_monday: MagicMock, mock_post: MagicMock) -> None:
|
|
mock_monday.return_value = MagicMock(
|
|
strftime=MagicMock(return_value="2024-01-08T09:00:00.000000Z")
|
|
)
|
|
expected = {"routes": [{"duration": "600s", "distanceMeters": 5000}]}
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 200
|
|
mock_response.json.return_value = expected
|
|
mock_post.return_value = mock_response
|
|
|
|
with patch.dict(os.environ, {"ROUTING_API_KEY": "test-key"}):
|
|
result = transit_route(51.5, -0.1, "London Bridge", TravelMode.TRANSIT)
|
|
|
|
assert result == expected
|
|
mock_post.assert_called_once()
|
|
call_kwargs = mock_post.call_args
|
|
assert call_kwargs.kwargs["headers"]["X-Goog-Api-Key"] == "test-key"
|
|
|
|
@patch("rec.routing.requests.post")
|
|
@patch("rec.routing.nextMonday")
|
|
def test_raises_routing_api_error_on_non_200(self, mock_monday: MagicMock, mock_post: MagicMock) -> None:
|
|
mock_monday.return_value = MagicMock(
|
|
strftime=MagicMock(return_value="2024-01-08T09:00:00.000000Z")
|
|
)
|
|
error_body = {"error": {"message": "Invalid API key", "status": "PERMISSION_DENIED"}}
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 403
|
|
mock_response.json.return_value = error_body
|
|
mock_post.return_value = mock_response
|
|
|
|
with patch.dict(os.environ, {"ROUTING_API_KEY": "bad-key"}):
|
|
with pytest.raises(RoutingApiError) as exc_info:
|
|
transit_route(51.5, -0.1, "London Bridge", TravelMode.TRANSIT)
|
|
|
|
assert exc_info.value.status_code == 403
|
|
assert exc_info.value.response_body == error_body
|
|
|
|
def test_raises_key_error_when_api_key_not_set(self) -> None:
|
|
env = os.environ.copy()
|
|
env.pop("ROUTING_API_KEY", None)
|
|
with patch.dict(os.environ, env, clear=True):
|
|
with pytest.raises(KeyError):
|
|
transit_route(51.5, -0.1, "London Bridge", TravelMode.TRANSIT)
|