feat(progress): add progress tracking enhancements
- 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>
This commit is contained in:
111
SportsTimeTests/Features/Progress/VisitListTests.swift
Normal file
111
SportsTimeTests/Features/Progress/VisitListTests.swift
Normal file
@@ -0,0 +1,111 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user