This PR contains the work done to implement the actual public service interface to the Amiibo API. To provide further details about this work: - [x] defined a `Filter` protocol; - [x] implemented the `AmiiboFilter` and the `KeyNameFilter` filters; - [x] implemented the `Result` model; - [x] defined the `Service` protocol; - [x] implemented the `AmiiboService` concrete service; - [x] fixed the `path` of the `GetAmiiboEndpoint` endpoint; - [x] made the `usage` property of the `Game` model optional; - [x] replaced the `showGames` and the `showUsage` flags of the `AmiiboFilter` filter with an enumeration. Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Reviewed-on: #4
146 lines
3.9 KiB
Swift
146 lines
3.9 KiB
Swift
import Communications
|
|
import Foundation
|
|
import XCTest
|
|
|
|
@testable import AmiiboService
|
|
|
|
final class AmiiboClientTests: XCTestCase {
|
|
|
|
// MARK: Properties
|
|
|
|
private let configuration: URLSessionConfiguration = {
|
|
let configuration = URLSessionConfiguration.ephemeral
|
|
|
|
configuration.protocolClasses = [MockURLProtocol.self]
|
|
|
|
return configuration
|
|
}()
|
|
private let makeURLRequest = MakeURLRequestUseCase()
|
|
private let endpoint = TestEndpoint()
|
|
|
|
private var client: AmiiboClient!
|
|
|
|
// MARK: Setup
|
|
|
|
override func setUp() async throws {
|
|
client = .init(configuration: configuration)
|
|
}
|
|
|
|
override func tearDown() async throws {
|
|
client = nil
|
|
}
|
|
|
|
// MARK: Tests
|
|
|
|
func test_request_withEndpointAndModel_whenDataDoesMatchModel() async throws {
|
|
// GIVEN
|
|
let url = try XCTUnwrap(try makeURLRequest(endpoint: endpoint).url)
|
|
|
|
MockURLProtocol.mockData[.init(url: url)] = .init(
|
|
status: .ok,
|
|
data: .Client.Seed.dataWithoutTimestamp
|
|
)
|
|
|
|
// WHEN
|
|
let model = try await client.request(
|
|
endpoint: endpoint,
|
|
as: TestModel.self
|
|
)
|
|
|
|
// THEN
|
|
XCTAssertNotNil(model)
|
|
XCTAssertNil(model.timestamp)
|
|
}
|
|
|
|
func test_request_withEndpointAndModel_whenDataDoesMatchModel_andDateDecodingStrategy() async throws {
|
|
// GIVEN
|
|
let url = try XCTUnwrap(try makeURLRequest(endpoint: endpoint).url)
|
|
|
|
MockURLProtocol.mockData[.init(url: url)] = .init(
|
|
status: .ok,
|
|
data: .Client.Seed.dataWithDateAndTime
|
|
)
|
|
|
|
client.setDateDecodingStrategy(.formatted(.dateAndTime))
|
|
|
|
// WHEN
|
|
let model = try await client.request(
|
|
endpoint: endpoint,
|
|
as: TestModel.self
|
|
)
|
|
|
|
// THEN
|
|
XCTAssertNotNil(model)
|
|
XCTAssertNotNil(model.timestamp)
|
|
}
|
|
|
|
func test_request_withEndpointAndModel_whenDataDoesNotMatchModel() async throws {
|
|
// GIVEN
|
|
let url = try XCTUnwrap(try makeURLRequest(endpoint: endpoint).url)
|
|
|
|
MockURLProtocol.mockData[.init(url: url)] = .init(
|
|
status: .ok,
|
|
data: .Client.Seed.dataUnrelated
|
|
)
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
let _ = try await client.request(
|
|
endpoint: endpoint,
|
|
as: TestModel.self
|
|
)
|
|
} catch is DecodingError {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
func test_request_withEndpointAndModel_whenDateDecodingStrategyNotCorrectlySet() async throws {
|
|
// GIVEN
|
|
let url = try XCTUnwrap(try makeURLRequest(endpoint: endpoint).url)
|
|
|
|
MockURLProtocol.mockData[.init(url: url)] = .init(
|
|
status: .ok,
|
|
data: .Client.Seed.dataWithDateAndTime
|
|
)
|
|
|
|
client.setDateDecodingStrategy(.formatted(.dateOnly))
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
let _ = try await client.request(
|
|
endpoint: endpoint,
|
|
as: TestModel.self
|
|
)
|
|
} catch is DecodingError {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
func test_request_withEndpointAndModel_whenResponseCodeIsNotOK() async throws {
|
|
// GIVEN
|
|
let url = try XCTUnwrap(try makeURLRequest(endpoint: endpoint).url)
|
|
|
|
MockURLProtocol.mockData[.init(url: url)] = .init(
|
|
status: .notFound,
|
|
data: .Client.Seed.dataWithoutTimestamp
|
|
)
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
let _ = try await client.request(
|
|
endpoint: endpoint,
|
|
as: TestModel.self
|
|
)
|
|
} catch is AmiiboClientError {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
}
|