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>
34 lines
921 B
Python
34 lines
921 B
Python
"""
|
||
Smoke tests for searcher module.
|
||
"""
|
||
|
||
import sys
|
||
sys.path.insert(0, '..')
|
||
|
||
from searcher import _parse_duration
|
||
|
||
|
||
def test_parse_duration():
|
||
"""Test duration parsing logic."""
|
||
assert _parse_duration("9h 30m") == 570
|
||
assert _parse_duration("9h") == 540
|
||
assert _parse_duration("90m") == 90
|
||
assert _parse_duration("10h 15m") == 615
|
||
assert _parse_duration("") == 0
|
||
print("✓ Duration parsing works")
|
||
|
||
|
||
def test_parse_duration_edge_cases():
|
||
"""Test edge cases in duration parsing."""
|
||
assert _parse_duration("0h 0m") == 0
|
||
assert _parse_duration("1h 1m") == 61
|
||
assert _parse_duration("24h") == 1440
|
||
print("✓ Duration parsing edge cases work")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
test_parse_duration()
|
||
test_parse_duration_edge_cases()
|
||
print("\n✅ All searcher tests passed!")
|
||
print("ℹ️ Note: Full API integration tests require fast-flights and live network")
|