Favourites are fuel-scoped: starring pins the station for one fuel only

Fixing the bug where favouriting an Unleaded entry also created a Diesel
favourite. Favourites are now [FavouriteEntry] = (station, fuel) pairs:
- Starring a row pins it only for the fuel being viewed
- Favourites tabs show only fuels that actually have favourites
- Geofence monitor gives priority slots only to favourites matching the
  monitored fuel
- Tests updated + new fuel-scoping test (31/31 passing)
This commit is contained in:
FuelBoard Contributor
2026-08-12 08:31:08 +01:00
parent 0dbf88ee7d
commit 35e0adaf0b
6 changed files with 88 additions and 54 deletions
@@ -217,18 +217,29 @@ final class FuelTypeLabelTests: XCTestCase {
final class FavouriteRefreshTests: XCTestCase {
func testRefreshedFavouritesApplyFreshPrices() {
let fav = FuelStation(id: "s1", name: "OLD NAME", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 140.0], priceUpdated: nil)
let fav = FavouriteEntry(station: FuelStation(id: "s1", name: "OLD NAME", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 140.0], priceUpdated: nil), fuel: .e10)
let fresh = FuelStation(id: "s1", name: "Fresh Station", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 132.9], priceUpdated: nil)
let updated = FuelStore.refreshedFavourites([fav], from: [fresh])
XCTAssertEqual(updated.count, 1)
XCTAssertEqual(updated[0].name, "Fresh Station")
XCTAssertEqual(updated[0].prices[.e10], 132.9)
XCTAssertEqual(updated[0].station.name, "Fresh Station")
XCTAssertEqual(updated[0].station.prices[.e10], 132.9)
XCTAssertEqual(updated[0].fuel, .e10, "fuel scoping survives refresh")
}
func testRefreshedFavouritesKeepUnmatchedSnapshot() {
let fav = FuelStation(id: "s1", name: "Cached", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 140.0], priceUpdated: nil)
let fav = FavouriteEntry(station: FuelStation(id: "s1", name: "Cached", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 140.0], priceUpdated: nil), fuel: .diesel)
let updated = FuelStore.refreshedFavourites([fav], from: [])
XCTAssertEqual(updated[0].name, "Cached", "unmatched favourite keeps its snapshot")
XCTAssertEqual(updated[0].prices[.e10], 140.0)
XCTAssertEqual(updated[0].station.name, "Cached", "unmatched favourite keeps its snapshot")
XCTAssertEqual(updated[0].station.prices[.e10], 140.0)
XCTAssertEqual(updated[0].fuel, .diesel, "fuel scoping survives unmatched refresh")
}
func testFavouriteEntryIDIsFuelScoped() {
let station = FuelStation(id: "s1", name: "X", brand: "X", address: "", postcode: "", lat: 0, lng: 0, prices: [.e10: 140.0, .diesel: 150.0], priceUpdated: nil)
let unleaded = FavouriteEntry(station: station, fuel: .e10)
let diesel = FavouriteEntry(station: station, fuel: .diesel)
XCTAssertNotEqual(unleaded.id, diesel.id, "same station favourited for two fuels is two distinct favourites")
XCTAssertTrue(unleaded.id.hasSuffix("|s1"))
XCTAssertTrue(diesel.id.hasPrefix("diesel|"))
}
}