Harden App Store build for review
This commit is contained in:
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user