// // VisitPhotoServiceTests.swift // SportsTimeTests // // TDD specification tests for VisitPhotoService types. // import Testing import Foundation @testable import SportsTime // MARK: - PhotoServiceError Tests @Suite("PhotoServiceError") struct PhotoServiceErrorTests { // MARK: - Specification Tests: errorDescription /// - Expected Behavior: notSignedIn explains iCloud requirement @Test("errorDescription: notSignedIn mentions iCloud") func errorDescription_notSignedIn() { let error = PhotoServiceError.notSignedIn #expect(error.errorDescription != nil) #expect(error.errorDescription!.lowercased().contains("icloud") || error.errorDescription!.lowercased().contains("sign in")) } /// - Expected Behavior: uploadFailed includes the message @Test("errorDescription: uploadFailed includes message") func errorDescription_uploadFailed() { let error = PhotoServiceError.uploadFailed("Network timeout") #expect(error.errorDescription != nil) #expect(error.errorDescription!.contains("Network timeout") || error.errorDescription!.lowercased().contains("upload")) } /// - Expected Behavior: downloadFailed includes the message @Test("errorDescription: downloadFailed includes message") func errorDescription_downloadFailed() { let error = PhotoServiceError.downloadFailed("Connection lost") #expect(error.errorDescription != nil) #expect(error.errorDescription!.contains("Connection lost") || error.errorDescription!.lowercased().contains("download")) } /// - Expected Behavior: thumbnailGenerationFailed explains the issue @Test("errorDescription: thumbnailGenerationFailed mentions thumbnail") func errorDescription_thumbnailGenerationFailed() { let error = PhotoServiceError.thumbnailGenerationFailed #expect(error.errorDescription != nil) #expect(error.errorDescription!.lowercased().contains("thumbnail")) } /// - Expected Behavior: invalidImage explains invalid data @Test("errorDescription: invalidImage mentions invalid") func errorDescription_invalidImage() { let error = PhotoServiceError.invalidImage #expect(error.errorDescription != nil) #expect(error.errorDescription!.lowercased().contains("invalid")) } /// - Expected Behavior: assetNotFound explains missing photo @Test("errorDescription: assetNotFound mentions not found") func errorDescription_assetNotFound() { let error = PhotoServiceError.assetNotFound #expect(error.errorDescription != nil) #expect(error.errorDescription!.lowercased().contains("not found") || error.errorDescription!.lowercased().contains("photo")) } /// - Expected Behavior: quotaExceeded explains storage limit @Test("errorDescription: quotaExceeded mentions quota") func errorDescription_quotaExceeded() { let error = PhotoServiceError.quotaExceeded #expect(error.errorDescription != nil) #expect(error.errorDescription!.lowercased().contains("quota") || error.errorDescription!.lowercased().contains("storage")) } // MARK: - Invariant Tests /// - Invariant: All errors have non-empty descriptions @Test("Invariant: all errors have descriptions") func invariant_allHaveDescriptions() { let errors: [PhotoServiceError] = [ .notSignedIn, .uploadFailed("test"), .downloadFailed("test"), .thumbnailGenerationFailed, .invalidImage, .assetNotFound, .quotaExceeded ] for error in errors { #expect(error.errorDescription != nil) #expect(!error.errorDescription!.isEmpty) } } /// - Invariant: uploadFailed and downloadFailed preserve their messages @Test("Invariant: parameterized errors preserve message") func invariant_parameterizedErrorsPreserveMessage() { let testMessage = "Test error message 12345" let uploadError = PhotoServiceError.uploadFailed(testMessage) let downloadError = PhotoServiceError.downloadFailed(testMessage) // The message should appear somewhere in the description #expect(uploadError.errorDescription!.contains(testMessage)) #expect(downloadError.errorDescription!.contains(testMessage)) } }