[Library] iTunes library (#5)
This PR contains the work done to implement the `iTunesService` service that fetches the reviews from the **Apple App Store**. Reviewed-on: rock-n-code/app-reviews#5 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #5.
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// GetReviewsAPIEndpointTests.swift
|
||||
// ReviewsiTunesTest
|
||||
//
|
||||
// Created by Javier Cicchelli on 17/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
||||
//
|
||||
|
||||
import ReviewsFeedKit
|
||||
import ReviewsFoundationKit
|
||||
import XCTest
|
||||
|
||||
@testable import ReviewsiTunesKit
|
||||
|
||||
final class GetReviewsAPIEndpointTests: XCTestCase {
|
||||
|
||||
// MARK: Properties
|
||||
private var input: GetReviewsAPIEndpoint.Input!
|
||||
private var sut: GetReviewsAPIEndpoint!
|
||||
|
||||
// MARK: Setup
|
||||
override func setUp() async throws {
|
||||
sut = .init(
|
||||
host: .iTunes,
|
||||
decoder: .default,
|
||||
session: .init(configuration: .mock)
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: Functions tests
|
||||
func testCallAsFunction_whenResponseOK_withOneReview() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .one
|
||||
|
||||
input = .init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testCallAsFunction_whenResponseOK_withManyReviews() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .many
|
||||
|
||||
input = .init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testCallAsFunction_whenResponseOK_withEmptyReviews() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .empty
|
||||
|
||||
input = .init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut(input)
|
||||
|
||||
// THEN
|
||||
XCTAssertTrue(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testCallAsFunction_whenResponseNotOK() async throws {
|
||||
// GIVEN
|
||||
let statusCode = 404
|
||||
|
||||
input = .init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
MockURLProtocol.response = .init(statusCode: statusCode)
|
||||
|
||||
// WHEN
|
||||
// THEN
|
||||
do {
|
||||
try await sut(input)
|
||||
} catch EndpointError.requestFailed(statusCode: statusCode) {
|
||||
XCTAssertTrue(true)
|
||||
} catch {
|
||||
XCTAssertTrue(false)
|
||||
}
|
||||
}
|
||||
|
||||
func testMakePath_withFilledInput() throws {
|
||||
// GIVEN
|
||||
input = .init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let path = try sut.makePath(with: input)
|
||||
|
||||
// THEN
|
||||
XCTAssertEqual(path, "/\(input.countryCode)/rss/customerreviews/id=\(input.appID)/sortby=mostrecent/json")
|
||||
}
|
||||
|
||||
func testMakePath_withPartiallyFilledInput() throws {
|
||||
// GIVEN
|
||||
input = .init(
|
||||
appID: .empty,
|
||||
countryCode: "abc"
|
||||
)
|
||||
|
||||
// WHEN
|
||||
// THEN
|
||||
XCTAssertThrowsError(try sut.makePath(with: input)) { error in
|
||||
XCTAssertEqual(error as? EndpointError, .inputParametersEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
func testMakePath_withEmptyInput() throws {
|
||||
// GIVEN
|
||||
input = .init(
|
||||
appID: .empty,
|
||||
countryCode: .empty
|
||||
)
|
||||
|
||||
// WHEN
|
||||
// THEN
|
||||
XCTAssertThrowsError(try sut.makePath(with: input)) { error in
|
||||
XCTAssertEqual(error as? EndpointError, .inputParametersEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// iTunesServiceTests.swift
|
||||
// ReviewsiTunesTest
|
||||
//
|
||||
// Created by Javier Cicchelli on 17/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
||||
//
|
||||
|
||||
import ReviewsFeedKit
|
||||
import ReviewsFoundationKit
|
||||
import XCTest
|
||||
|
||||
@testable import ReviewsiTunesKit
|
||||
|
||||
final class iTunesServiceTests: XCTestCase {
|
||||
|
||||
// MARK: Properties
|
||||
private var sut: iTunesService!
|
||||
|
||||
// MARK: Setup
|
||||
override func setUp() async throws {
|
||||
sut = .init(configuration: .init(session: .mock))
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
func testGetReviews_whenResponseOK_withOneReview() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .one
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut.getReviews(.init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
))
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews.count, reviews.count)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testGetReviews_whenResponseOK_withManyReview() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .many
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut.getReviews(.init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
))
|
||||
|
||||
// THEN
|
||||
XCTAssertFalse(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews.count, reviews.count)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testGetReviews_whenResponseOK_withEmptyReview() async throws {
|
||||
// GIVEN
|
||||
let reviews: [Review] = .empty
|
||||
|
||||
MockURLProtocol.response = .init(
|
||||
statusCode: 200,
|
||||
object: Feed(entries: reviews)
|
||||
)
|
||||
|
||||
// WHEN
|
||||
let output = try await sut.getReviews(.init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
))
|
||||
|
||||
// THEN
|
||||
XCTAssertTrue(output.reviews.isEmpty)
|
||||
XCTAssertEqual(output.reviews, reviews)
|
||||
}
|
||||
|
||||
func testGetReviews_whenResponseNotOK() async throws {
|
||||
// GIVEN
|
||||
let statusCode = 404
|
||||
|
||||
MockURLProtocol.response = .init(statusCode: statusCode)
|
||||
|
||||
// WHEN
|
||||
// THEN
|
||||
do {
|
||||
try await sut.getReviews(.init(
|
||||
appID: "1234567890",
|
||||
countryCode: "abc"
|
||||
))
|
||||
} catch EndpointError.requestFailed(statusCode: statusCode) {
|
||||
XCTAssertTrue(true)
|
||||
} catch {
|
||||
XCTAssertTrue(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user