diff --git a/tests/test_busy.py b/tests/test_busy.py
index d3b80fc..8a12d8c 100644
--- a/tests/test_busy.py
+++ b/tests/test_busy.py
@@ -1,4 +1,4 @@
-from datetime import date, datetime, timezone
+from datetime import date, datetime
import agenda.busy
import agenda.travel as travel
@@ -157,8 +157,7 @@ def test_parse_datetime_field():
# Test with datetime object
dt = datetime(2023, 1, 1, 12, 0, 0)
parsed_dt, parsed_date = _parse_datetime_field(dt)
- assert parsed_dt == dt.replace(tzinfo=timezone.utc)
- assert parsed_dt.tzinfo == timezone.utc
+ assert parsed_dt == dt
assert parsed_date == date(2023, 1, 1)
# Test with ISO string
diff --git a/tests/test_busy_timezone.py b/tests/test_busy_timezone.py
deleted file mode 100644
index 73d35dd..0000000
--- a/tests/test_busy_timezone.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Regression tests for timezone handling in busy location logic."""
-
-from datetime import date, datetime, timezone
-
-import agenda.busy
-from agenda.types import Trip
-
-
-def test_mixed_naive_and_aware_arrivals_do_not_crash() -> None:
- """Most recent travel should compare mixed timezone styles safely."""
- trips = [
- Trip(
- start=date(2099, 12, 30),
- travel=[
- {
- "type": "flight",
- "arrive": datetime(2100, 1, 1, 10, 0, 0),
- "to": "CDG",
- "to_airport": {"country": "fr", "city": "Paris"},
- },
- {
- "type": "flight",
- "arrive": datetime(2100, 1, 1, 12, 0, 0, tzinfo=timezone.utc),
- "to": "AMS",
- "to_airport": {"country": "nl", "city": "Amsterdam"},
- },
- ],
- )
- ]
-
- location = agenda.busy._find_most_recent_travel_before_date(date(2100, 1, 1), trips)
- assert location is not None
- assert location[0] == "Amsterdam"
- assert location[1] is not None
- assert location[1].alpha_2 == "NL"
diff --git a/tests/test_trip.py b/tests/test_trip.py
deleted file mode 100644
index 69c0e6e..0000000
--- a/tests/test_trip.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""Tests for trip map coordinate assembly."""
-
-from datetime import date
-
-import agenda.trip
-from agenda.types import Trip
-from web_view import app
-
-
-def test_add_coordinates_for_unbooked_flights_adds_missing_airports() -> None:
- """Unbooked routes should contribute missing airport pins."""
- routes = [
- {
- "type": "unbooked_flight",
- "key": "LHR_Paris_fr",
- "from_iata": "LHR",
- "to_iata": "CDG",
- "from": (51.47, -0.45),
- "to": (49.01, 2.55),
- }
- ]
- coordinates = [
- {
- "name": "Heathrow Airport",
- "type": "airport",
- "latitude": 51.47,
- "longitude": -0.45,
- }
- ]
- airports = {
- "LHR": {
- "name": "Heathrow Airport",
- "latitude": 51.47,
- "longitude": -0.45,
- },
- "CDG": {
- "name": "Paris Charles de Gaulle Airport",
- "latitude": 49.01,
- "longitude": 2.55,
- },
- }
-
- with app.app_context():
- original_parse_yaml = agenda.trip.travel.parse_yaml
- try:
- agenda.trip.travel.parse_yaml = lambda _name, _data_dir: airports
- agenda.trip.add_coordinates_for_unbooked_flights(
- routes, coordinates, app.config["PERSONAL_DATA"]
- )
- finally:
- agenda.trip.travel.parse_yaml = original_parse_yaml
-
- airport_names = {
- coord["name"] for coord in coordinates if coord["type"] == "airport"
- }
- assert airport_names == {"Heathrow Airport", "Paris Charles de Gaulle Airport"}
-
-
-def test_get_coordinates_and_routes_adds_unbooked_flight_airports() -> None:
- """Trip list map data should include pins for unbooked flights."""
- trips = [Trip(start=date(2026, 7, 20))]
- unbooked_routes = [
- {
- "type": "unbooked_flight",
- "key": "LHR_Paris_fr",
- "from_iata": "LHR",
- "to_iata": "CDG",
- "from": (51.47, -0.45),
- "to": (49.01, 2.55),
- }
- ]
- airports = {
- "LHR": {
- "name": "Heathrow Airport",
- "latitude": 51.47,
- "longitude": -0.45,
- },
- "CDG": {
- "name": "Paris Charles de Gaulle Airport",
- "latitude": 49.01,
- "longitude": 2.55,
- },
- }
-
- with app.app_context():
- original_collect_trip_coordinates = agenda.trip.collect_trip_coordinates
- original_get_trip_routes = agenda.trip.get_trip_routes
- original_parse_yaml = agenda.trip.travel.parse_yaml
- try:
- agenda.trip.collect_trip_coordinates = lambda _trip: []
- agenda.trip.get_trip_routes = lambda _trip, _data_dir: unbooked_routes
- agenda.trip.travel.parse_yaml = lambda _name, _data_dir: airports
-
- coordinates, _routes = agenda.trip.get_coordinates_and_routes(trips)
- finally:
- agenda.trip.collect_trip_coordinates = original_collect_trip_coordinates
- agenda.trip.get_trip_routes = original_get_trip_routes
- agenda.trip.travel.parse_yaml = original_parse_yaml
-
- airport_names = {
- coord["name"] for coord in coordinates if coord["type"] == "airport"
- }
- assert airport_names == {"Heathrow Airport", "Paris Charles de Gaulle Airport"}
diff --git a/tests/test_trip_page_route.py b/tests/test_trip_page_route.py
deleted file mode 100644
index d471caa..0000000
--- a/tests/test_trip_page_route.py
+++ /dev/null
@@ -1,131 +0,0 @@
-"""Regression tests for trip page route wiring and rendering."""
-
-from datetime import date
-import typing
-
-import web_view
-from agenda.types import Trip
-
-
-def test_trip_page_passes_data_dir_to_unbooked_flight_helper() -> None:
- """Trip page should call helper with routes, coordinates and data_dir."""
- trip = Trip(start=date(2025, 1, 28))
- 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"
-
- 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)."""
- trip = Trip(
- start=date(2025, 1, 28),
- travel=[
- {
- "type": "train",
- "depart": date(2025, 1, 28),
- "from": "A",
- "to": "B",
- "from_station": {
- "name": "A",
- "country": "gb",
- "latitude": 51.5,
- "longitude": -0.1,
- },
- "to_station": {
- "name": "B",
- "country": "gb",
- "latitude": 51.6,
- "longitude": -0.2,
- },
- "legs": [
- {
- "from": "A",
- "to": "B",
- "depart": date(2025, 1, 28),
- "arrive": date(2025, 1, 28),
- "from_station": {
- "name": "A",
- "country": "gb",
- "latitude": 51.5,
- "longitude": -0.1,
- },
- "to_station": {
- "name": "B",
- "country": "gb",
- "latitude": 51.6,
- "longitude": -0.2,
- },
- "operator": "Test Rail",
- }
- ],
- }
- ],
- )
-
- 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: []
- web_view.app.config["TESTING"] = True
-
- with web_view.app.test_client() as client:
- response = client.get("/trip/2025-01-28")
-
- 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
diff --git a/tests/test_weekends_route.py b/tests/test_weekends_route.py
deleted file mode 100644
index 46de40c..0000000
--- a/tests/test_weekends_route.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""Tests for weekends route query validation."""
-
-from datetime import date
-import typing
-
-import pytest
-
-import web_view
-
-
-@pytest.fixture # type: ignore[untyped-decorator]
-def client() -> typing.Any:
- """Flask test client."""
- web_view.app.config["TESTING"] = True
- with web_view.app.test_client() as c:
- yield c
-
-
-def test_weekends_rejects_year_before_2020(client: typing.Any) -> None:
- """Years before 2020 should return HTTP 400."""
- response = client.get("/weekends?year=2019&week=1")
- assert response.status_code == 400
- assert b"Year must be between 2020" in response.data
-
-
-def test_weekends_rejects_year_more_than_five_years_ahead(client: typing.Any) -> None:
- """Years beyond current year + 5 should return HTTP 400."""
- too_far = date.today().year + 6
- response = client.get(f"/weekends?year={too_far}&week=1")
- assert response.status_code == 400
- assert b"Year must be between 2020" in response.data
diff --git a/update.py b/update.py
index f6e5ef3..97e4d41 100755
--- a/update.py
+++ b/update.py
@@ -321,9 +321,6 @@ def update_thespacedevs(config: flask.config.Config) -> None:
existing_data = agenda.thespacedevs.load_cached_launches(rocket_dir)
assert existing_data
- if agenda.thespacedevs.is_launches_cache_fresh(rocket_dir):
- return
-
# Update active crewed mission cache used by the launches page.
# Uses the 2-hour TTL; failures are handled internally with cache fallback.
active_crewed = agenda.thespacedevs.get_active_crewed_flights(rocket_dir)
diff --git a/web_view.py b/web_view.py
index 18a62dc..4fa2d7c 100755
--- a/web_view.py
+++ b/web_view.py
@@ -268,16 +268,6 @@ async def gaps_page() -> str:
async def weekends() -> str:
"""List of available weekends using an optional date, week, or year parameter."""
today = datetime.now().date()
- min_year = 2020
- max_year = today.year + 5
-
- def validate_year(year: int) -> None:
- """Validate year parameter range for weekends page."""
- if year < min_year or year > max_year:
- flask.abort(
- 400, description=f"Year must be between {min_year} and {max_year}."
- )
-
date_str = flask.request.args.get("date")
week_str = flask.request.args.get("week")
year_str = flask.request.args.get("year")
@@ -285,14 +275,12 @@ async def weekends() -> str:
if date_str:
try:
start = datetime.strptime(date_str, "%Y-%m-%d").date()
- validate_year(start.year)
except ValueError:
return flask.abort(400, description="Invalid date format. Use YYYY-MM-DD.")
elif week_str:
try:
week = int(week_str)
year = int(year_str) if year_str else today.year
- validate_year(year)
if week < 1 or week > 53:
return flask.abort(
400, description="Week number must be between 1 and 53."
@@ -305,13 +293,6 @@ async def weekends() -> str:
return flask.abort(
400, description="Invalid week or year format. Use integers."
)
- elif year_str:
- try:
- year = int(year_str)
- validate_year(year)
- start = date(year, 1, 1)
- except ValueError:
- return flask.abort(400, description="Invalid year format. Use an integer.")
else:
start = date(today.year, 1, 1)
@@ -933,7 +914,9 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]:
if flight_country:
flight_locations.append((city, flight_country))
- existing_location_keys = {(loc, c.alpha_2.lower()) for loc, c in trip.locations()}
+ existing_location_keys = {
+ (loc, c.alpha_2.lower()) for loc, c in trip.locations()
+ }
all_locations = list(trip.locations()) + [
(city, country)
for city, country in flight_locations
@@ -1035,9 +1018,7 @@ def trip_page(start: str) -> str:
coordinates = agenda.trip.collect_trip_coordinates(trip)
routes = agenda.trip.get_trip_routes(trip, app.config["PERSONAL_DATA"])
- agenda.trip.add_coordinates_for_unbooked_flights(
- routes, coordinates, app.config["PERSONAL_DATA"]
- )
+ agenda.trip.add_coordinates_for_unbooked_flights(routes, coordinates)
for route in routes:
if "geojson_filename" in route: