Skip to content

Commit 546b103

Browse files
committed
Fix airport list pagination guard
1 parent 8a81dbe commit 546b103

2 files changed

Lines changed: 50 additions & 28 deletions

File tree

app/routers/airport.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ def get_airports_list(
7979
db=Depends(CouchbaseClient),
8080
) -> list[Airport]:
8181
"""Get a list of airports with pagination. Optionally, filter by country."""
82+
completeness_filters = """
83+
airport.airportname IS NOT MISSING
84+
AND airport.airportname IS NOT NULL
85+
AND airport.city IS NOT MISSING
86+
AND airport.city IS NOT NULL
87+
AND airport.country IS NOT MISSING
88+
AND airport.country IS NOT NULL
89+
"""
90+
8291
if country:
8392
query = """
8493
SELECT airport.airportname,
@@ -90,6 +99,7 @@ def get_airports_list(
9099
airport.tz
91100
FROM airport AS airport
92101
WHERE airport.country = $country
102+
AND """ + completeness_filters + """
93103
ORDER BY airport.airportname
94104
LIMIT $limit
95105
OFFSET $offset;
@@ -104,6 +114,7 @@ def get_airports_list(
104114
airport.icao,
105115
airport.tz
106116
FROM airport AS airport
117+
WHERE """ + completeness_filters + """
107118
ORDER BY airport.airportname
108119
LIMIT $limit
109120
OFFSET $offset;
@@ -112,21 +123,11 @@ def get_airports_list(
112123
try:
113124
result = db.query(query, country=country, limit=limit, offset=offset)
114125
airports = [r for r in result]
115-
return _filter_complete_airports(airports)
126+
return airports
116127
except Exception as e:
117128
raise HTTPException(status_code=500, detail=f"Unexpected error: {e}")
118129

119130

120-
def _filter_complete_airports(airports: list[dict]) -> list[dict]:
121-
"""Drop rows that cannot satisfy the Airport response model."""
122-
required_fields = ("airportname", "city", "country")
123-
return [
124-
airport
125-
for airport in airports
126-
if all(field in airport and airport[field] is not None for field in required_fields)
127-
]
128-
129-
130131
class DestinationAirport(BaseModel):
131132
"""Model for Destination Airport"""
132133

app/tests/test_airport.py

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,48 @@
33
from couchbase.exceptions import DocumentNotFoundException
44

55
from app.main import app
6-
from app.routers.airport import _filter_complete_airports
6+
from app.routers.airport import get_airports_list
77

88
client = TestClient(app)
99

1010

11-
def test_filter_complete_airports_skips_incomplete_rows():
12-
complete_airport = {
13-
"airportname": "Test Airport",
14-
"city": "Test City",
15-
"country": "Test Country",
16-
"faa": "TAA",
17-
}
18-
incomplete_airport = {
19-
"city": "Initial Test City",
20-
"country": "Initial Test Country",
21-
"faa": "TESTFAA",
22-
}
23-
24-
assert _filter_complete_airports([complete_airport, incomplete_airport]) == [
25-
complete_airport
26-
]
11+
class RecordingDB:
12+
def __init__(self, rows):
13+
self.rows = rows
14+
self.calls = []
15+
16+
def query(self, query, **params):
17+
self.calls.append((query, params))
18+
return self.rows
19+
20+
21+
def test_list_airports_bakes_required_fields_into_the_query_before_pagination():
22+
db = RecordingDB([])
23+
24+
assert get_airports_list(limit=3, offset=6, db=db) == []
25+
26+
query, params = db.calls[0]
27+
assert "airport.airportname IS NOT MISSING" in query
28+
assert "airport.airportname IS NOT NULL" in query
29+
assert "airport.city IS NOT MISSING" in query
30+
assert "airport.city IS NOT NULL" in query
31+
assert "airport.country IS NOT MISSING" in query
32+
assert "airport.country IS NOT NULL" in query
33+
assert "ORDER BY airport.airportname" in query
34+
assert "LIMIT $limit" in query
35+
assert "OFFSET $offset" in query
36+
assert params == {"country": None, "limit": 3, "offset": 6}
37+
38+
39+
def test_list_airports_bakes_country_filter_into_the_query_when_present():
40+
db = RecordingDB([])
41+
42+
assert get_airports_list(country="France", limit=2, offset=4, db=db) == []
43+
44+
query, params = db.calls[0]
45+
assert "WHERE airport.country = $country" in query
46+
assert "airport.airportname IS NOT MISSING" in query
47+
assert params == {"country": "France", "limit": 2, "offset": 4}
2748

2849

2950
class TestAirport:

0 commit comments

Comments
 (0)