From a6cd279514afaf90e44d11b684c3acb14547db64 Mon Sep 17 00:00:00 2001 From: Adam Young Date: Mon, 6 May 2024 21:16:44 +0100 Subject: [PATCH] FEATURE: TV Series aggregate credits (#174) * TVSeriesAggregateCreditsRequest * Add method to TVSeriesService * FEATURE: TV Series aggregate credits * Update docs --- .../Domain/Models/AggregrateCastMember.swift | 118 +++++++++++++++++ .../Domain/Models/AggregrateCrewMember.swift | 118 +++++++++++++++++ Sources/TMDb/Domain/Models/CastRole.swift | 71 ++++++++++ Sources/TMDb/Domain/Models/CrewJob.swift | 71 ++++++++++ .../Models/TVSeriesAggregateCredits.swift | 58 +++++++++ .../TVSeriesAggregateCreditsRequest.swift | 30 +++++ .../Services/TVSeries/TVSeriesService.swift | 29 +++++ .../TMDb.docc/Extensions/TVSeriesService.md | 1 + Sources/TMDb/TMDb.docc/TMDb.md | 5 + .../TVSeriesServiceTests.swift | 9 ++ .../Models/AggregrateCastMemberTests.swift | 58 +++++++++ .../Models/AggregrateCrewMemberTests.swift | 58 +++++++++ .../TVSeriesAggregateCreditsTests.swift | 36 ++++++ ...TVSeriesAggregateCreditsRequestTests.swift | 57 +++++++++ .../TVSeries/TVSeriesServiceTests.swift | 12 ++ .../Resources/json/aggregate-cast-member.json | 19 +++ .../Resources/json/aggregate-crew-member.json | 19 +++ .../json/tv-series-aggregate-credits.json | 121 ++++++++++++++++++ 18 files changed, 890 insertions(+) create mode 100644 Sources/TMDb/Domain/Models/AggregrateCastMember.swift create mode 100644 Sources/TMDb/Domain/Models/AggregrateCrewMember.swift create mode 100644 Sources/TMDb/Domain/Models/CastRole.swift create mode 100644 Sources/TMDb/Domain/Models/CrewJob.swift create mode 100644 Sources/TMDb/Domain/Models/TVSeriesAggregateCredits.swift create mode 100644 Sources/TMDb/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequest.swift create mode 100644 Tests/TMDbTests/Domain/Models/AggregrateCastMemberTests.swift create mode 100644 Tests/TMDbTests/Domain/Models/AggregrateCrewMemberTests.swift create mode 100644 Tests/TMDbTests/Domain/Models/TVSeriesAggregateCreditsTests.swift create mode 100644 Tests/TMDbTests/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequestTests.swift create mode 100644 Tests/TMDbTests/Resources/json/aggregate-cast-member.json create mode 100644 Tests/TMDbTests/Resources/json/aggregate-crew-member.json create mode 100644 Tests/TMDbTests/Resources/json/tv-series-aggregate-credits.json diff --git a/Sources/TMDb/Domain/Models/AggregrateCastMember.swift b/Sources/TMDb/Domain/Models/AggregrateCastMember.swift new file mode 100644 index 00000000..0b3b93ad --- /dev/null +++ b/Sources/TMDb/Domain/Models/AggregrateCastMember.swift @@ -0,0 +1,118 @@ +// +// AggregrateCastMember.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 an aggregate cast member. +/// +public struct AggregrateCastMember: Identifiable, Codable, Equatable, Hashable, Sendable { + + /// + /// Person identifier. + /// + public let id: Int + + /// + /// Cast member's name. + /// + public let name: String + + /// + /// Cast member's original name. + /// + public let originalName: String + + /// + /// Cast member's gender. + /// + public let gender: Gender + + /// + /// Cast member's profile image. + /// + /// To generate a full URL see . + /// + public let profilePath: URL? + + /// + /// Cast member's roles. + /// + public let roles: [CastRole] + + /// + /// Department this person is known for. + /// + public let knownForDepartment: String? + + /// + /// Is adult? + /// + public let adult: Bool? + + /// + /// Total episodes this cast member appears in. + /// + public let totalEpisodeCount: Int + + /// + /// Cast member's popularity. + /// + public let popularity: Double? + + /// + /// Creates an aggregate cast member's role object. + /// + /// - Parameters: + /// - id: Person identifier. + /// - name: Cast member's name. + /// - originalName: Cast member's original name. + /// - gender: Cast member's gender. + /// - profilePath: Cast member's profile image. + /// - roles: Cast member's roles. + /// - knownForDepartment: Department this person is known for. + /// - adult: Is adult? + /// - totalEpisodeCount: Total episodes this cast member appears in. + /// - popularity: Cast member's popularity. + /// + public init( + id: Int, + name: String, + originalName: String, + gender: Gender, + profilePath: URL?, + roles: [CastRole], + knownForDepartment: String?, + adult: Bool?, + totalEpisodeCount: Int, + popularity: Double? + ) { + self.id = id + self.name = name + self.originalName = originalName + self.gender = gender + self.profilePath = profilePath + self.roles = roles + self.knownForDepartment = knownForDepartment + self.adult = adult + self.totalEpisodeCount = totalEpisodeCount + self.popularity = popularity + } + +} diff --git a/Sources/TMDb/Domain/Models/AggregrateCrewMember.swift b/Sources/TMDb/Domain/Models/AggregrateCrewMember.swift new file mode 100644 index 00000000..dcf597d7 --- /dev/null +++ b/Sources/TMDb/Domain/Models/AggregrateCrewMember.swift @@ -0,0 +1,118 @@ +// +// AggregrateCrewMember.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 an aggregate crew member. +/// +public struct AggregrateCrewMember: Identifiable, Codable, Equatable, Hashable, Sendable { + + /// + /// Person identifier. + /// + public let id: Int + + /// + /// Crew member's name. + /// + public let name: String + + /// + /// Crew member's original name. + /// + public let originalName: String + + /// + /// Cast member's gender. + /// + public let gender: Gender + + /// + /// Cast member's profile image. + /// + /// To generate a full URL see . + /// + public let profilePath: URL? + + /// + /// Cast member's roles. + /// + public let jobs: [CrewJob] + + /// + /// Department this person is known for. + /// + public let knownForDepartment: String? + + /// + /// Is adult? + /// + public let adult: Bool? + + /// + /// Total episodes the crew member worked on. + /// + public let totalEpisodeCount: Int + + /// + /// Cast member's popularity. + /// + public let popularity: Double? + + /// + /// Creates an aggregate cast member's role object. + /// + /// - Parameters: + /// - id: Person identifier. + /// - name: Crew member's name. + /// - originalName: Crew member's original name. + /// - gender: Crew member's gender. + /// - profilePath: Crew member's profile image. + /// - jobs: Crew member's job. + /// - knownForDepartment: Department this person is known for. + /// - adult: Is adult? + /// - totalEpisodeCount: Total episodes this crew member appears in. + /// - popularity: Crew member's popularity. + /// + public init( + id: Int, + name: String, + originalName: String, + gender: Gender, + profilePath: URL?, + jobs: [CrewJob], + knownForDepartment: String?, + adult: Bool?, + totalEpisodeCount: Int, + popularity: Double? + ) { + self.id = id + self.name = name + self.originalName = originalName + self.gender = gender + self.profilePath = profilePath + self.jobs = jobs + self.knownForDepartment = knownForDepartment + self.adult = adult + self.totalEpisodeCount = totalEpisodeCount + self.popularity = popularity + } + +} diff --git a/Sources/TMDb/Domain/Models/CastRole.swift b/Sources/TMDb/Domain/Models/CastRole.swift new file mode 100644 index 00000000..bea03c02 --- /dev/null +++ b/Sources/TMDb/Domain/Models/CastRole.swift @@ -0,0 +1,71 @@ +// +// CastRole.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 an aggregate cast member's role. +/// +public struct CastRole: Codable, Equatable, Hashable, Sendable { + + /// + /// Credit identifier. + /// + public let creditID: String + + /// + /// Cast member's character. + /// + public let character: String + + /// + /// Number of episodes this cast member appeared in in this role. + /// + public let episodeCount: Int + + /// + /// Creates an aggregate cast member's role object. + /// + /// - Parameters: + /// - creditID: Credit identifier. + /// - character: Cast member's character. + /// - episodeCount: Number of episodes this cast member appeared in in + /// this role. + /// + public init( + creditID: String, + character: String, + episodeCount: Int + ) { + self.creditID = creditID + self.character = character + self.episodeCount = episodeCount + } + +} + +extension CastRole { + + private enum CodingKeys: String, CodingKey { + case creditID = "creditId" + case character + case episodeCount + } + +} diff --git a/Sources/TMDb/Domain/Models/CrewJob.swift b/Sources/TMDb/Domain/Models/CrewJob.swift new file mode 100644 index 00000000..c747d0e2 --- /dev/null +++ b/Sources/TMDb/Domain/Models/CrewJob.swift @@ -0,0 +1,71 @@ +// +// CrewJob.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 an aggregate crew member's job. +/// +public struct CrewJob: Codable, Equatable, Hashable, Sendable { + + /// + /// Credit identifier. + /// + public let creditID: String + + /// + /// Crew member's job. + /// + public let job: String + + /// + /// Number of episodes this crew member appeared in in this role. + /// + public let episodeCount: Int + + /// + /// Creates an aggregate crew member's role object. + /// + /// - Parameters: + /// - creditID: Credit identifier. + /// - job: Crew member's job. + /// - episodeCount: Number of episodes this crew member appeared in in + /// this role. + /// + public init( + creditID: String, + job: String, + episodeCount: Int + ) { + self.creditID = creditID + self.job = job + self.episodeCount = episodeCount + } + +} + +extension CrewJob { + + private enum CodingKeys: String, CodingKey { + case creditID = "creditId" + case job + case episodeCount + } + +} diff --git a/Sources/TMDb/Domain/Models/TVSeriesAggregateCredits.swift b/Sources/TMDb/Domain/Models/TVSeriesAggregateCredits.swift new file mode 100644 index 00000000..80cdf73c --- /dev/null +++ b/Sources/TMDb/Domain/Models/TVSeriesAggregateCredits.swift @@ -0,0 +1,58 @@ +// +// TVSeriesAggregateCredits.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 a TV series aggregated credits. +/// +/// A person can be both a cast member and crew member of the same show. +/// +public struct TVSeriesAggregateCredits: Identifiable, Codable, Equatable, Hashable, Sendable { + + /// + /// TV series identifier. + /// + public let id: TVSeries.ID + + /// + /// Cast members of the TV series. + /// + public let cast: [AggregrateCastMember] + + /// + /// Crew members of the TV series. + /// + public let crew: [AggregrateCrewMember] + + /// + /// Creates a TV series aggregrate credits object. + /// + /// - Parameters: + /// - id: TV series identifier. + /// - cast: Cast members of the TV series. + /// - crew: Crew members of the TV series. + /// + public init(id: TVSeries.ID, cast: [AggregrateCastMember], crew: [AggregrateCrewMember]) { + self.id = id + self.cast = cast + self.crew = crew + } + +} diff --git a/Sources/TMDb/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequest.swift b/Sources/TMDb/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequest.swift new file mode 100644 index 00000000..9df6b7b5 --- /dev/null +++ b/Sources/TMDb/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequest.swift @@ -0,0 +1,30 @@ +// +// TVSeriesAggregateCreditsRequest.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 TVSeriesAggregateCreditsRequest: DecodableAPIRequest { + + init(id: TVSeries.ID) { + let path = "/tv/\(id)/aggregate_credits" + + super.init(path: path) + } + +} diff --git a/Sources/TMDb/Domain/Services/TVSeries/TVSeriesService.swift b/Sources/TMDb/Domain/Services/TVSeries/TVSeriesService.swift index e1e1cbe2..3787b438 100644 --- a/Sources/TMDb/Domain/Services/TVSeries/TVSeriesService.swift +++ b/Sources/TMDb/Domain/Services/TVSeries/TVSeriesService.swift @@ -95,6 +95,35 @@ public final class TVSeriesService { return credits } + /// + /// Returns the aggregate cast and crew of a TV series. + /// + /// This call differs from the main credits call in that it does not return + /// the newest season. Instead, it is a view of all the entire cast & crew + /// for all episodes belonging to a TV series. + /// + /// [TMDb API - TV Series: Aggregate Credits](https://developer.themoviedb.org/reference/tv-series-aggregate-credits) + /// + /// - Parameters: + /// - tvSeriesID: The identifier of the TV series. + /// + /// - Throws: TMDb error ``TMDbError``. + /// + /// - Returns: Show credits for the matching TV series. + /// + public func aggregateCredits(forTVSeries tvSeriesID: TVSeries.ID) async throws -> TVSeriesAggregateCredits { + let request = TVSeriesAggregateCreditsRequest(id: tvSeriesID) + + let credits: TVSeriesAggregateCredits + do { + credits = try await apiClient.perform(request) + } catch let error { + throw TMDbError(error: error) + } + + return credits + } + /// /// Returns the user reviews for a TV series. /// diff --git a/Sources/TMDb/TMDb.docc/Extensions/TVSeriesService.md b/Sources/TMDb/TMDb.docc/Extensions/TVSeriesService.md index 7fc641eb..740ac915 100644 --- a/Sources/TMDb/TMDb.docc/Extensions/TVSeriesService.md +++ b/Sources/TMDb/TMDb.docc/Extensions/TVSeriesService.md @@ -13,6 +13,7 @@ ### Credits - ``credits(forTVSeries:)`` +- ``aggregateCredits(forTVSeries:)`` ### Reviews diff --git a/Sources/TMDb/TMDb.docc/TMDb.md b/Sources/TMDb/TMDb.docc/TMDb.md index 39292a60..381167e7 100644 --- a/Sources/TMDb/TMDb.docc/TMDb.md +++ b/Sources/TMDb/TMDb.docc/TMDb.md @@ -67,6 +67,11 @@ For the TMDb API documentation, see - ``TVSeriesService`` - ``TVSeries`` - ``ShowCredits`` +- ``TVSeriesAggregateCredits`` +- ``AggregrateCastMember`` +- ``AggregrateCrewMember`` +- ``CastRole`` +- ``CrewJob`` - ``ReviewPageableList`` - ``Review`` - ``ImageCollection`` diff --git a/Tests/TMDbIntegrationTests/TVSeriesServiceTests.swift b/Tests/TMDbIntegrationTests/TVSeriesServiceTests.swift index 0aa6346e..e2864b38 100644 --- a/Tests/TMDbIntegrationTests/TVSeriesServiceTests.swift +++ b/Tests/TMDbIntegrationTests/TVSeriesServiceTests.swift @@ -53,6 +53,15 @@ final class TVSeriesServiceTests: XCTestCase { XCTAssertFalse(credits.crew.isEmpty) } + func testAggregateCredits() async throws { + let tvSeriesID = 4604 + + let credits = try await tvSeriesService.aggregateCredits(forTVSeries: tvSeriesID) + + XCTAssertFalse(credits.cast.isEmpty) + XCTAssertFalse(credits.crew.isEmpty) + } + func testReviews() async throws { let tvSeriesID = 76479 diff --git a/Tests/TMDbTests/Domain/Models/AggregrateCastMemberTests.swift b/Tests/TMDbTests/Domain/Models/AggregrateCastMemberTests.swift new file mode 100644 index 00000000..c04deaf5 --- /dev/null +++ b/Tests/TMDbTests/Domain/Models/AggregrateCastMemberTests.swift @@ -0,0 +1,58 @@ +// +// AggregrateCastMemberTests.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 AggregrateCastMemberTests: XCTestCase { + + func testDecodeReturnsCastMember() throws { + let result = try JSONDecoder.theMovieDatabase.decode( + AggregrateCastMember.self, + fromResource: "aggregate-cast-member" + ) + + XCTAssertEqual(result.id, castMember.id) + XCTAssertEqual(result.name, castMember.name) + XCTAssertEqual(result.originalName, castMember.originalName) + XCTAssertEqual(result.gender, castMember.gender) + XCTAssertEqual(result.profilePath, castMember.profilePath) + XCTAssertEqual(result.roles, castMember.roles) + XCTAssertEqual(result.knownForDepartment, castMember.knownForDepartment) + XCTAssertEqual(result.adult, castMember.adult) + XCTAssertEqual(result.totalEpisodeCount, castMember.totalEpisodeCount) + XCTAssertEqual(result.popularity, castMember.popularity) + } + + private let castMember = AggregrateCastMember( + id: 11824, + name: "Tom Welling", + originalName: "Tom Peter Welling", + gender: .male, + profilePath: URL(string: "/iLyXgCimAWNHSjkTXb7e5KgcMWh.jpg"), + roles: [ + CastRole(creditID: "5257751c760ee36aaa50e171", character: "Clark Kent", episodeCount: 216) + ], + knownForDepartment: "Acting", + adult: false, + totalEpisodeCount: 216, + popularity: 35.505 + ) + +} diff --git a/Tests/TMDbTests/Domain/Models/AggregrateCrewMemberTests.swift b/Tests/TMDbTests/Domain/Models/AggregrateCrewMemberTests.swift new file mode 100644 index 00000000..bc9daf00 --- /dev/null +++ b/Tests/TMDbTests/Domain/Models/AggregrateCrewMemberTests.swift @@ -0,0 +1,58 @@ +// +// AggregrateCrewMemberTests.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 AggregrateCrewMemberTests: XCTestCase { + + func testDecodeReturnsCrewMember() throws { + let result = try JSONDecoder.theMovieDatabase.decode( + AggregrateCrewMember.self, + fromResource: "aggregate-crew-member" + ) + + XCTAssertEqual(result.id, crewMember.id) + XCTAssertEqual(result.name, crewMember.name) + XCTAssertEqual(result.originalName, crewMember.originalName) + XCTAssertEqual(result.gender, crewMember.gender) + XCTAssertEqual(result.profilePath, crewMember.profilePath) + XCTAssertEqual(result.jobs, crewMember.jobs) + XCTAssertEqual(result.knownForDepartment, crewMember.knownForDepartment) + XCTAssertEqual(result.adult, crewMember.adult) + XCTAssertEqual(result.totalEpisodeCount, crewMember.totalEpisodeCount) + XCTAssertEqual(result.popularity, crewMember.popularity) + } + + private let crewMember = AggregrateCrewMember( + id: 1_856_851, + name: "Lance King", + originalName: "Lance King", + gender: .unknown, + profilePath: nil, + jobs: [ + CrewJob(creditID: "5ff88c4b383df2003c330070", job: "Production Design", episodeCount: 1) + ], + knownForDepartment: "Production", + adult: false, + totalEpisodeCount: 1, + popularity: 1.646 + ) + +} diff --git a/Tests/TMDbTests/Domain/Models/TVSeriesAggregateCreditsTests.swift b/Tests/TMDbTests/Domain/Models/TVSeriesAggregateCreditsTests.swift new file mode 100644 index 00000000..7ce32b83 --- /dev/null +++ b/Tests/TMDbTests/Domain/Models/TVSeriesAggregateCreditsTests.swift @@ -0,0 +1,36 @@ +// +// TVSeriesAggregateCreditsTests.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 TVSeriesAggregateCreditsTests: XCTestCase { + + func testDecodeReturnsTVSeriesAggregateCredits() throws { + let result = try JSONDecoder.theMovieDatabase.decode( + TVSeriesAggregateCredits.self, + fromResource: "tv-series-aggregate-credits" + ) + + XCTAssertEqual(result.id, 4604) + XCTAssertEqual(result.cast.count, 4) + XCTAssertEqual(result.crew.count, 2) + } + +} diff --git a/Tests/TMDbTests/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequestTests.swift b/Tests/TMDbTests/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequestTests.swift new file mode 100644 index 00000000..a4463239 --- /dev/null +++ b/Tests/TMDbTests/Domain/Services/TVSeries/Requests/TVSeriesAggregateCreditsRequestTests.swift @@ -0,0 +1,57 @@ +// +// TVSeriesAggregateCreditsRequestTests.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 TVSeriesAggregateCreditsRequestTests: XCTestCase { + + var request: TVSeriesAggregateCreditsRequest! + + override func setUp() { + super.setUp() + request = TVSeriesAggregateCreditsRequest(id: 1) + } + + override func tearDown() { + request = nil + super.tearDown() + } + + func testPath() { + XCTAssertEqual(request.path, "/tv/1/aggregate_credits") + } + + func testQueryItemsAreEmpty() { + XCTAssertTrue(request.queryItems.isEmpty) + } + + func testMethodIsGet() { + XCTAssertEqual(request.method, .get) + } + + func testHeadersIsEmpty() { + XCTAssertTrue(request.headers.isEmpty) + } + + func testBodyIsNil() { + XCTAssertNil(request.body) + } + +} diff --git a/Tests/TMDbTests/Domain/Services/TVSeries/TVSeriesServiceTests.swift b/Tests/TMDbTests/Domain/Services/TVSeries/TVSeriesServiceTests.swift index 78bb7c24..cc8e0db0 100644 --- a/Tests/TMDbTests/Domain/Services/TVSeries/TVSeriesServiceTests.swift +++ b/Tests/TMDbTests/Domain/Services/TVSeries/TVSeriesServiceTests.swift @@ -64,6 +64,18 @@ final class TVSeriesServiceTests: XCTestCase { XCTAssertEqual(apiClient.lastRequest as? TVSeriesCreditsRequest, expectedRequest) } + func testAggregateCreditsReturnsShowsCredits() async throws { + let expectedResult = TVSeriesAggregateCredits(id: 1, cast: [], crew: []) + let tvSeriesID = expectedResult.id + apiClient.addResponse(.success(expectedResult)) + let expectedRequest = TVSeriesAggregateCreditsRequest(id: tvSeriesID) + + let result = try await service.aggregateCredits(forTVSeries: tvSeriesID) + + XCTAssertEqual(result, expectedResult) + XCTAssertEqual(apiClient.lastRequest as? TVSeriesAggregateCreditsRequest, expectedRequest) + } + func testReviewsWithDefaultParametersReturnsReviews() async throws { let tvSeriesID = Int.randomID let expectedResult = ReviewPageableList.mock() diff --git a/Tests/TMDbTests/Resources/json/aggregate-cast-member.json b/Tests/TMDbTests/Resources/json/aggregate-cast-member.json new file mode 100644 index 00000000..1daf48e5 --- /dev/null +++ b/Tests/TMDbTests/Resources/json/aggregate-cast-member.json @@ -0,0 +1,19 @@ +{ + "adult": false, + "gender": 2, + "id": 11824, + "known_for_department": "Acting", + "name": "Tom Welling", + "original_name": "Tom Peter Welling", + "popularity": 35.505, + "profile_path": "/iLyXgCimAWNHSjkTXb7e5KgcMWh.jpg", + "roles": [ + { + "credit_id": "5257751c760ee36aaa50e171", + "character": "Clark Kent", + "episode_count": 216 + } + ], + "total_episode_count": 216, + "order": 0 +} diff --git a/Tests/TMDbTests/Resources/json/aggregate-crew-member.json b/Tests/TMDbTests/Resources/json/aggregate-crew-member.json new file mode 100644 index 00000000..eb65e91d --- /dev/null +++ b/Tests/TMDbTests/Resources/json/aggregate-crew-member.json @@ -0,0 +1,19 @@ +{ + "adult": false, + "gender": 0, + "id": 1856851, + "known_for_department": "Production", + "name": "Lance King", + "original_name": "Lance King", + "popularity": 1.646, + "profile_path": null, + "jobs": [ + { + "credit_id": "5ff88c4b383df2003c330070", + "job": "Production Design", + "episode_count": 1 + } + ], + "department": "Art", + "total_episode_count": 1 +} diff --git a/Tests/TMDbTests/Resources/json/tv-series-aggregate-credits.json b/Tests/TMDbTests/Resources/json/tv-series-aggregate-credits.json new file mode 100644 index 00000000..c4bf6b04 --- /dev/null +++ b/Tests/TMDbTests/Resources/json/tv-series-aggregate-credits.json @@ -0,0 +1,121 @@ +{ + "cast": [ + { + "adult": false, + "gender": 2, + "id": 11824, + "known_for_department": "Acting", + "name": "Tom Welling", + "original_name": "Tom Welling", + "popularity": 35.505, + "profile_path": "/iLyXgCimAWNHSjkTXb7e5KgcMWh.jpg", + "roles": [ + { + "credit_id": "5257751c760ee36aaa50e171", + "character": "Clark Kent", + "episode_count": 216 + } + ], + "total_episode_count": 216, + "order": 0 + }, + { + "adult": false, + "gender": 1, + "id": 60253, + "known_for_department": "Acting", + "name": "Allison Mack", + "original_name": "Allison Mack", + "popularity": 19.689, + "profile_path": "/roawhm5chQexp1nP69rslFsp8ns.jpg", + "roles": [ + { + "credit_id": "5257751c760ee36aaa50e299", + "character": "Chloe Sullivan", + "episode_count": 195 + } + ], + "total_episode_count": 195, + "order": 4 + }, + { + "adult": false, + "gender": 1, + "id": 55751, + "known_for_department": "Acting", + "name": "Kristin Kreuk", + "original_name": "Kristin Kreuk", + "popularity": 37.889, + "profile_path": "/vFA9YTXdgQ5VCkPzbdQfBC4tQrG.jpg", + "roles": [ + { + "credit_id": "5257751c760ee36aaa50e205", + "character": "Lana Lang", + "episode_count": 157 + } + ], + "total_episode_count": 157, + "order": 1 + }, + { + "adult": false, + "gender": 2, + "id": 19975, + "known_for_department": "Acting", + "name": "Michael Rosenbaum", + "original_name": "Michael Rosenbaum", + "popularity": 38.373, + "profile_path": "/9a1wACjRIAg1cbTEsL5WrzPwnFi.jpg", + "roles": [ + { + "credit_id": "5257751c760ee36aaa50e24f", + "character": "Lex Luthor", + "episode_count": 153 + } + ], + "total_episode_count": 153, + "order": 2 + } + ], + "crew": [ + { + "adult": false, + "gender": 0, + "id": 1856851, + "known_for_department": "Production", + "name": "Lance King", + "original_name": "Lance King", + "popularity": 1.646, + "profile_path": null, + "jobs": [ + { + "credit_id": "5ff88c4b383df2003c330070", + "job": "Production Design", + "episode_count": 1 + } + ], + "department": "Art", + "total_episode_count": 1 + }, + { + "adult": false, + "gender": 2, + "id": 203444, + "known_for_department": "Directing", + "name": "Glen Winter", + "original_name": "Glen Winter", + "popularity": 18.95, + "profile_path": null, + "jobs": [ + { + "credit_id": "60b4763afd140b007ab37b1d", + "job": "Director of Photography", + "episode_count": 17 + } + ], + "department": "Camera", + "total_episode_count": 17 + } + ], + "id": 4604 +}