Harden App Store build for review

This commit is contained in:
FuelBoard Contributor
2026-10-01 12:19:05 +01:00
parent c7731d2b36
commit 50c543c776
14 changed files with 177 additions and 412 deletions
@@ -3,23 +3,11 @@ import XCTest
@testable import FuelBoardShared
#endif
/// P0 live chain: GitHub mirror FIRST everywhere → [dev-only LAN relay] →
/// P0 live chain: public GitHub mirror first everywhere →
/// (app: bundled dump in ContentView's catch, widget: cache → placeholder).
/// The relay is NOT part of the consumer chain — it only joins behind the
/// hidden dev flag `fuelboard.relayFallback`.
/// No LAN relay fallback is compiled into the app binary.
final class LiveChainTests: XCTestCase {
override func setUp() {
super.setUp()
FuelBeacon.isEnabled = false // chain tests must not fire real pings
FuelStore.saveRelayFallbackEnabled(false) // dev flag off by default
}
override func tearDown() {
FuelBeacon.isEnabled = true
super.tearDown()
}
// MARK: Fixtures
private final class StubProvider: FuelPriceProviding {
@@ -45,86 +33,56 @@ final class LiveChainTests: XCTestCase {
prices: [.e10: 137.9, .e5: 144.9, .diesel: 144.9], priceUpdated: nil)
}
// MARK: Full path (app refresh): GitHub first
// MARK: Full path (app refresh): GitHub mirror only
func testFullPathPrefersMirror() async throws {
func testFullPathUsesMirror() async throws {
let mirror = StubProvider(result: [fixtureStation()])
let relay = StubProvider(error: FuelProviderError.relayUnavailable)
let chain = LiveChainProvider(mirror: mirror, relay: relay)
let chain = LiveChainProvider(mirror: mirror)
let stations = try await chain.fetchStations(near: nil, lng: nil, fuel: .e10, radiusKM: nil)
XCTAssertEqual(stations.count, 1)
XCTAssertEqual(mirror.callCount, 1, "full path must try the GitHub mirror first")
XCTAssertEqual(relay.callCount, 0, "relay must not run when the mirror serves")
XCTAssertEqual(mirror.callCount, 1, "full path must use the public GitHub mirror")
XCTAssertEqual(LiveChainProvider.lastSource, "github")
}
func testFullPathRelaySkippedWhenDisabled() async {
func testFullPathPropagatesMirrorFailure() async {
let mirror = StubProvider(error: FuelProviderError.mirrorUnavailable)
let relay = StubProvider(result: [fixtureStation("relay")])
let chain = LiveChainProvider(mirror: mirror, relay: relay)
let chain = LiveChainProvider(mirror: mirror)
do {
_ = try await chain.fetchStations(near: nil, lng: nil, fuel: .e10, radiusKM: nil)
XCTFail("chain must throw when the mirror fails and the relay flag is off")
XCTFail("chain must throw when the public mirror fails; callers decide cache/bundled fallback")
} catch {
XCTAssertEqual(relay.callCount, 0, "consumers must NEVER attempt the relay")
XCTAssertEqual(mirror.callCount, 1)
}
}
func testFullPathRelayFallbackWhenDevFlagOn() async throws {
FuelStore.saveRelayFallbackEnabled(true)
let mirror = StubProvider(error: FuelProviderError.mirrorUnavailable)
let relay = StubProvider(result: [fixtureStation("relay")])
let chain = LiveChainProvider(mirror: mirror, relay: relay)
// MARK: Focused path (alert checks + widget): GitHub mirror only
let stations = try await chain.fetchStations(near: nil, lng: nil, fuel: .e10, radiusKM: nil)
XCTAssertEqual(stations.first?.id, "relay")
XCTAssertEqual(relay.callCount, 1, "dev flag on → relay fallback serves")
XCTAssertEqual(LiveChainProvider.lastSource, "relay")
}
// MARK: Focused path (alert checks + widget): GitHub first too
func testFocusedPathPrefersMirror() async throws {
func testFocusedPathUsesMirror() async throws {
let mirror = StubProvider(result: [fixtureStation("mirror")])
let relay = StubProvider(result: [fixtureStation("relay")])
let chain = LiveChainProvider(mirror: mirror, relay: relay)
let chain = LiveChainProvider(mirror: mirror)
let stations = try await chain.fetchStations(near: 53.7, lng: -1.8, fuel: .e10, radiusKM: 5)
XCTAssertEqual(stations.first?.id, "mirror", "focused path must prefer the mirror — the relay is unreachable off-LAN")
XCTAssertEqual(relay.callCount, 0)
XCTAssertEqual(stations.first?.id, "mirror", "focused path must use the public GitHub mirror")
XCTAssertEqual(mirror.callCount, 1)
XCTAssertEqual(LiveChainProvider.lastSource, "github")
}
func testFocusedPathRelaySkippedWhenDisabled() async {
func testFocusedPathPropagatesMirrorFailure() async {
let mirror = StubProvider(error: FuelProviderError.mirrorUnavailable)
let relay = StubProvider(result: [fixtureStation("relay")])
let chain = LiveChainProvider(mirror: mirror, relay: relay)
let chain = LiveChainProvider(mirror: mirror)
do {
_ = try await chain.fetchStations(near: 53.7, lng: -1.8, fuel: .e10, radiusKM: 5)
XCTFail("focused path must throw when the mirror fails and the relay flag is off")
XCTFail("focused path must throw when the public mirror fails")
} catch {
XCTAssertEqual(relay.callCount, 0, "consumers must NEVER attempt the relay")
XCTAssertEqual(mirror.callCount, 1)
}
}
func testFocusedPathRelayFallbackWhenDevFlagOn() async throws {
FuelStore.saveRelayFallbackEnabled(true)
let mirror = StubProvider(error: FuelProviderError.mirrorUnavailable)
let relay = StubProvider(result: [fixtureStation("relay")])
let chain = LiveChainProvider(mirror: mirror, relay: relay)
let stations = try await chain.fetchStations(near: 53.7, lng: -1.8, fuel: .e10, radiusKM: 5)
XCTAssertEqual(stations.first?.id, "relay")
XCTAssertEqual(relay.callCount, 1)
}
// MARK: Mirror focused projection (replaces the relay's server-side radius)
func testMirrorFocusedFiltersByFuelRadiusDistanceAndLimit() {
@@ -165,24 +123,4 @@ final class LiveChainTests: XCTestCase {
XCTAssertFalse(MirrorFuelProvider.canReuseCache(cachedDay: "2026-08-15", latestDay: nil))
}
// MARK: Beacon
func testBeaconURLCarriesAppAttribution() {
guard let url = FuelBeacon.beaconURL(source: "github", n: 8022) else {
return XCTFail("beacon URL must build")
}
XCTAssertTrue(url.absoluteString.contains("api/v1/widget-diag"))
let items = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems ?? []
XCTAssertTrue(items.contains(URLQueryItem(name: "intent", value: "app-live")))
XCTAssertTrue(items.contains(URLQueryItem(name: "source", value: "github")))
XCTAssertTrue(items.contains(URLQueryItem(name: "n", value: "8022")))
}
func testBeaconGatedByDevFlag() {
FuelBeacon.isEnabled = true
FuelStore.saveRelayFallbackEnabled(false)
XCTAssertFalse(FuelBeacon.shouldFire, "consumers: beacon must never fire (no local-network attempt)")
FuelStore.saveRelayFallbackEnabled(true)
XCTAssertTrue(FuelBeacon.shouldFire, "dev flag on: beacon fires for attribution")
}
}
}