8000 FEATURE: TVShow Content Ratings (#188) · adamayoung/TMDb@08094ce · GitHub
[go: up one dir, main page]

Skip to content

Commit

Permalink
FEATURE: TVShow Content Ratings (#188)
Browse files Browse the repository at this point in the history
* Add models and reqeust

* Add coding key

* Finalize

* Add id and initializer to Content Rating

* Update models

* Add mocks and tests

* Add json

* Add service test

* Format

* Remove swiftlint disable comment

* Request tests

* formatting

* More mocks and tests

---------

Co-authored-by: Adam Young <me@adam-young.co.uk>
  • Loading branch information
chickdan and adamayoung authored Jul 16, 2024
1 parent 868a1ad commit 08094ce
Show file tree
Hide file tree
Showing 15 changed files with 693 additions and 1 deletion.
62 changes: 62 additions & 0 deletions Sources/TMDb/Domain/Models/ContentRating.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// ContentRating.swift
// TMDb
//
// Copyright © 2024 Adam Young.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

///
/// A model representing the content rating.
///
public struct ContentRating: Codable, Equatable, Hashable, Sendable {

///
/// ?
///
public let descriptors: [String]

///
/// The ISO 3166-1 country code.
///
public let countryCode: String

///
/// The content rating of the tv show
///
public let rating: String

/// Creates a content rating object.
///
/// - Parameters:
/// - descriptors: Array of....
/// - countryCode: ISO 3166-1 country code.
/// - rating: The content rating of the tv show
///
public init(descriptors: [String], countryCode: String, rating: String) {
self.descriptors = descriptors
self.countryCode = countryCode
self.rating = rating
}
}

extension ContentRating {
private enum CodingKeys: String, CodingKey {
case rating
case descriptors
case countryCode = "iso31661"
}
}
25 changes: 25 additions & 0 deletions Sources/TMDb/Domain/Models/ContentRatingResult.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// ContentRatingResult.swift
// TMDb
//
// Copyright © 2024 Adam Young.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

struct ContentRatingResult: Codable, Equatable, Hashable, Sendable {
let results: [ContentRating]
let id: Int
}
2 changes: 1 addition & 1 deletion Sources/TMDb/Domain/Models/CrewMember.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import Foundation

///
/// A model representing a crew member..
/// A model representing a crew member.
///
public struct CrewMember: Identifiable, Codable, Equatable, Hashable, Sendable {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ContentRatingRequest.swift
// TMDb
//
// Copyright © 2024 Adam Young.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

final class ContentRatingRequest: DecodableAPIRequest<ContentRatingResult> {

init(id: TVSeries.ID) {
let path = "/tv/\(id)/content_ratings"

super.init(path: path)
}

}
18 changes: 18 additions & 0 deletions Sources/TMDb/Domain/Services/TVSeries/TMDbTVSeriesService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ final class TMDbTVSeriesService: TVSeriesService {
return result.results[country]
}

func contentRatings(
forTVSeries tvSeriesID: TVSeries.ID,
country: String = "US"
) async throws -> ContentRating? {
let request = ContentRatingRequest(id: tvSeriesID)

let result: ContentRatingResult
do {
result = try await apiClient.perform(request)
} catch let error {
throw TMDbError(error: error)
}

return result.results.first { rating in
rating.countryCode == country
}
}

func externalLinks(forTVSeries tvSeriesID: TVSeries.ID) async throws -> TVSeriesExternalLinksCollection {
let request = TVSeriesExternalLinksRequest(id: tvSeriesID)

Expand Down
17 changes: 17 additions & 0 deletions Sources/TMDb/Domain/Services/TVSeries/TVSeriesService.swift
8000
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,17 @@ public protocol TVSeriesService: Sendable {
///
func externalLinks(forTVSeries tvSeriesID: TVSeries.ID) async throws -> TVSeriesExternalLinksCollection

///
/// Returns the content rating of a TV series.
///
/// [TMDb API - TVSeries: Content ratings](https://developer.themoviedb.org/reference/tv-series-content-ratings)
///
/// - Parameters:
/// - tvSeriesID: The identifier of the TV series.
///
/// - Returns: A content rating for the specificed TV series.
///
func contentRatings(forTVSeries tvSeriesID: TVSeries.ID, country: String) async throws -> ContentRating?
}

public extension TVSeriesService {
Expand Down Expand Up @@ -285,4 +296,10 @@ public extension TVSeriesService {
try await watchProviders(forTVSeries: tvSeriesID, country: country)
}

func contentRatings(
forTVSeries tvSeriesID: TVSeries.ID,
country: String = "US"
) async throws -> ContentRating? {
try await contentRatings(forTVSeries: tvSeriesID, country: country)
}
}
12 changes: 12 additions & 0 deletions Tests/TMDbIntegrationTests/TVSeriesServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,16 @@ final class TVSeriesServiceTests: XCTestCase {
XCTAssertNotNil(linksCollection.twitter)
}

func testContentRatings() async throws {
let tvSeriesID = 8592

let contentRatings = try await tvSeriesService.contentRatings(forTVSeries: tvSeriesID, country: "US")

XCTAssertNotNil(contentRatings)

if let contentRating = contentRatings {
XCTAssertEqual(contentRating.rating, "TV-14")
XCTAssertEqual(contentRating.countryCode, "US")
}
}
}
38 changes: 38 additions & 0 deletions Tests/TMDbTests/Domain/Models/ContentRatingTests.swift
A3E2
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ContentRatingTests.swift
// TMDb
//
// Copyright © 2024 Adam Young.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

@testable import TMDb
import XCTest

final class ContentRatingTests: XCTestCase {

func testDecodeReturnsContentRating() throws {
let result = try JSONDecoder.theMovieDatabase.decode(ContentRating.self, fromResource: "content-rating")

XCTAssertEqual(result.descriptors, contentRating.descriptors)
XCTAssertEqual(result.countryCode, contentRating.countryCode)
XCTAssertEqual(result.rating, contentRating.rating)
}

private let contentRating = ContentRating(
descriptors: [],
countryCode: "US",
rating: "TV-14"
)
}
151 changes: 151 additions & 0 deletions Tests/TMDbTests/Domain/Models/ContentRatingsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
//
// ContentRatingsTests.swift
// TMDb
//
// Copyright © 2024 Adam Young.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

@testable import TMDb
import XCTest

final class ContentRatingsTests: XCTestCase {

func testDecodeReturnsContentRatingResult() throws {
let result = try JSONDecoder.theMovieDatabase.decode(ContentRatingResult.self, fromResource: "content-ratings")

XCTAssertEqual(result, contentRatings)
}

private let contentRatings = ContentRatingResult(
results: [
ContentRating(
descriptors: [],
countryCode: "US",
rating: "TV-14"
),
ContentRating(
descriptors: [],
countryCode: "AU",
rating: "M"
),
ContentRating(
descriptors: [],
countryCode: "RU",
rating: "12+"
),
ContentRating(
descriptors: [],
countryCode: "GB",
rating: "15"
),
ContentRating(
descriptors: [],
countryCode: "BR",
rating: "12"
),
ContentRating(
descriptors: [],
countryCode: "HU",
rating: "12"
),
ContentRating(
descriptors: [],
countryCode: "PH",
rating: "G"
),
ContentRating(
descriptors: [],
countryCode: "MX",
rating: "A"
),
ContentRating(
descriptors: [],
countryCode: "PT",
rating: "NR"
),
ContentRating(
descriptors: [],
countryCode: "ES",
rating: "16"
),
ContentRating(
descriptors: [],
countryCode: "FR",
rating: "16"
),
ContentRating(
descriptors: [],
countryCode: "CA",
rating: "PG"
),
ContentRating(
descriptors: [],
countryCode: "NL",
rating: "6"
),
ContentRating(
descriptors: [],
countryCode: "DE",
rating: "12"
),
ContentRating(
descriptors: [],
countryCode: "DE",
rating: "16"
),
ContentRating(
descriptors: [],
countryCode: "AU",
rating: "PG"
),
ContentRating(
descriptors: [],
countryCode: "KR",
rating: "15"
),
ContentRating(
descriptors: [],
countryCode: "AT",
rating: "12"
),
ContentRating(
descriptors: [],
countryCode: "CH",
rating: "12"
),
ContentRating(
descriptors: [],
countryCode: "PL",
rating: "16"
),
ContentRating(
descriptors: [],
countryCode: "HU",
rating: "16"
),
ContentRating(
descriptors: [],
countryCode: "CZ",
rating: "15+"
),
ContentRating(
descriptors: [],
countryCode: "RO",
rating: "15"
)
],
id: 8592
)
}
Loading

0 comments on commit 08094ce

Please sign in to comment.
0