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>
126 lines
3.7 KiB
Swift
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: "🍽️"))
|
|
)
|
|
}
|
|
}
|