Files
ciaovolo/flight-comparator/tests/test_airports.py
domverse 6421f83ca7 Add flight comparator web app with full scan pipeline
Full-stack flight price scanner built on fast-flights v3 (SOCS cookie bypass):

Backend (FastAPI + SQLite):
- REST API with rate limiting, Pydantic v2 validation, paginated responses
- Scan pipeline: resolves airports, queries every day in the window, saves
  individual flights + aggregate route stats to SQLite
- Background async scan processor with real-time progress tracking
- Airport search endpoint backed by OpenFlights dataset
- Daily scan window (all dates, not monthly samples)

Frontend (React 19 + TypeScript + Tailwind CSS v4):
- Dashboard with live scan status and recent scans
- Create scan form: country mode or specific airports (searchable dropdown)
- Scan detail page with expandable route rows showing individual flights
  (date, airline, departure, arrival, price) loaded on demand
- AirportSearch component with debounced live search and multi-select

Database:
- scans → routes → flights schema with FK cascade and auto-update triggers
- Migrations for schema evolution (relaxed country constraint)

Tests:
- 74 tests: unit + integration, isolated per-test SQLite DB
- Confirmed flight fixtures in tests/confirmed_flights.json (50 real flights,
  BDS→FMM Ryanair + BDS→DUS Eurowings, scraped Feb 2026)
- Integration tests parametrized from confirmed routes

Docker:
- Multi-stage builds, Compose orchestration, Nginx reverse proxy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 17:11:51 +01:00

54 lines
1.7 KiB
Python

"""
Smoke tests for airports module.
"""
import sys
sys.path.insert(0, '..')
from airports import get_airports_for_country, resolve_airport_list
def test_get_airports_for_country():
"""Test loading airports for a country."""
de_airports = get_airports_for_country("DE")
assert len(de_airports) > 0
assert all('iata' in a for a in de_airports)
assert all('name' in a for a in de_airports)
assert all('city' in a for a in de_airports)
print(f"✓ Found {len(de_airports)} airports in Germany")
def test_resolve_airport_list_from_country():
"""Test resolving airport list from country."""
airports = resolve_airport_list("DE", None)
assert len(airports) > 0
print(f"✓ Resolved {len(airports)} airports from country DE")
def test_resolve_airport_list_from_custom():
"""Test resolving airport list from custom --from argument."""
airports = resolve_airport_list(None, "FRA,MUC,BER")
assert len(airports) == 3
assert airports[0]['iata'] == 'FRA'
assert airports[1]['iata'] == 'MUC'
assert airports[2]['iata'] == 'BER'
print(f"✓ Resolved custom airport list: {[a['iata'] for a in airports]}")
def test_invalid_country():
"""Test handling of invalid country code."""
try:
get_airports_for_country("XX")
assert False, "Should have raised ValueError"
except ValueError as e:
assert "not found" in str(e)
print("✓ Invalid country code raises appropriate error")
if __name__ == "__main__":
test_get_airports_for_country()
test_resolve_airport_list_from_country()
test_resolve_airport_list_from_custom()
test_invalid_country()
print("\n✅ All airports tests passed!")