Files
Sportstime/SportsTimeTests/Features/Trip/ItineraryTestHelpers.swift
Trey t e72da7c5a7 fix(itinerary): add city to game items for proper constraint validation
Travel constraint validation was not working because ItineraryConstraints
had no game items to validate against - games came from RichGame objects
but were never converted to ItineraryItem for constraint checking.

Changes:
- Add city parameter to ItemKind.game enum case
- Create game ItineraryItems from RichGame data in buildItineraryData()
- Update isValidTravelPosition to compare against actual game sortOrders
- Fix tests to use appropriate game sortOrder conventions

Now travel is properly constrained to appear before arrival city games
and after departure city games.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:46:40 -06:00

126 lines
3.7 KiB
Swift

//
// ItineraryTestHelpers.swift
// SportsTimeTests
//
// Shared test fixtures and helpers for Itinerary tests.
//
import Foundation
@testable import SportsTime
/// Shared test fixtures for itinerary tests
enum ItineraryTestHelpers {
static let testTripId = UUID()
static let testDate = Date()
// MARK: - Day Helpers
static func makeDays(count: Int, from baseDate: Date = testDate) -> [ItineraryDayData] {
return (0..<count).map { i in
ItineraryDayData(
id: i + 1,
dayNumber: i + 1,
date: Calendar.current.date(byAdding: .day, value: i, to: baseDate)!,
games: [],
items: [],
travelBefore: nil
)
}
}
static func dayAfter(_ date: Date) -> Date {
Calendar.current.date(byAdding: .day, value: 1, to: date)!
}
// MARK: - Travel Helpers
static func makeTravelSegment(from: String, to: String) -> TravelSegment {
TravelSegment(
fromLocation: LocationInput(name: from, coordinate: nil),
toLocation: LocationInput(name: to, coordinate: nil),
travelMode: .drive,
distanceMeters: 500_000,
durationSeconds: 18000
)
}
static func makeTravelItem(from: String, to: String, day: Int, sortOrder: Double) -> ItineraryItem {
ItineraryItem(
tripId: testTripId,
day: day,
sortOrder: sortOrder,
kind: .travel(TravelInfo(fromCity: from, toCity: to))
)
}
// MARK: - Game Helpers
static func makeRichGame(city: String, hour: Int, baseDate: Date = testDate) -> RichGame {
var dateComponents = Calendar.current.dateComponents([.year, .month, .day], from: baseDate)
dateComponents.hour = hour
let gameTime = Calendar.current.date(from: dateComponents)!
let game = Game(
id: "game-\(city)-\(UUID().uuidString.prefix(4))",
homeTeamId: "team-\(city)",
awayTeamId: "team-visitor",
stadiumId: "stadium-\(city)",
dateTime: gameTime,
sport: .mlb,
season: "2026",
isPlayoff: false
)
let stadium = Stadium(
id: "stadium-\(city)",
name: "\(city) Stadium",
city: city,
state: "XX",
latitude: 40.0,
longitude: -80.0,
capacity: 40000,
sport: .mlb
)
let homeTeam = Team(
id: "team-\(city)",
name: "\(city) Team",
abbreviation: String(city.prefix(3)).uppercased(),
sport: .mlb,
city: city,
stadiumId: "stadium-\(city)"
)
let awayTeam = Team(
id: "team-visitor",
name: "Visitor Team",
abbreviation: "VIS",
sport: .mlb,
city: "Visiting",
stadiumId: "stadium-visitor"
)
return RichGame(game: game, homeTeam: homeTeam, awayTeam: awayTeam, stadium: stadium)
}
static func makeGameItem(city: String, day: Int, sortOrder: Double = 100) -> ItineraryItem {
ItineraryItem(
tripId: testTripId,
day: day,
sortOrder: sortOrder,
kind: .game(gameId: "game-\(city)-\(UUID().uuidString.prefix(4))", city: city)
)
}
// MARK: - Custom Item Helpers
static func makeCustomItem(day: Int, sortOrder: Double, title: String) -> ItineraryItem {
ItineraryItem(
tripId: testTripId,
day: day,
sortOrder: sortOrder,
kind: .custom(CustomInfo(title: title, icon: "🍽️"))
)
}
}