Various improvements

This commit is contained in:
Edward Betts 2026-06-30 12:31:51 +01:00
parent 5f6cb57c2a
commit bc7a2e89d0
4 changed files with 160 additions and 75 deletions

View file

@ -1,8 +1,14 @@
"""Regression tests for trip page route wiring and rendering."""
from datetime import date
from datetime import date, datetime
import typing
from unittest import mock
import flask
import agenda.trip
import agenda.trip_schengen
import agenda.weather
import web_view
from agenda.types import Trip
@ -13,61 +19,40 @@ def test_trip_page_passes_data_dir_to_unbooked_flight_helper() -> None:
captured: dict[str, str] = {}
with web_view.app.app_context():
original_get_trip_list = web_view.get_trip_list
original_add_schengen = (
web_view.agenda.trip_schengen.add_schengen_compliance_to_trip
)
original_collect_trip_coordinates = (
web_view.agenda.trip.collect_trip_coordinates
)
original_get_trip_routes = web_view.agenda.trip.get_trip_routes
original_add_coordinates = (
web_view.agenda.trip.add_coordinates_for_unbooked_flights
)
original_get_trip_weather = web_view.agenda.weather.get_trip_weather
original_render_template = web_view.flask.render_template
try:
web_view.get_trip_list = lambda: [trip]
web_view.agenda.trip_schengen.add_schengen_compliance_to_trip = lambda t: t
web_view.agenda.trip.collect_trip_coordinates = lambda _trip: []
web_view.agenda.trip.get_trip_routes = lambda _trip, _data_dir: []
def fake_add_coordinates(
_routes: list[typing.Any],
_coordinates: list[typing.Any],
data_dir: str,
) -> None:
captured["data_dir"] = data_dir
web_view.agenda.trip.add_coordinates_for_unbooked_flights = (
fake_add_coordinates
)
web_view.agenda.weather.get_trip_weather = lambda *_args, **_kwargs: []
web_view.flask.render_template = lambda *_args, **_kwargs: "ok"
def fake_add_coordinates(
_routes: list[typing.Any],
_coordinates: list[typing.Any],
data_dir: str,
) -> None:
captured["data_dir"] = data_dir
with (
mock.patch.object(web_view, "get_trip_list", return_value=[trip]),
mock.patch.object(
agenda.trip_schengen,
"add_schengen_compliance_to_trip",
side_effect=lambda t: t,
),
mock.patch.object(agenda.trip, "collect_trip_coordinates", return_value=[]),
mock.patch.object(agenda.trip, "get_trip_routes", return_value=[]),
mock.patch.object(
agenda.trip,
"add_coordinates_for_unbooked_flights",
side_effect=fake_add_coordinates,
),
mock.patch.object(agenda.weather, "get_trip_weather", return_value=[]),
mock.patch.object(flask, "render_template", return_value="ok"),
):
with web_view.app.test_request_context("/trip/2025-01-28"):
result = web_view.trip_page("2025-01-28")
assert result == "ok"
assert captured["data_dir"] == web_view.app.config["PERSONAL_DATA"]
finally:
web_view.get_trip_list = original_get_trip_list
web_view.agenda.trip_schengen.add_schengen_compliance_to_trip = (
original_add_schengen
)
web_view.agenda.trip.collect_trip_coordinates = (
original_collect_trip_coordinates
)
web_view.agenda.trip.get_trip_routes = original_get_trip_routes
web_view.agenda.trip.add_coordinates_for_unbooked_flights = (
original_add_coordinates
)
web_view.agenda.weather.get_trip_weather = original_get_trip_weather
web_view.flask.render_template = original_render_template
def test_trip_page_renders_with_date_only_train_leg() -> None:
"""Trip page should render when train legs use date values (no time)."""
def test_trip_page_renders_with_mixed_date_and_datetime_train_leg() -> None:
"""Trip page should render when train leg times mix dates and datetimes."""
trip = Trip(
start=date(2025, 1, 28),
travel=[
@ -93,7 +78,7 @@ def test_trip_page_renders_with_date_only_train_leg() -> None:
"from": "A",
"to": "B",
"depart": date(2025, 1, 28),
"arrive": date(2025, 1, 28),
"arrive": datetime(2025, 1, 28, 16, 49),
"from_station": {
"name": "A",
"country": "gb",
@ -114,11 +99,10 @@ def test_trip_page_renders_with_date_only_train_leg() -> None:
)
with web_view.app.app_context():
original_get_trip_list = web_view.get_trip_list
original_get_trip_weather = web_view.agenda.weather.get_trip_weather
try:
web_view.get_trip_list = lambda: [trip]
web_view.agenda.weather.get_trip_weather = lambda *_args, **_kwargs: []
with (
mock.patch.object(web_view, "get_trip_list", return_value=[trip]),
mock.patch.object(agenda.weather, "get_trip_weather", return_value=[]),
):
web_view.app.config["TESTING"] = True
with web_view.app.test_client() as client:
@ -126,6 +110,71 @@ def test_trip_page_renders_with_date_only_train_leg() -> None:
assert response.status_code == 200
assert b"Test Rail" in response.data
finally:
web_view.get_trip_list = original_get_trip_list
web_view.agenda.weather.get_trip_weather = original_get_trip_weather
def test_trip_page_hides_train_times_for_date_only_train_leg() -> None:
"""Trip page should not show midnight times for unbooked date-only trains."""
trip = Trip(
start=date(2026, 8, 23),
travel=[
{
"type": "train",
"depart": date(2026, 8, 23),
"arrive": date(2026, 8, 23),
"from": "London St Pancras",
"to": "Paris Gare du Nord",
"from_station": {
"name": "London St Pancras",
"country": "gb",
"latitude": 51.532,
"longitude": -0.126,
},
"to_station": {
"name": "Paris Gare du Nord",
"country": "fr",
"latitude": 48.88,
"longitude": 2.355,
},
"legs": [
{
"from": "London St Pancras",
"to": "Paris Gare du Nord",
"depart": date(2026, 8, 23),
"arrive": date(2026, 8, 23),
"from_station": {
"name": "London St Pancras",
"country": "gb",
"latitude": 51.532,
"longitude": -0.126,
},
"to_station": {
"name": "Paris Gare du Nord",
"country": "fr",
"latitude": 48.88,
"longitude": 2.355,
},
"operator": "Eurostar",
"class": "Eurostar Plus",
}
],
}
],
)
with web_view.app.app_context():
with (
mock.patch.object(web_view, "get_trip_list", return_value=[trip]),
mock.patch.object(agenda.weather, "get_trip_weather", return_value=[]),
):
web_view.app.config["TESTING"] = True
with web_view.app.test_client() as client:
response = client.get("/trip/2026-08-23")
assert response.status_code == 200
page = response.data.decode()
assert "London St Pancras → Paris Gare du Nord" in page
assert "Eurostar" in page
assert "Eurostar Plus" in page
assert "00:00" not in page
assert "🕒" not in page