- Enable zoom/pan on progress map with reset button - Add visit count badges to stadium chips - Create GamesHistoryView with year grouping and sport filters - Create StadiumVisitHistoryView for viewing all visits to a stadium - Add VisitListCard and GamesHistoryRow components - Add "See All" navigation from Recent Visits to Games History - Add tests for map interactions, visit lists, and games history Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
112 lines
3.7 KiB
Swift
112 lines
3.7 KiB
Swift
import XCTest
|
|
import SwiftData
|
|
@testable import SportsTime
|
|
|
|
@MainActor
|
|
final class VisitListTests: XCTestCase {
|
|
var modelContainer: ModelContainer!
|
|
var modelContext: ModelContext!
|
|
|
|
override func setUp() async throws {
|
|
let config = ModelConfiguration(isStoredInMemoryOnly: true)
|
|
modelContainer = try ModelContainer(
|
|
for: StadiumVisit.self, Achievement.self, UserPreferences.self,
|
|
configurations: config
|
|
)
|
|
modelContext = modelContainer.mainContext
|
|
}
|
|
|
|
override func tearDown() async throws {
|
|
modelContainer = nil
|
|
modelContext = nil
|
|
}
|
|
|
|
func test_VisitsForStadium_ReturnsAllVisitsSortedByDate() async throws {
|
|
// Given: Multiple visits to the same stadium
|
|
let stadiumId = "yankee-stadium"
|
|
|
|
let visit1 = StadiumVisit(
|
|
stadiumId: stadiumId,
|
|
stadiumNameAtVisit: "Yankee Stadium",
|
|
visitDate: Date().addingTimeInterval(-86400 * 30), // 30 days ago
|
|
visitType: .game,
|
|
dataSource: .manual
|
|
)
|
|
|
|
let visit2 = StadiumVisit(
|
|
stadiumId: stadiumId,
|
|
stadiumNameAtVisit: "Yankee Stadium",
|
|
visitDate: Date().addingTimeInterval(-86400 * 7), // 7 days ago
|
|
visitType: .game,
|
|
dataSource: .manual
|
|
)
|
|
|
|
let visit3 = StadiumVisit(
|
|
stadiumId: stadiumId,
|
|
stadiumNameAtVisit: "Yankee Stadium",
|
|
visitDate: Date(), // today
|
|
visitType: .tour,
|
|
dataSource: .manual
|
|
)
|
|
|
|
modelContext.insert(visit1)
|
|
modelContext.insert(visit2)
|
|
modelContext.insert(visit3)
|
|
try modelContext.save()
|
|
|
|
// When: Fetching visits for that stadium
|
|
let descriptor = FetchDescriptor<StadiumVisit>(
|
|
predicate: #Predicate { $0.stadiumId == stadiumId },
|
|
sortBy: [SortDescriptor(\.visitDate, order: .reverse)]
|
|
)
|
|
let visits = try modelContext.fetch(descriptor)
|
|
|
|
// Then: All visits returned, most recent first
|
|
XCTAssertEqual(visits.count, 3, "Should return all 3 visits")
|
|
XCTAssertEqual(visits[0].visitType, .tour, "Most recent visit should be first")
|
|
XCTAssertEqual(visits[2].visitType, .game, "Oldest visit should be last")
|
|
}
|
|
|
|
func test_VisitCountForStadium_ReturnsCorrectCount() async throws {
|
|
// Given: 3 visits to one stadium, 1 to another
|
|
let stadium1 = "yankee-stadium"
|
|
let stadium2 = "fenway-park"
|
|
|
|
for i in 0..<3 {
|
|
let visit = StadiumVisit(
|
|
stadiumId: stadium1,
|
|
stadiumNameAtVisit: "Yankee Stadium",
|
|
visitDate: Date().addingTimeInterval(Double(-i * 86400)),
|
|
visitType: .game,
|
|
dataSource: .manual
|
|
)
|
|
modelContext.insert(visit)
|
|
}
|
|
|
|
let fenwayVisit = StadiumVisit(
|
|
stadiumId: stadium2,
|
|
stadiumNameAtVisit: "Fenway Park",
|
|
visitDate: Date(),
|
|
visitType: .game,
|
|
dataSource: .manual
|
|
)
|
|
modelContext.insert(fenwayVisit)
|
|
try modelContext.save()
|
|
|
|
// When: Counting visits per stadium
|
|
let yankeeDescriptor = FetchDescriptor<StadiumVisit>(
|
|
predicate: #Predicate { $0.stadiumId == stadium1 }
|
|
)
|
|
let fenwayDescriptor = FetchDescriptor<StadiumVisit>(
|
|
predicate: #Predicate { $0.stadiumId == stadium2 }
|
|
)
|
|
|
|
let yankeeCount = try modelContext.fetchCount(yankeeDescriptor)
|
|
let fenwayCount = try modelContext.fetchCount(fenwayDescriptor)
|
|
|
|
// Then: Correct counts
|
|
XCTAssertEqual(yankeeCount, 3)
|
|
XCTAssertEqual(fenwayCount, 1)
|
|
}
|
|
}
|