ba0688a412
route-explorer's /api/token sits behind invisible Cloudflare Turnstile
that requires Apple's Private Access Token attestation. Third-party
iOS apps don't qualify for PAT issuance, and Linux Docker containers
can't pass it either (cross-OS fingerprint, even with patchright /
Camoufox). Migrates direct-flight search to FlightAware; multi-stop
and where-can-I-go remain via embedded SFSafariViewController.
- FlightAwareScheduleClient — scrapes route.rvt + trackpoll JSON for
real schedules without auth. T+0..2 day window. Tests against
captured HTML fixtures.
- BlobRouteClient — pulls the public Vercel blob route catalog
route-explorer's frontend reads (no auth, no Turnstile).
- DiagnosticLogger + LoggingURLSessionDelegate + DiagnosticsView —
device-shareable forensic trace. Boot header captures device, OS,
locale, UA; share-sheet export of session logs.
- TurnstileDebugView — live WKWebView gate inspector. Used to prove
the PAT-entitlement gap on a real device.
- RouteExplorerBrowserView — SFSafariViewController wrapper. Real
Safari clears Turnstile naturally; the in-app browser opens at
pre-filled search URLs. Surfaced from Search ("Open in
route-explorer") and Settings → Tools.
- RouteExplorerTokenStore + RouteExplorerSetupView — bookmarklet
capture flow (token round-tripped via flights://routeexplorer-token
URL scheme). Kept dormant for future use.
backend/ — Docker proxy attempts (Playwright, patchright, Camoufox).
All fail on Linux because Cloudflare auto-denies before the Turnstile
widget renders. Documented; kept as scaffolding for a future paid-
solver integration.
scripts/probe_flightaware.py — reference algorithm for the FA path.
scripts/probe_nodriver.py — local-Mac sanity check confirming the
gate clears with real macOS Chrome (proves the blocker is
fingerprint-level, not network-level).
66 lines
2.6 KiB
Swift
66 lines
2.6 KiB
Swift
import XCTest
|
|
@testable import Flights
|
|
|
|
/// Tests for the standby tracking fields on the history flight model.
|
|
///
|
|
/// NOTE: The codebase's history record type is `LoggedFlight` (see
|
|
/// `Flights/Models/LoggedFlight.swift`). The task spec referred to it as
|
|
/// "HistoryFlight" — that name does not exist. These tests therefore
|
|
/// target `LoggedFlight`, which is the actual @Model SwiftData type that
|
|
/// owns `standbyOutcome` and the computed `wasStandby`.
|
|
///
|
|
/// Assumption to verify: there is no separate `HistoryFlight` type.
|
|
final class HistoryFlightModelTests: XCTestCase {
|
|
|
|
// MARK: wasStandby
|
|
|
|
func test_wasStandby_isTrue_whenOutcomeIsStandbyMade() {
|
|
let flight = LoggedFlight(departureIATA: "LAX", arrivalIATA: "JFK")
|
|
flight.standbyOutcome = "standby-made"
|
|
XCTAssertTrue(flight.wasStandby,
|
|
"standby-made should count as a standby attempt")
|
|
}
|
|
|
|
func test_wasStandby_isTrue_whenOutcomeIsStandbyBumped() {
|
|
let flight = LoggedFlight(departureIATA: "LAX", arrivalIATA: "JFK")
|
|
flight.standbyOutcome = "standby-bumped"
|
|
XCTAssertTrue(flight.wasStandby,
|
|
"standby-bumped should count as a standby attempt")
|
|
}
|
|
|
|
func test_wasStandby_isFalse_whenOutcomeIsConfirmed() {
|
|
let flight = LoggedFlight(departureIATA: "LAX", arrivalIATA: "JFK")
|
|
flight.standbyOutcome = "confirmed"
|
|
XCTAssertFalse(flight.wasStandby,
|
|
"confirmed is a positive-space ticket, not standby")
|
|
}
|
|
|
|
func test_wasStandby_isFalse_whenOutcomeIsNil() {
|
|
let flight = LoggedFlight(departureIATA: "LAX", arrivalIATA: "JFK")
|
|
flight.standbyOutcome = nil
|
|
XCTAssertFalse(flight.wasStandby,
|
|
"nil outcome (legacy / unmigrated) should not count as standby")
|
|
}
|
|
|
|
// MARK: Default init — all new standby fields nil
|
|
|
|
func test_defaultInit_hasAllStandbyFieldsNil() {
|
|
let flight = LoggedFlight()
|
|
|
|
XCTAssertNil(flight.standbyOutcome,
|
|
"standbyOutcome must default to nil for CloudKit migration safety")
|
|
XCTAssertNil(flight.standbyAttemptedAt,
|
|
"standbyAttemptedAt must default to nil")
|
|
XCTAssertNil(flight.standbyClearedAt,
|
|
"standbyClearedAt must default to nil")
|
|
XCTAssertNil(flight.standbyClass,
|
|
"standbyClass must default to nil")
|
|
XCTAssertNil(flight.standbyNotes,
|
|
"standbyNotes must default to nil")
|
|
|
|
// And the derived flag follows.
|
|
XCTAssertFalse(flight.wasStandby,
|
|
"a freshly-constructed record is not a standby attempt")
|
|
}
|
|
}
|