Flyair_wonderplan / tests /test_intelligence.py
RKugel's picture
Pricing reliability + deal intelligence upgrade (provider telemetry, negative caching, city-code queries, stale-fare guard, fare tracker, true trip cost, TripRank; 78 unit tests)
13e0153 verified
Raw
History Blame Contribute Delete
5.65 kB
"""Unit tests for the Deal Intelligence Engine (pure functions, no network)."""
import os
import sys
from datetime import date
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
os.environ.setdefault("TRAVELPAYOUTS_TOKEN", "test-token")
from flights import intelligence as iq
PASS = 0
def check(name, cond):
global PASS
assert cond, f"FAIL: {name}"
PASS += 1
print(f" ok {name}")
# ── fair_price: hedonic baseline sanity ──────────────────────────────────────
short = iq.fair_price(500) # TLV->ATH-ish
medium = iq.fair_price(3200) # TLV->LON-ish
long = iq.fair_price(9100) # TLV->JFK-ish
check("baseline increases with distance", short < medium < long)
check("short-haul in sane range", 60 <= short <= 160)
check("long-haul in sane range", 300 <= long <= 900)
per_km_short = short / 500
per_km_long = long / 9100
check("economies of distance (concave curve)", per_km_long < per_km_short)
july_fri = iq.fair_price(3200, date(2026, 7, 3)) # Friday in July (peak+peak)
feb_tue = iq.fair_price(3200, date(2026, 2, 10)) # Tuesday in February (trough)
check("July Friday priced above February Tuesday", july_fri > feb_tue)
check("round trip < 2x one-way", iq.fair_price(3200, round_trip=True) < 2 * iq.fair_price(3200))
# ── deal_score: monotone, labeled, explainable ───────────────────────────────
steal = iq.deal_score(0.5 * medium, medium)
fairp = iq.deal_score(medium, medium)
rip = iq.deal_score(1.8 * medium, medium)
check("half typical scores ~95", steal["score"] >= 90)
check("typical price scores 60", fairp["score"] == 60)
check("1.8x typical floors", rip["score"] <= 10)
check("scores monotone", steal["score"] > fairp["score"] > rip["score"])
check("labels attached", steal["label"] == "exceptional deal" and fairp["label"] == "typical price")
check("vs_typical_pct signed", steal["vs_typical_pct"] == -50 and rip["vs_typical_pct"] == 80)
check("degenerate fair handled", iq.deal_score(100, 0)["score"] is None)
# ── annotate_offers: uses airport coords, skips unknowns ─────────────────────
offers = [
{"price": 120.0, "origin": "TLV", "destination": "ATH", "date": "2026-08-10", "round_trip": False},
{"price": None, "origin": "TLV", "destination": "ATH", "date": "2026-08-10"}, # unpriced
{"price": 99.0, "origin": "XXQ", "destination": "ZZQ", "date": "2026-08-10"}, # unknown route
]
iq.annotate_offers(offers)
check("priced known route annotated", offers[0].get("deal", {}).get("score") is not None)
check("unpriced offer skipped", "deal" not in offers[1])
check("unknown route skipped, no crash", "deal" not in offers[2])
# ── date_insights: fly-Tuesday-save-$X analytics ─────────────────────────────
month = [
{"price": 210.0, "date": "2026-08-03"}, # Monday
{"price": 150.0, "date": "2026-08-04"}, # Tuesday <- cheapest
{"price": 205.0, "date": "2026-08-07"}, # Friday
{"price": 260.0, "date": "2026-08-08"}, # Saturday <- priciest
{"price": 155.0, "date": "2026-08-11"}, # Tuesday
]
ins = iq.date_insights(month)
check("cheapest date found", ins["cheapest_date"] == "2026-08-04" and ins["cheapest_date_price"] == 150.0)
check("flex savings computed", ins["max_flex_savings"] == 110.0)
check("best weekday is Tuesday", ins.get("best_weekday") == "Tuesday")
check("weekday savings positive", ins.get("weekday_avg_savings", 0) > 0)
check("insufficient data -> None", iq.date_insights([{"price": 100.0, "date": "2026-08-03"}]) is None)
# ── wander_scores: utility per dollar, best = 100 ────────────────────────────
alts = [
{"similarity": 0.90, "cheapest_flight": {"price": 300.0}}, # 0.0030 per $
{"similarity": 0.80, "cheapest_flight": {"price": 160.0}}, # 0.0050 per $ <- best value
{"similarity": 0.95, "cheapest_flight": {"price": None}}, # unpriced -> no score
]
iq.wander_scores(alts)
check("best value scores 100", alts[1]["wander_score"] == 100)
check("worse value scaled down", alts[0]["wander_score"] == 60)
check("unpriced alt unscored", "wander_score" not in alts[2])
check("empty set safe", iq.wander_scores([]) == [])
# ── scan_start_dates: multi-month cheapest-date engine ───────────────────────
d0 = date(2026, 11, 20)
scan = iq.scan_start_dates(d0, 3)
check("scan keeps start date", scan[0] == d0)
check("scan hits following month firsts", scan[1] == date(2026, 12, 1))
check("scan wraps the year", scan[2] == date(2027, 1, 1))
check("scan n=1 is just start", iq.scan_start_dates(d0, 1) == [d0])
# ── price_calendar: cheapest per date, date-sorted ───────────────────────────
cal = iq.price_calendar([
{"price": 220.0, "date": "2026-08-10", "stops": 1},
{"price": 180.0, "date": "2026-08-10", "stops": 0}, # cheaper same-day wins
{"price": 150.0, "date": "2026-08-04", "stops": 0},
{"price": None, "date": "2026-08-05"}, # unpriced skipped
{"price": 300.0, "date": "not-a-date"}, # junk skipped
])
check("calendar keeps cheapest per date", [c["price"] for c in cal] == [150.0, 180.0])
check("calendar date-sorted", [c["date"] for c in cal] == ["2026-08-04", "2026-08-10"])
check("calendar carries stops", cal[1]["stops"] == 0)
print(f"\nALL {PASS} CHECKS PASSED")