diff --git a/Sources/TMDb/Certifications/CertificationService.swift b/Sources/TMDb/Certifications/CertificationService.swift index 23293cc7..310de3f6 100644 --- a/Sources/TMDb/Certifications/CertificationService.swift +++ b/Sources/TMDb/Certifications/CertificationService.swift @@ -26,6 +26,8 @@ public final class CertificationService { /// /// [TMDb API - Movie Certifications](https://developer.themoviedb.org/reference/certification-movie-list) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A dictionary of movie certifications. /// public func movieCertifications() async throws -> [String: [Certification]] { @@ -33,7 +35,7 @@ public final class CertificationService { do { certifications = try await apiClient.get(endpoint: CertificationsEndpoint.movie) } catch let error { - throw error + throw TMDbError(error: error) } return certifications.certifications @@ -44,6 +46,8 @@ public final class CertificationService { /// /// [TMDb API - TV show Certifications](https://developer.themoviedb.org/reference/certifications-tv-list) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A dictionary of TV show certifications. /// public func tvShowCertifications() async throws -> [String: [Certification]] { @@ -51,7 +55,7 @@ public final class CertificationService { do { certifications = try await apiClient.get(endpoint: CertificationsEndpoint.tvShow) } catch let error { - throw error + throw TMDbError(error: error) } return certifications.certifications diff --git a/Sources/TMDb/Company/CompanyService.swift b/Sources/TMDb/Company/CompanyService.swift index 0e6620ea..a2a0c8d9 100644 --- a/Sources/TMDb/Company/CompanyService.swift +++ b/Sources/TMDb/Company/CompanyService.swift @@ -29,6 +29,8 @@ public final class CompanyService { /// - Parameters: /// - id: The identifier of the company. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Matching company. /// public func details(forCompany id: Company.ID) async throws -> Company { @@ -36,7 +38,7 @@ public final class CompanyService { do { company = try await apiClient.get(endpoint: CompanyEndpoint.details(companyID: id)) } catch let error { - throw error + throw TMDbError(error: error) } return company diff --git a/Sources/TMDb/Configuration/ConfigurationService.swift b/Sources/TMDb/Configuration/ConfigurationService.swift index 4254c9cd..9f61bba2 100644 --- a/Sources/TMDb/Configuration/ConfigurationService.swift +++ b/Sources/TMDb/Configuration/ConfigurationService.swift @@ -27,6 +27,8 @@ public final class ConfigurationService { /// /// [TMDb API - Configuration: API Configuration](https://developers.themoviedb.org/3/configuration/get-api-configuration) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The API configuration. /// public func apiConfiguration() async throws -> APIConfiguration { @@ -34,7 +36,7 @@ public final class ConfigurationService { do { apiConfiguration = try await apiClient.get(endpoint: ConfigurationEndpoint.api) } catch let error { - throw error + throw TMDbError(error: error) } return apiConfiguration @@ -45,6 +47,8 @@ public final class ConfigurationService { /// /// [TMDb API - Configuration: Countries](https://developers.themoviedb.org/3/configuration/get-countries) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Countries used throughout TMDb, /// public func countries() async throws -> [Country] { @@ -52,7 +56,7 @@ public final class ConfigurationService { do { countries = try await apiClient.get(endpoint: ConfigurationEndpoint.countries) } catch let error { - throw error + throw TMDbError(error: error) } return countries @@ -63,6 +67,8 @@ public final class ConfigurationService { /// /// [TMDb API - Configuration: Jobs](https://developers.themoviedb.org/3/configuration/get-jobs) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Jobs and departments used on TMDb. /// public func jobsByDepartment() async throws -> [Department] { @@ -70,7 +76,7 @@ public final class ConfigurationService { do { departments = try await apiClient.get(endpoint: ConfigurationEndpoint.jobs) } catch let error { - throw error + throw TMDbError(error: error) } return departments @@ -81,14 +87,16 @@ public final class ConfigurationService { /// /// [TMDb API - Configuration: Languages](https://developers.themoviedb.org/3/configuration/get-languages) /// - /// - Returns: Languages used throughout TMDb. + /// - Throws: TMDb data error ``TMDbError``. + /// + /// - Returns: Languages used throughout TMDb. /// public func languages() async throws -> [Language] { let languages: [Language] do { languages = try await apiClient.get(endpoint: ConfigurationEndpoint.languages) } catch let error { - throw error + throw TMDbError(error: error) } return languages diff --git a/Sources/TMDb/Discover/DiscoverService.swift b/Sources/TMDb/Discover/DiscoverService.swift index 31a536ea..b27cf15c 100644 --- a/Sources/TMDb/Discover/DiscoverService.swift +++ b/Sources/TMDb/Discover/DiscoverService.swift @@ -33,6 +33,8 @@ public final class DiscoverService { /// - people: A list of Person identifiers which to return only movies they have appeared in. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Matching movies as a pageable list. /// public func movies(sortedBy: MovieSort? = nil, withPeople people: [Person.ID]? = nil, @@ -43,7 +45,7 @@ public final class DiscoverService { endpoint: DiscoverEndpoint.movies(sortedBy: sortedBy, people: people, page: page) ) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -60,6 +62,8 @@ public final class DiscoverService { /// - sortedBy: How results should be sorted. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Matching TV shows as a pageable list. /// public func tvShows(sortedBy: TVShowSort? = nil, page: Int? = nil) async throws -> TVShowPageableList { @@ -67,7 +71,7 @@ public final class DiscoverService { do { tvShowList = try await apiClient.get(endpoint: DiscoverEndpoint.tvShows(sortedBy: sortedBy, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList diff --git a/Sources/TMDb/Genres/GenreService.swift b/Sources/TMDb/Genres/GenreService.swift index 55527da1..206479f6 100644 --- a/Sources/TMDb/Genres/GenreService.swift +++ b/Sources/TMDb/Genres/GenreService.swift @@ -26,6 +26,8 @@ public final class GenreService { /// /// [TMDb API - Genres: Movies](https://developers.themoviedb.org/3/genres/get-movie-list) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A list of genres. /// public func movieGenres() async throws -> [Genre] { @@ -33,7 +35,7 @@ public final class GenreService { do { genreList = try await apiClient.get(endpoint: GenresEndpoint.movie) } catch let error { - throw error + throw TMDbError(error: error) } return genreList.genres @@ -44,6 +46,8 @@ public final class GenreService { /// /// [TMDb API - Genres: Movies](https://developers.themoviedb.org/3/genres/get-tv-list) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A list of genres. /// public func tvShowGenres() async throws -> [Genre] { @@ -51,7 +55,7 @@ public final class GenreService { do { genreList = try await apiClient.get(endpoint: GenresEndpoint.tvShow) } catch let error { - throw error + throw TMDbError(error: error) } return genreList.genres diff --git a/Sources/TMDb/Models/Movie.swift b/Sources/TMDb/Models/Movie.swift index 1d1fbb1b..a074b745 100644 --- a/Sources/TMDb/Models/Movie.swift +++ b/Sources/TMDb/Models/Movie.swift @@ -229,22 +229,6 @@ public struct Movie: Identifiable, Codable, Equatable, Hashable { } -extension Movie: Comparable { - - public static func < (lhs: Movie, rhs: Movie) -> Bool { - guard let lhsDate = lhs.releaseDate else { - return false - } - - guard let rhsDate = rhs.releaseDate else { - return true - } - - return lhsDate > rhsDate - } - -} - extension Movie { private enum CodingKeys: String, CodingKey { diff --git a/Sources/TMDb/Models/TMDbError+TMDbAPIError.swift b/Sources/TMDb/Models/TMDbError+TMDbAPIError.swift new file mode 100644 index 00000000..e15508eb --- /dev/null +++ b/Sources/TMDb/Models/TMDbError+TMDbAPIError.swift @@ -0,0 +1,23 @@ +import Foundation + +extension TMDbError { + + init(error: Error) { + guard let apiError = error as? TMDbAPIError else { + self = .unknown + return + } + + switch apiError { + case .notFound: + self = .notFound + + case .network(let error): + self = .network(error) + + default: + self = .unknown + } + } + +} diff --git a/Sources/TMDb/Models/TMDbError.swift b/Sources/TMDb/Models/TMDbError.swift index 9a7ae59c..a141c32a 100644 --- a/Sources/TMDb/Models/TMDbError.swift +++ b/Sources/TMDb/Models/TMDbError.swift @@ -1,195 +1,47 @@ import Foundation -/// -/// A model representing a TMDb error. -/// -public enum TMDbError: Error { +public enum TMDbError: Equatable, LocalizedError { - /// - /// Network error. - /// - case network(Error) - - /// - /// Bad request. - /// - case badRequest(String?) - - /// - /// Unauthorised. - /// - case unauthorised(String?) - - /// - /// Forbidden. - /// - case forbidden(String?) - - /// - /// Not found. - /// - case notFound(String?) - - /// - /// Method not allowed. - /// - case methodNotAllowed(String?) + /// An error indicating the resource could not be found. + case notFound - /// - /// Not acceptable. - /// - case notAcceptable(String?) - - /// - /// Unprocessable content. - /// - case unprocessableContent(String?) - - /// - /// Too many requests. - /// - case tooManyRequests(String?) - - /// - /// Internal server error. - /// - case internalServerError(String?) - - /// - /// Not implemented. - /// - case notImplemented(String?) + /// An error indicating there was a network problem. + case network(Error) - /// - /// Bad gateway. - /// - case badGateway(String?) + /// An unknown error. + case unknown - /// - /// Service unavailable. - /// - case serviceUnavailable(String?) + public static func == (lhs: TMDbError, rhs: TMDbError) -> Bool { + switch (lhs, rhs) { + case (.notFound, .notFound): + return true - /// - /// Gateway timeout. - /// - case gatewayTimeout(String?) + case (.network, .network): + return true - /// - /// Data decode error. - /// - case decode(Error) + case (.unknown, .unknown): + return true - /// - /// Unknown error. - /// - case unknown + default: + return false + } + } } -extension TMDbError: LocalizedError { +extension TMDbError { + /// A localized message describing what error occurred. public var errorDescription: String? { switch self { - case .network(let error): - return error.localizedDescription - - case .badRequest: - return NSLocalizedString("BAD_REQUEST", bundle: .module, comment: "Bad request") - - case .unauthorised: - return NSLocalizedString("UNAUTHORISED", bundle: .module, comment: "Unauthorised") - - case .forbidden: - return NSLocalizedString("FORBIDDEN", bundle: .module, comment: "Forbidden") - case .notFound: - return NSLocalizedString("NOT_FOUND", bundle: .module, comment: "Not found") - - case .methodNotAllowed: - return NSLocalizedString("METHOD_NOT_ALLOWED", bundle: .module, comment: "Method not allowed") - - case .notAcceptable: - return NSLocalizedString("NOT_ACCEPTABLE", bundle: .module, comment: "Not acceptable") - - case .unprocessableContent: - return NSLocalizedString("UNPROCESSABLE_CONTENT", bundle: .module, comment: "Unprocessable content") - - case .tooManyRequests: - return NSLocalizedString("TOO_MANY_REQUESTS", bundle: .module, comment: "Too many requests") - - case .internalServerError: - return NSLocalizedString("INTERNAL_SERVER_ERROR", bundle: .module, comment: "Internal server error") - - case .notImplemented: - return NSLocalizedString("NOT_IMPLEMENTED", bundle: .module, comment: "Not implemented") - - case .badGateway: - return NSLocalizedString("BAD_GATEWAY", bundle: .module, comment: "Bad gateway") - - case .serviceUnavailable: - return NSLocalizedString("SERVICE_UNAVAILABLE", bundle: .module, comment: "Service unavailable") - - case .gatewayTimeout: - return NSLocalizedString("GATEWAY_TIMEOUT", bundle: .module, comment: "Gatewat timeout") - - case .decode(let error): - return error.localizedDescription - - case .unknown: - return NSLocalizedString("UNKNOWN_ERROR", bundle: .module, comment: "Unknown error") - } - } - - public var failureReason: String? { - switch self { - case .network(let error): - return (error as NSError).localizedFailureReason - - case .badRequest(let statusMessage): - return statusMessage - - case .unauthorised(let statusMessage): - return statusMessage - - case .forbidden(let statusMessage): - return statusMessage - - case .notFound(let statusMessage): - return statusMessage - - case .methodNotAllowed(let statusMessage): - return statusMessage - - case .notAcceptable(let statusMessage): - return statusMessage - - case .unprocessableContent(let statusMessage): - return statusMessage - - case .tooManyRequests(let statusMessage): - return statusMessage - - case .internalServerError(let statusMessage): - return statusMessage - - case .notImplemented(let statusMessage): - return statusMessage - - case .badGateway(let statusMessage): - return statusMessage - - case .serviceUnavailable(let statusMessage): - return statusMessage - - case .gatewayTimeout(let statusMessage): - return statusMessage + return "Not found" - case .decode(let error): - return (error as NSError).localizedFailureReason + case .network: + return "Network error" case .unknown: - return nil + return "Unknown" } } diff --git a/Sources/TMDb/Models/TVShow.swift b/Sources/TMDb/Models/TVShow.swift index ed9c3ec5..d318ff39 100644 --- a/Sources/TMDb/Models/TVShow.swift +++ b/Sources/TMDb/Models/TVShow.swift @@ -236,22 +236,6 @@ public struct TVShow: Identifiable, Codable, Equatable, Hashable { } -extension TVShow: Comparable { - - public static func < (lhs: TVShow, rhs: TVShow) -> Bool { - guard let lhsDate = lhs.firstAirDate else { - return false - } - - guard let rhsDate = rhs.firstAirDate else { - return true - } - - return lhsDate > rhsDate - } - -} - extension TVShow { private enum CodingKeys: String, CodingKey { diff --git a/Sources/TMDb/Movies/MovieService.swift b/Sources/TMDb/Movies/MovieService.swift index d50bc2c5..77954a51 100644 --- a/Sources/TMDb/Movies/MovieService.swift +++ b/Sources/TMDb/Movies/MovieService.swift @@ -32,6 +32,8 @@ public final class MovieService { /// - Parameters: /// - id: The identifier of the movie. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching movie. /// public func details(forMovie id: Movie.ID) async throws -> Movie { @@ -39,7 +41,7 @@ public final class MovieService { do { movie = try await apiClient.get(endpoint: MoviesEndpoint.details(movieID: id)) } catch let error { - throw error + throw TMDbError(error: error) } return movie @@ -53,6 +55,8 @@ public final class MovieService { /// - Parameters: /// - movieID: The identifier of the movie. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Credits for the matching movie. /// public func credits(forMovie movieID: Movie.ID) async throws -> ShowCredits { @@ -60,7 +64,7 @@ public final class MovieService { do { credits = try await apiClient.get(endpoint: MoviesEndpoint.credits(movieID: movieID)) } catch let error { - throw error + throw TMDbError(error: error) } return credits @@ -77,6 +81,8 @@ public final class MovieService { /// - movieID: The identifier of the movie. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Reviews for the matching movie as a pageable list. /// public func reviews(forMovie movieID: Movie.ID, page: Int? = nil) async throws -> ReviewPageableList { @@ -84,7 +90,7 @@ public final class MovieService { do { reviewList = try await apiClient.get(endpoint: MoviesEndpoint.reviews(movieID: movieID, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return reviewList @@ -98,6 +104,8 @@ public final class MovieService { /// - Parameters: /// - movieID: The identifier of the movie. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Collection of images for the matching movie. /// public func images(forMovie movieID: Movie.ID) async throws -> ImageCollection { @@ -108,7 +116,7 @@ public final class MovieService { endpoint: MoviesEndpoint.images(movieID: movieID, languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return imageCollection @@ -122,6 +130,8 @@ public final class MovieService { /// - Parameters: /// - movieID: The identifier of the movie. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Collection of videos for the matching movie. /// public func videos(forMovie movieID: Movie.ID) async throws -> VideoCollection { @@ -132,7 +142,7 @@ public final class MovieService { endpoint: MoviesEndpoint.videos(movieID: movieID, languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return videoCollection @@ -149,6 +159,8 @@ public final class MovieService { /// - movieID: The identifier of the movie for get recommendations for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Recommended movies for the matching movie as a pageable list. /// public func recommendations(forMovie movieID: Movie.ID, page: Int? = nil) async throws -> MoviePageableList { @@ -156,7 +168,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.recommendations(movieID: movieID, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -175,6 +187,8 @@ public final class MovieService { /// - movieID: The identifier of the movie for get similar movies for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Similar movies for the matching movie as a pageable list. /// public func similar(toMovie movieID: Movie.ID, page: Int? = nil) async throws -> MoviePageableList { @@ -182,7 +196,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.similar(movieID: movieID, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -198,6 +212,8 @@ public final class MovieService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Now playing movies as a pageable list. /// public func nowPlaying(page: Int? = nil) async throws -> MoviePageableList { @@ -205,7 +221,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.nowPlaying(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -221,6 +237,8 @@ public final class MovieService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Current popular movies as a pageable list. /// public func popular(page: Int? = nil) async throws -> MoviePageableList { @@ -228,7 +246,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.popular(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -244,6 +262,8 @@ public final class MovieService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Current popular movies as a pageable list. /// public func topRated(page: Int? = nil) async throws -> MoviePageableList { @@ -251,7 +271,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.topRated(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -267,6 +287,8 @@ public final class MovieService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Current popular movies as a pageable list. /// public func upcoming(page: Int? = nil) async throws -> MoviePageableList { @@ -274,7 +296,7 @@ public final class MovieService { do { movieList = try await apiClient.get(endpoint: MoviesEndpoint.upcoming(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList diff --git a/Sources/TMDb/Networking/APIClient/TMDbAPIClient.swift b/Sources/TMDb/Networking/APIClient/TMDbAPIClient.swift index 0fc7c753..31c4f3dc 100644 --- a/Sources/TMDb/Networking/APIClient/TMDbAPIClient.swift +++ b/Sources/TMDb/Networking/APIClient/TMDbAPIClient.swift @@ -33,20 +33,20 @@ final class TMDbAPIClient: APIClient { do { response = try await httpClient.get(url: url, headers: headers) } catch { - throw TMDbError.network(error) + throw TMDbAPIError.network(error) } try await validate(response: response) guard let data = response.data else { - throw TMDbError.unknown + throw TMDbAPIError.unknown } let decodedResponse: Response do { decodedResponse = try await serialiser.decode(Response.self, from: data) } catch let error { - throw TMDbError.decode(error) + throw TMDbAPIError.decode(error) } return decodedResponse @@ -77,13 +77,13 @@ extension TMDbAPIClient { } guard let data = response.data else { - throw TMDbError(statusCode: statusCode, message: nil) + throw TMDbAPIError(statusCode: statusCode, message: nil) } let statusResponse = try? await serialiser.decode(TMDbStatusResponse.self, from: data) let message = statusResponse?.statusMessage - throw TMDbError(statusCode: statusCode, message: message) + throw TMDbAPIError(statusCode: statusCode, message: message) } } diff --git a/Sources/TMDb/Networking/APIClient/TMDbError+HTTPStatusCode.swift b/Sources/TMDb/Networking/APIClient/TMDbAPIError+HTTPStatusCode.swift similarity index 97% rename from Sources/TMDb/Networking/APIClient/TMDbError+HTTPStatusCode.swift rename to Sources/TMDb/Networking/APIClient/TMDbAPIError+HTTPStatusCode.swift index 737df46a..90bdab5b 100644 --- a/Sources/TMDb/Networking/APIClient/TMDbError+HTTPStatusCode.swift +++ b/Sources/TMDb/Networking/APIClient/TMDbAPIError+HTTPStatusCode.swift @@ -1,6 +1,6 @@ import Foundation -extension TMDbError { +extension TMDbAPIError { init(statusCode: Int, message: String?) { switch statusCode { diff --git a/Sources/TMDb/Networking/APIClient/TMDbAPIError.swift b/Sources/TMDb/Networking/APIClient/TMDbAPIError.swift new file mode 100644 index 00000000..bd7dc61a --- /dev/null +++ b/Sources/TMDb/Networking/APIClient/TMDbAPIError.swift @@ -0,0 +1,88 @@ +import Foundation + +/// +/// A model representing a TMDb API error. +/// +enum TMDbAPIError: Error { + + /// + /// Network error. + /// + case network(Error) + + /// + /// Bad request. + /// + case badRequest(String?) + + /// + /// Unauthorised. + /// + case unauthorised(String?) + + /// + /// Forbidden. + /// + case forbidden(String?) + + /// + /// Not found. + /// + case notFound(String?) + + /// + /// Method not allowed. + /// + case methodNotAllowed(String?) + + /// + /// Not acceptable. + /// + case notAcceptable(String?) + + /// + /// Unprocessable content. + /// + case unprocessableContent(String?) + + /// + /// Too many requests. + /// + case tooManyRequests(String?) + + /// + /// Internal server error. + /// + case internalServerError(String?) + + /// + /// Not implemented. + /// + case notImplemented(String?) + + /// + /// Bad gateway. + /// + case badGateway(String?) + + /// + /// Service unavailable. + /// + case serviceUnavailable(String?) + + /// + /// Gateway timeout. + /// + case gatewayTimeout(String?) + + /// + /// Data decode error. + /// + case decode(Error) + + /// + /// Unknown error. + /// + case unknown + +} diff --git a/Sources/TMDb/Models/TMDbStatusResponse.swift b/Sources/TMDb/Networking/APIClient/TMDbStatusResponse.swift similarity index 100% rename from Sources/TMDb/Models/TMDbStatusResponse.swift rename to Sources/TMDb/Networking/APIClient/TMDbStatusResponse.swift diff --git a/Sources/TMDb/People/PersonService.swift b/Sources/TMDb/People/PersonService.swift index f046262c..1aef61f9 100644 --- a/Sources/TMDb/People/PersonService.swift +++ b/Sources/TMDb/People/PersonService.swift @@ -31,6 +31,8 @@ public final class PersonService { /// - Parameters: /// - id: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person. /// public func details(forPerson id: Person.ID) async throws -> Person { @@ -38,7 +40,7 @@ public final class PersonService { do { person = try await apiClient.get(endpoint: PeopleEndpoint.details(personID: id)) } catch let error { - throw error + throw TMDbError(error: error) } return person @@ -52,6 +54,8 @@ public final class PersonService { /// - Parameters: /// - personID: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person's combined movie and TV show credits. /// public func combinedCredits(forPerson personID: Person.ID) async throws -> PersonCombinedCredits { @@ -59,7 +63,7 @@ public final class PersonService { do { credits = try await apiClient.get(endpoint: PeopleEndpoint.combinedCredits(personID: personID)) } catch let error { - throw error + throw TMDbError(error: error) } return credits @@ -73,6 +77,8 @@ public final class PersonService { /// - Parameters: /// - personID: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person's movie credits. /// public func movieCredits(forPerson personID: Person.ID) async throws -> PersonMovieCredits { @@ -80,7 +86,7 @@ public final class PersonService { do { credits = try await apiClient.get(endpoint: PeopleEndpoint.movieCredits(personID: personID)) } catch let error { - throw error + throw TMDbError(error: error) } return credits @@ -94,6 +100,8 @@ public final class PersonService { /// - Parameters: /// - personID: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person's TV show credits. /// public func tvShowCredits(forPerson personID: Person.ID) async throws -> PersonTVShowCredits { @@ -101,7 +109,7 @@ public final class PersonService { do { credits = try await apiClient.get(endpoint: PeopleEndpoint.tvShowCredits(personID: personID)) } catch let error { - throw error + throw TMDbError(error: error) } return credits @@ -115,6 +123,8 @@ public final class PersonService { /// - Parameters: /// - personID: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person's images. /// public func images(forPerson personID: Person.ID) async throws -> PersonImageCollection { @@ -122,7 +132,7 @@ public final class PersonService { do { imageCollection = try await apiClient.get(endpoint: PeopleEndpoint.images(personID: personID)) } catch let error { - throw error + throw TMDbError(error: error) } return imageCollection @@ -134,6 +144,8 @@ public final class PersonService { /// - Parameters: /// - personID: The identifier of the person. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching person's show credits. /// public func knownFor(forPerson personID: Person.ID) async throws -> [Show] { @@ -141,7 +153,7 @@ public final class PersonService { do { credits = try await apiClient.get(endpoint: PeopleEndpoint.combinedCredits(personID: personID)) } catch let error { - throw error + throw TMDbError(error: error) } let topShowsSubSequence = credits.allShows.lazy @@ -162,6 +174,8 @@ public final class PersonService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Current popular people as a pageable list. /// public func popular(page: Int? = nil) async throws -> PersonPageableList { @@ -169,7 +183,7 @@ public final class PersonService { do { personList = try await apiClient.get(endpoint: PeopleEndpoint.popular(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return personList diff --git a/Sources/TMDb/Search/SearchService.swift b/Sources/TMDb/Search/SearchService.swift index 9be768a5..2e57ead1 100644 --- a/Sources/TMDb/Search/SearchService.swift +++ b/Sources/TMDb/Search/SearchService.swift @@ -32,6 +32,8 @@ public final class SearchService { /// - query: A text query to search for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Movies, TV shows and people matching the query. /// public func searchAll(query: String, page: Int? = nil) async throws -> MediaPageableList { @@ -39,7 +41,7 @@ public final class SearchService { do { mediaList = try await apiClient.get(endpoint: SearchEndpoint.multi(query: query, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return mediaList @@ -57,6 +59,8 @@ public final class SearchService { /// - year: The year to filter results for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Movies matching the query. /// public func searchMovies(query: String, year: Int? = nil, page: Int? = nil) async throws -> MoviePageableList { @@ -64,7 +68,7 @@ public final class SearchService { do { movieList = try await apiClient.get(endpoint: SearchEndpoint.movies(query: query, year: year, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -82,6 +86,8 @@ public final class SearchService { /// - firstAirDateYear: The year of first air date to filter results for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: TV shows matching the query. /// public func searchTVShows(query: String, firstAirDateYear: Int? = nil, @@ -92,7 +98,7 @@ public final class SearchService { endpoint: SearchEndpoint.tvShows(query: query, firstAirDateYear: firstAirDateYear, page: page) ) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList @@ -109,6 +115,8 @@ public final class SearchService { /// - query: A text query to search for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: People matching the query. /// public func searchPeople(query: String, page: Int? = nil) async throws -> PersonPageableList { @@ -116,7 +124,7 @@ public final class SearchService { do { peopleList = try await apiClient.get(endpoint: SearchEndpoint.people(query: query, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return peopleList diff --git a/Sources/TMDb/TMDbConfiguration.swift b/Sources/TMDb/TMDbConfiguration.swift index 6c0ae087..7496a4fd 100644 --- a/Sources/TMDb/TMDbConfiguration.swift +++ b/Sources/TMDb/TMDbConfiguration.swift @@ -8,7 +8,7 @@ import Foundation public struct TMDbConfiguration { let apiKey: @Sendable () -> String - let httpClient: () -> any HTTPClient + let httpClient: @Sendable () -> any HTTPClient /// /// Creates a TMDb configuration object using URLSession as the HTTP client. @@ -30,7 +30,7 @@ public struct TMDbConfiguration { /// - apiKey: The TMDb API key to use. /// - httpClient: A custom HTTP client adapter for making HTTP requests. /// - public init(apiKey: String, httpClient: HTTPClient) { + public init(apiKey: String, httpClient: some HTTPClient) { self.init( apiKey: { apiKey }, httpClient: { httpClient } diff --git a/Sources/TMDb/TVShowEpisodes/TVShowEpisodeService.swift b/Sources/TMDb/TVShowEpisodes/TVShowEpisodeService.swift index b15efd46..6743710c 100644 --- a/Sources/TMDb/TVShowEpisodes/TVShowEpisodeService.swift +++ b/Sources/TMDb/TVShowEpisodes/TVShowEpisodeService.swift @@ -31,6 +31,8 @@ public final class TVShowEpisodeService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A episode of the matching TV show. /// public func details(forEpisode episodeNumber: Int, inSeason seasonNumber: Int, @@ -45,7 +47,7 @@ public final class TVShowEpisodeService { ) ) } catch let error { - throw error + throw TMDbError(error: error) } return episode @@ -61,6 +63,8 @@ public final class TVShowEpisodeService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of images for the matching TV show's episode. /// public func images(forEpisode episodeNumber: Int, inSeason seasonNumber: Int, @@ -75,7 +79,7 @@ public final class TVShowEpisodeService { ) ) } catch let error { - throw error + throw TMDbError(error: error) } return imageCollection @@ -91,6 +95,8 @@ public final class TVShowEpisodeService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of videos for the matching TV show's episode. /// public func videos(forEpisode episodeNumber: Int, inSeason seasonNumber: Int, @@ -105,7 +111,7 @@ public final class TVShowEpisodeService { ) ) } catch let error { - throw error + throw TMDbError(error: error) } return videoCollection diff --git a/Sources/TMDb/TVShowSeasons/TVShowSeasonService.swift b/Sources/TMDb/TVShowSeasons/TVShowSeasonService.swift index 8c2b257c..d2f74e0b 100644 --- a/Sources/TMDb/TVShowSeasons/TVShowSeasonService.swift +++ b/Sources/TMDb/TVShowSeasons/TVShowSeasonService.swift @@ -33,6 +33,8 @@ public final class TVShowSeasonService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A season of the matching TV show. /// public func details(forSeason seasonNumber: Int, inTVShow tvShowID: TVShow.ID) async throws -> TVShowSeason { @@ -42,7 +44,7 @@ public final class TVShowSeasonService { endpoint: TVShowSeasonsEndpoint.details(tvShowID: tvShowID, seasonNumber: seasonNumber) ) } catch let error { - throw error + throw TMDbError(error: error) } return season @@ -57,6 +59,8 @@ public final class TVShowSeasonService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of images for the matching TV show's season. /// public func images(forSeason seasonNumber: Int, inTVShow tvShowID: TVShow.ID) async throws -> ImageCollection { @@ -68,7 +72,7 @@ public final class TVShowSeasonService { languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return imageCollection @@ -83,6 +87,8 @@ public final class TVShowSeasonService { /// - seasonNumber: The season number of a TV show. /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of videos for the matching TV show's season. /// public func videos(forSeason seasonNumber: Int, inTVShow tvShowID: TVShow.ID) async throws -> VideoCollection { @@ -94,7 +100,7 @@ public final class TVShowSeasonService { languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return videoCollection diff --git a/Sources/TMDb/TVShows/TVShowService.swift b/Sources/TMDb/TVShows/TVShowService.swift index 6ac24408..2db66c19 100644 --- a/Sources/TMDb/TVShows/TVShowService.swift +++ b/Sources/TMDb/TVShows/TVShowService.swift @@ -32,6 +32,8 @@ public final class TVShowService { /// - Parameters: /// - id: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: The matching TV show. /// public func details(forTVShow id: TVShow.ID) async throws -> TVShow { @@ -39,7 +41,7 @@ public final class TVShowService { do { tvShow = try await apiClient.get(endpoint: TVShowsEndpoint.details(tvShowID: id)) } catch let error { - throw error + throw TMDbError(error: error) } return tvShow @@ -53,6 +55,8 @@ public final class TVShowService { /// - Parameters: /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Show credits for the matching TV show. /// public func credits(forTVShow tvShowID: TVShow.ID) async throws -> ShowCredits { @@ -60,7 +64,7 @@ public final class TVShowService { do { credits = try await apiClient.get(endpoint: TVShowsEndpoint.credits(tvShowID: tvShowID)) } catch let error { - throw error + throw TMDbError(error: error) } return credits @@ -77,6 +81,8 @@ public final class TVShowService { /// - tvShowID: The identifier of the TV show. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Reviews for the matching TV show as a pageable list. /// public func reviews(forTVShow tvShowID: TVShow.ID, page: Int? = nil) async throws -> ReviewPageableList { @@ -84,7 +90,7 @@ public final class TVShowService { do { reviewList = try await apiClient.get(endpoint: TVShowsEndpoint.reviews(tvShowID: tvShowID, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return reviewList @@ -98,6 +104,8 @@ public final class TVShowService { /// - Parameters: /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of images for the matching TV show. /// public func images(forTVShow tvShowID: TVShow.ID) async throws -> ImageCollection { @@ -108,7 +116,7 @@ public final class TVShowService { endpoint: TVShowsEndpoint.images(tvShowID: tvShowID, languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return imageCollection @@ -122,6 +130,8 @@ public final class TVShowService { /// - Parameters: /// - tvShowID: The identifier of the TV show. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: A collection of videos for the matching TV show. /// public func videos(forTVShow tvShowID: TVShow.ID) async throws -> VideoCollection { @@ -132,7 +142,7 @@ public final class TVShowService { endpoint: TVShowsEndpoint.videos(tvShowID: tvShowID, languageCode: languageCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return videoCollection @@ -149,6 +159,8 @@ public final class TVShowService { /// - tvShowID: The identifier of the TV show. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Recommended TV shows for the matching TV show as a pageable list. /// public func recommendations(forTVShow tvShowID: TVShow.ID, page: Int? = nil) async throws -> TVShowPageableList { @@ -158,7 +170,7 @@ public final class TVShowService { endpoint: TVShowsEndpoint.recommendations(tvShowID: tvShowID, page: page) ) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList @@ -177,6 +189,8 @@ public final class TVShowService { /// - tvShowID: The identifier of the TV show for get similar TV shows for. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Similar TV shows for the matching TV show as a pageable list. /// public func similar(toTVShow tvShowID: TVShow.ID, page: Int? = nil) async throws -> TVShowPageableList { @@ -184,7 +198,7 @@ public final class TVShowService { do { tvShowList = try await apiClient.get(endpoint: TVShowsEndpoint.similar(tvShowID: tvShowID, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList @@ -200,6 +214,8 @@ public final class TVShowService { /// - Parameters: /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Current popular TV shows as a pageable list. /// public func popular(page: Int? = nil) async throws -> TVShowPageableList { @@ -207,7 +223,7 @@ public final class TVShowService { do { tvShowList = try await apiClient.get(endpoint: TVShowsEndpoint.popular(page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList diff --git a/Sources/TMDb/Trending/TrendingService.swift b/Sources/TMDb/Trending/TrendingService.swift index 7c6f473d..a9609475 100644 --- a/Sources/TMDb/Trending/TrendingService.swift +++ b/Sources/TMDb/Trending/TrendingService.swift @@ -35,6 +35,8 @@ public final class TrendingService { /// - timeWindow: Daily or weekly time window. Defaults to daily. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Trending movies in a time window as a pageable list. /// public func movies(inTimeWindow timeWindow: TrendingTimeWindowFilterType = .default, @@ -43,7 +45,7 @@ public final class TrendingService { do { movieList = try await apiClient.get(endpoint: TrendingEndpoint.movies(timeWindow: timeWindow, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return movieList @@ -63,6 +65,8 @@ public final class TrendingService { /// - timeWindow: Daily or weekly time window. Defaults to daily. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Trending TV shows in a time window as a pageable list. /// public func tvShows(inTimeWindow timeWindow: TrendingTimeWindowFilterType = .default, @@ -71,7 +75,7 @@ public final class TrendingService { do { tvShowList = try await apiClient.get(endpoint: TrendingEndpoint.tvShows(timeWindow: timeWindow, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return tvShowList @@ -91,6 +95,8 @@ public final class TrendingService { /// - timeWindow: Daily or weekly time window. Defaults to daily. /// - page: The page of results to return. /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Trending people in a time window as a pageable list. /// public func people(inTimeWindow timeWindow: TrendingTimeWindowFilterType = .default, @@ -99,7 +105,7 @@ public final class TrendingService { do { peopleList = try await apiClient.get(endpoint: TrendingEndpoint.people(timeWindow: timeWindow, page: page)) } catch let error { - throw error + throw TMDbError(error: error) } return peopleList diff --git a/Sources/TMDb/WatchProviders/WatchProviderService.swift b/Sources/TMDb/WatchProviders/WatchProviderService.swift index 5f3cec98..d566b1a9 100644 --- a/Sources/TMDb/WatchProviders/WatchProviderService.swift +++ b/Sources/TMDb/WatchProviders/WatchProviderService.swift @@ -29,6 +29,8 @@ public final class WatchProviderService { /// /// [TMDb API - Watch Providers: Regions](https://developers.themoviedb.org/3/watch-providers/get-available-regions) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Countries TMDb have watch provider data for. /// public func countries() async throws -> [Country] { @@ -36,7 +38,7 @@ public final class WatchProviderService { do { regions = try await apiClient.get(endpoint: WatchProviderEndpoint.regions) } catch let error { - throw error + throw TMDbError(error: error) } return regions.results @@ -47,6 +49,8 @@ public final class WatchProviderService { /// /// [TMDb API - Watch Providers: Movie](https://developers.themoviedb.org/3/watch-providers/get-movie-providers) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Watch providers for movies. /// public func movieWatchProviders() async throws -> [WatchProvider] { @@ -57,7 +61,7 @@ public final class WatchProviderService { endpoint: WatchProviderEndpoint.movie(regionCode: regionCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return result.results @@ -68,6 +72,8 @@ public final class WatchProviderService { /// /// [TMDb API - Watch Providers: TV](https://developers.themoviedb.org/3/watch-providers/get-tv-providers) /// + /// - Throws: TMDb data error ``TMDbError``. + /// /// - Returns: Watch providers for TV shows. /// public func tvShowWatchProviders() async throws -> [WatchProvider] { @@ -78,7 +84,7 @@ public final class WatchProviderService { endpoint: WatchProviderEndpoint.tvShow(regionCode: regionCode) ) } catch let error { - throw error + throw TMDbError(error: error) } return result.results diff --git a/Tests/TMDbTests/Mocks/Client/MockAPIClient.swift b/Tests/TMDbTests/Mocks/Client/MockAPIClient.swift index 47743f5c..10f768f8 100644 --- a/Tests/TMDbTests/Mocks/Client/MockAPIClient.swift +++ b/Tests/TMDbTests/Mocks/Client/MockAPIClient.swift @@ -5,7 +5,7 @@ final class MockAPIClient: APIClient { static var apiKey: String? - var result: Result? + var result: Result? var requestTime: UInt64 = 0 private(set) var lastPath: URL? private(set) var getCount = 0 @@ -23,20 +23,20 @@ final class MockAPIClient: APIClient { } guard let result else { - throw TMDbError.unknown + throw TMDbAPIError.unknown } do { guard let value = try result.get() as? Response else { - XCTFail("Can't cast response to type \(String(describing: Response.self))") - throw TMDbError.unknown + preconditionFailure("Can't cast response to type \(String(describing: Response.self))") +// throw TMDbAPIError.unknown } return value - } catch let error as TMDbError { + } catch let error as TMDbAPIError { throw error } catch { - throw TMDbError.unknown + throw TMDbAPIError.unknown } } diff --git a/Tests/TMDbTests/Models/MovieTests.swift b/Tests/TMDbTests/Models/MovieTests.swift index 1dbb3a36..1a49ce80 100644 --- a/Tests/TMDbTests/Models/MovieTests.swift +++ b/Tests/TMDbTests/Models/MovieTests.swift @@ -28,42 +28,6 @@ final class MovieTests: XCTestCase { XCTAssertEqual(result, movie) } - func testSortWithNoDates() { - let movieOne = Movie(id: .randomID, title: .randomString) - let movieTwo = Movie(id: .randomID, title: .randomString) - - let result = movieOne < movieTwo - - XCTAssertFalse(result) - } - - func testSortWithLHSDate() { - let movieOne = Movie(id: .randomID, title: .randomString, releaseDate: Date(timeIntervalSince1970: 1618840399)) - let movieTwo = Movie(id: .randomID, title: .randomString) - - let result = movieOne < movieTwo - - XCTAssertTrue(result) - } - - func testSortWithRHSDate() { - let movieOne = Movie(id: .randomID, title: .randomString) - let movieTwo = Movie(id: .randomID, title: .randomString, releaseDate: Date(timeIntervalSince1970: 1218840399)) - - let result = movieOne < movieTwo - - XCTAssertFalse(result) - } - - func testSortWithDates() { - let movieOne = Movie(id: .randomID, title: .randomString, releaseDate: Date(timeIntervalSince1970: 1618840399)) - let movieTwo = Movie(id: .randomID, title: .randomString, releaseDate: Date(timeIntervalSince1970: 1218840399)) - - let result = movieOne < movieTwo - - XCTAssertTrue(result) - } - } extension MovieTests { diff --git a/Tests/TMDbTests/Models/TMDbErrorTests.swift b/Tests/TMDbTests/Models/TMDbErrorTests.swift deleted file mode 100644 index 55c9377a..00000000 --- a/Tests/TMDbTests/Models/TMDbErrorTests.swift +++ /dev/null @@ -1,35 +0,0 @@ -@testable import TMDb -import XCTest - -final class TMDbErrorTests: XCTestCase { - - func testNetworkReturnsErrorDescription() { - let urlError = URLError(.badURL) - let expectedResult = urlError.localizedDescription - - let result = TMDbError.network(urlError).localizedDescription - - XCTAssertEqual(result, expectedResult) - } - - func testUnauthorizedReturnsErrorDescription() { - XCTAssertEqual(TMDbError.unauthorised(nil).localizedDescription, "Unauthorised") - } - - func testNotFoundReturnsErrorDescription() { - XCTAssertEqual(TMDbError.notFound(nil).localizedDescription, "Not found") - } - - func testUnknownReturnsErrorDescription() { - XCTAssertEqual(TMDbError.unknown.localizedDescription, "Unknown error") - } - - func testDecodeReturnsErrorDescription() { - let error = URLError(.badURL) - - let result = TMDbError.decode(error).localizedDescription - - XCTAssertEqual(result, error.localizedDescription) - } - -} diff --git a/Tests/TMDbTests/Models/TVShowTests.swift b/Tests/TMDbTests/Models/TVShowTests.swift index 14db4621..d8ae9fba 100644 --- a/Tests/TMDbTests/Models/TVShowTests.swift +++ b/Tests/TMDbTests/Models/TVShowTests.swift @@ -28,46 +28,6 @@ final class TVShowTests: XCTestCase { XCTAssertEqual(result, tvShow) } - func testSortNoDates() { - let tvShowOne = TVShow(id: .randomID, name: .randomString) - let tvShowTwo = TVShow(id: .randomID, name: .randomString) - - let result = tvShowOne < tvShowTwo - - XCTAssertFalse(result) - } - - func testSortWithLHSDate() { - let tvShowOne = TVShow(id: .randomID, name: .randomString, - firstAirDate: Date(timeIntervalSince1970: 1618840399)) - let tvShowTwo = TVShow(id: .randomID, name: .randomString) - - let result = tvShowOne < tvShowTwo - - XCTAssertTrue(result) - } - - func testSortWithRHSDate() { - let tvShowOne = TVShow(id: .randomID, name: .randomString) - let tvShowTwo = TVShow(id: .randomID, name: .randomString, - firstAirDate: Date(timeIntervalSince1970: 1218840399)) - - let result = tvShowOne < tvShowTwo - - XCTAssertFalse(result) - } - - func testSortWithDates() { - let tvShowOne = TVShow(id: .randomID, name: .randomString, - firstAirDate: Date(timeIntervalSince1970: 1618840399)) - let tvShowTwo = TVShow(id: .randomID, name: .randomString, - firstAirDate: Date(timeIntervalSince1970: 1218840399)) - - let result = tvShowOne < tvShowTwo - - XCTAssertTrue(result) - } - } extension TVShowTests { diff --git a/Tests/TMDbTests/Networking/APIClient/TMDbAPIClientTests.swift b/Tests/TMDbTests/Networking/APIClient/TMDbAPIClientTests.swift index 854133b0..471158a2 100644 --- a/Tests/TMDbTests/Networking/APIClient/TMDbAPIClientTests.swift +++ b/Tests/TMDbTests/Networking/APIClient/TMDbAPIClientTests.swift @@ -42,7 +42,7 @@ final class TMDbAPIClientTests: XCTestCase { do { _ = try await apiClient.get(path: URL(string: "/error")!) as String - } catch let error as TMDbError { + } catch let error as TMDbAPIError { switch error { case .unauthorised: XCTAssertTrue(true) @@ -60,7 +60,7 @@ final class TMDbAPIClientTests: XCTestCase { do { _ = try await apiClient.get(path: URL(string: "/error")!) as String - } catch let error as TMDbError { + } catch let error as TMDbAPIError { switch error { case .notFound: XCTAssertTrue(true) @@ -80,7 +80,7 @@ final class TMDbAPIClientTests: XCTestCase { do { _ = try await apiClient.get(path: URL(string: "/error")!) as String - } catch let error as TMDbError { + } catch let error as TMDbAPIError { switch error { case .notFound(let message): XCTAssertEqual(message, expectedStatusMessage) diff --git a/Tests/TMDbTests/Networking/APIClient/TMDbErrorHTTPStatusCodeTests.swift b/Tests/TMDbTests/Networking/APIClient/TMDbAPIErrorHTTPStatusCodeTests.swift similarity index 78% rename from Tests/TMDbTests/Networking/APIClient/TMDbErrorHTTPStatusCodeTests.swift rename to Tests/TMDbTests/Networking/APIClient/TMDbAPIErrorHTTPStatusCodeTests.swift index 4bb7f2c7..ef213b34 100644 --- a/Tests/TMDbTests/Networking/APIClient/TMDbErrorHTTPStatusCodeTests.swift +++ b/Tests/TMDbTests/Networking/APIClient/TMDbAPIErrorHTTPStatusCodeTests.swift @@ -1,13 +1,13 @@ @testable import TMDb import XCTest -final class TMDbErrorHTTPStatusCodeTests: XCTestCase { +final class TMDbAPIErrorHTTPStatusCodeTests: XCTestCase { func testBadRequest() { let statusCode = 400 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .badRequest(let message): @@ -22,7 +22,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 401 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .unauthorised(let message): @@ -37,7 +37,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 403 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .forbidden(let message): @@ -52,7 +52,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 404 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .notFound(let message): @@ -67,7 +67,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 405 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .methodNotAllowed(let message): @@ -82,7 +82,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 406 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .notAcceptable(let message): @@ -97,7 +97,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 422 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .unprocessableContent(let message): @@ -112,7 +112,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 429 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .tooManyRequests(let message): @@ -127,7 +127,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 500 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .internalServerError(let message): @@ -142,7 +142,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 501 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .notImplemented(let message): @@ -157,7 +157,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 502 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .badGateway(let message): @@ -172,7 +172,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 503 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .serviceUnavailable(let message): @@ -187,7 +187,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { let statusCode = 504 let expectedMessage = "Some error message" - let error = TMDbError(statusCode: statusCode, message: expectedMessage) + let error = TMDbAPIError(statusCode: statusCode, message: expectedMessage) switch error { case .gatewayTimeout(let message): @@ -201,7 +201,7 @@ final class TMDbErrorHTTPStatusCodeTests: XCTestCase { func testUnknown() { let statusCode = 999 - let error = TMDbError(statusCode: statusCode, message: nil) + let error = TMDbAPIError(statusCode: statusCode, message: nil) switch error { case .unknown: diff --git a/Tests/TMDbTests/Models/TMDbStatusResponseTests.swift b/Tests/TMDbTests/Networking/APIClient/TMDbStatusResponseTests.swift similarity index 100% rename from Tests/TMDbTests/Models/TMDbStatusResponseTests.swift rename to Tests/TMDbTests/Networking/APIClient/TMDbStatusResponseTests.swift diff --git a/Tests/TMDbTests/People/PersonServiceTests.swift b/Tests/TMDbTests/People/PersonServiceTests.swift index c20c46a7..6e7c66b0 100644 --- a/Tests/TMDbTests/People/PersonServiceTests.swift +++ b/Tests/TMDbTests/People/PersonServiceTests.swift @@ -43,7 +43,7 @@ final class PersonServiceTests: XCTestCase { func testMovieCreditsReturnsMovieCredits() async throws { let mock = PersonMovieCredits.mock() - let expectedResult = PersonMovieCredits(id: mock.id, cast: mock.cast.sorted(), crew: mock.crew.sorted()) + let expectedResult = PersonMovieCredits(id: mock.id, cast: mock.cast, crew: mock.crew) let personID = expectedResult.id apiClient.result = .success(expectedResult) @@ -55,7 +55,7 @@ final class PersonServiceTests: XCTestCase { func testTVShowCreditsReturnsTVShowCredits() async throws { let mock = PersonTVShowCredits.mock() - let expectedResult = PersonTVShowCredits(id: mock.id, cast: mock.cast.sorted(), crew: mock.crew.sorted()) + let expectedResult = PersonTVShowCredits(id: mock.id, cast: mock.cast, crew: mock.crew) let personID = expectedResult.id apiClient.result = .success(expectedResult) diff --git a/Tests/TMDbTests/TMDbTests.swift b/Tests/TMDbTests/TMDbTests.swift new file mode 100644 index 00000000..c402576b --- /dev/null +++ b/Tests/TMDbTests/TMDbTests.swift @@ -0,0 +1,48 @@ +@testable import TMDb +import XCTest + +final class TMDbTest: XCTestCase { + + func testConfigureSetsAPIKey() { + let expectedAPIKey = "abc123" + let configuration = TMDbConfiguration(apiKey: expectedAPIKey) + + TMDb.configure(configuration) + let apiKey = TMDb.configuration.apiKey() + + XCTAssertEqual(apiKey, expectedAPIKey) + } + + func testConfigurationWhenHTTPClientNotSetUsesDefaultAdapter() { + let configuration = TMDbConfiguration(apiKey: "") + + TMDb.configure(configuration) + let httpClient = TMDb.configuration.httpClient() + + XCTAssertTrue(httpClient is URLSessionHTTPClientAdapter) + } + + func testConfigurationWhenSetsHTTPClient() { + let expectedHTTPClient = MockHTTPClient() + let configuration = TMDbConfiguration(apiKey: "", httpClient: expectedHTTPClient) + + TMDb.configure(configuration) + let httpClient = TMDb.configuration.httpClient() + + XCTAssertIdentical(httpClient as AnyObject, expectedHTTPClient) + } + +} + +extension TMDbTest { + + private final class MockHTTPClient: HTTPClient { + + init() { } + + func get(url: URL, headers: [String: String]) async throws -> HTTPResponse { + HTTPResponse() + } + } + +}