Files
Sportstime/SportsTimeTests/Services/PollServiceTests.swift
Trey t 8162b4a029 refactor(tests): TDD rewrite of all unit tests with spec documentation
Complete rewrite of unit test suite using TDD methodology:

Planning Engine Tests:
- GameDAGRouterTests: Beam search, anchor games, transitions
- ItineraryBuilderTests: Stop connection, validators, EV enrichment
- RouteFiltersTests: Region, time window, scoring filters
- ScenarioA/B/C/D PlannerTests: All planning scenarios
- TravelEstimatorTests: Distance, duration, travel days
- TripPlanningEngineTests: Orchestration, caching, preferences

Domain Model Tests:
- AchievementDefinitionsTests, AnySportTests, DivisionTests
- GameTests, ProgressTests, RegionTests, StadiumTests
- TeamTests, TravelSegmentTests, TripTests, TripPollTests
- TripPreferencesTests, TripStopTests, SportTests

Service Tests:
- FreeScoreAPITests, RouteDescriptionGeneratorTests
- SuggestedTripsGeneratorTests

Export Tests:
- ShareableContentTests (card types, themes, dimensions)

Bug fixes discovered through TDD:
- ShareCardDimensions: mapSnapshotSize exceeded available width (960x480)
- ScenarioBPlanner: Added anchor game validation filter

All tests include:
- Specification tests (expected behavior)
- Invariant tests (properties that must always hold)
- Edge case tests (boundary conditions)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:07:41 -06:00

115 lines
4.3 KiB
Swift

//
// PollServiceTests.swift
// SportsTimeTests
//
// TDD specification tests for PollService types.
//
import Testing
import Foundation
@testable import SportsTime
// MARK: - PollError Tests
@Suite("PollError")
struct PollErrorTests {
// MARK: - Specification Tests: errorDescription
/// - Expected Behavior: notSignedIn explains iCloud requirement
@Test("errorDescription: notSignedIn mentions iCloud")
func errorDescription_notSignedIn() {
let error = PollError.notSignedIn
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("icloud") || error.errorDescription!.lowercased().contains("sign in"))
}
/// - Expected Behavior: pollNotFound explains poll doesn't exist
@Test("errorDescription: pollNotFound mentions not found")
func errorDescription_pollNotFound() {
let error = PollError.pollNotFound
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("not found") || error.errorDescription!.lowercased().contains("deleted"))
}
/// - Expected Behavior: alreadyVoted explains duplicate vote
@Test("errorDescription: alreadyVoted mentions already voted")
func errorDescription_alreadyVoted() {
let error = PollError.alreadyVoted
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("already voted"))
}
/// - Expected Behavior: notPollOwner explains ownership requirement
@Test("errorDescription: notPollOwner mentions owner")
func errorDescription_notPollOwner() {
let error = PollError.notPollOwner
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("owner"))
}
/// - Expected Behavior: networkUnavailable explains connection issue
@Test("errorDescription: networkUnavailable mentions connection")
func errorDescription_networkUnavailable() {
let error = PollError.networkUnavailable
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("connect") || error.errorDescription!.lowercased().contains("internet"))
}
/// - Expected Behavior: encodingError explains save failure
@Test("errorDescription: encodingError mentions save")
func errorDescription_encodingError() {
let error = PollError.encodingError
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.lowercased().contains("save") || error.errorDescription!.lowercased().contains("failed"))
}
/// - Expected Behavior: unknown includes underlying error message
@Test("errorDescription: unknown includes underlying error")
func errorDescription_unknown() {
let underlyingError = NSError(domain: "TestDomain", code: 123, userInfo: [NSLocalizedDescriptionKey: "Test underlying error"])
let error = PollError.unknown(underlyingError)
#expect(error.errorDescription != nil)
#expect(error.errorDescription!.contains("Test underlying error") || error.errorDescription!.lowercased().contains("error"))
}
// MARK: - Invariant Tests
/// - Invariant: All errors have non-empty descriptions
@Test("Invariant: all errors have descriptions")
func invariant_allHaveDescriptions() {
let errors: [PollError] = [
.notSignedIn,
.pollNotFound,
.alreadyVoted,
.notPollOwner,
.networkUnavailable,
.encodingError,
.unknown(NSError(domain: "", code: 0))
]
for error in errors {
#expect(error.errorDescription != nil)
#expect(!error.errorDescription!.isEmpty)
}
}
/// - Invariant: All non-unknown errors have distinct descriptions
@Test("Invariant: non-unknown errors have distinct descriptions")
func invariant_distinctDescriptions() {
let errors: [PollError] = [
.notSignedIn,
.pollNotFound,
.alreadyVoted,
.notPollOwner,
.networkUnavailable,
.encodingError
]
let descriptions = errors.compactMap { $0.errorDescription }
let uniqueDescriptions = Set(descriptions)
#expect(descriptions.count == uniqueDescriptions.count)
}
}