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>
This commit is contained in:
@@ -49,33 +49,35 @@ final class ItineraryConstraintsTests: XCTestCase {
|
||||
}
|
||||
|
||||
func test_travel_mustBeAfterDepartureGames() {
|
||||
// Given: Chicago game on Day 1 at sortOrder 100
|
||||
// Given: Chicago game on Day 1
|
||||
// Visual boundary is 0: sortOrder < 0 = before games, sortOrder >= 0 = after games
|
||||
let constraints = makeConstraints(
|
||||
tripDays: 3,
|
||||
games: [makeGameItem(city: "Chicago", day: 1, sortOrder: 100)]
|
||||
games: [makeGameItem(city: "Chicago", day: 1)]
|
||||
)
|
||||
let travel = makeTravelItem(from: "Chicago", to: "Detroit", day: 1, sortOrder: 50)
|
||||
let travel = makeTravelItem(from: "Chicago", to: "Detroit", day: 1, sortOrder: -1)
|
||||
|
||||
// When/Then: Travel before game is invalid
|
||||
XCTAssertFalse(constraints.isValidPosition(for: travel, day: 1, sortOrder: 50))
|
||||
// When/Then: Travel before game (negative sortOrder) is invalid on departure day
|
||||
XCTAssertFalse(constraints.isValidPosition(for: travel, day: 1, sortOrder: -1))
|
||||
|
||||
// Travel after game is valid
|
||||
XCTAssertTrue(constraints.isValidPosition(for: travel, day: 1, sortOrder: 150))
|
||||
// Travel after game (non-negative sortOrder) is valid
|
||||
XCTAssertTrue(constraints.isValidPosition(for: travel, day: 1, sortOrder: 1))
|
||||
}
|
||||
|
||||
func test_travel_mustBeBeforeArrivalGames() {
|
||||
// Given: Detroit game on Day 3 at sortOrder 100
|
||||
// Given: Detroit game on Day 3
|
||||
// Visual boundary is 0: sortOrder < 0 = before games, sortOrder >= 0 = after games
|
||||
let constraints = makeConstraints(
|
||||
tripDays: 3,
|
||||
games: [makeGameItem(city: "Detroit", day: 3, sortOrder: 100)]
|
||||
games: [makeGameItem(city: "Detroit", day: 3)]
|
||||
)
|
||||
let travel = makeTravelItem(from: "Chicago", to: "Detroit", day: 3, sortOrder: 150)
|
||||
let travel = makeTravelItem(from: "Chicago", to: "Detroit", day: 3, sortOrder: 1)
|
||||
|
||||
// When/Then: Travel after arrival game is invalid
|
||||
XCTAssertFalse(constraints.isValidPosition(for: travel, day: 3, sortOrder: 150))
|
||||
// When/Then: Travel after arrival game (non-negative sortOrder) is invalid on arrival day
|
||||
XCTAssertFalse(constraints.isValidPosition(for: travel, day: 3, sortOrder: 1))
|
||||
|
||||
// Travel before game is valid
|
||||
XCTAssertTrue(constraints.isValidPosition(for: travel, day: 3, sortOrder: 50))
|
||||
// Travel before game (negative sortOrder) is valid
|
||||
XCTAssertTrue(constraints.isValidPosition(for: travel, day: 3, sortOrder: -1))
|
||||
}
|
||||
|
||||
func test_travel_canBeAnywhereOnRestDays() {
|
||||
@@ -217,13 +219,12 @@ final class ItineraryConstraintsTests: XCTestCase {
|
||||
return ItineraryConstraints(tripDayCount: tripDays, items: games)
|
||||
}
|
||||
|
||||
private func makeGameItem(city: String, day: Int, sortOrder: Double = 100) -> ItineraryItem {
|
||||
// For tests, we use gameId to encode the city
|
||||
private func makeGameItem(city: String, day: Int, sortOrder: Double = 0) -> ItineraryItem {
|
||||
return ItineraryItem(
|
||||
tripId: testTripId,
|
||||
day: day,
|
||||
sortOrder: sortOrder,
|
||||
kind: .game(gameId: "game-\(city)-\(UUID().uuidString.prefix(4))")
|
||||
kind: .game(gameId: "game-\(city)-\(UUID().uuidString.prefix(4))", city: city)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user