165 lines
4.5 KiB
Swift

//
// LocationsClientTests.swift
// LocationsTests
//
// Created by Javier Cicchelli on 10/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
//
import APICore
import XCTest
@testable import Locations
final class LocationsClientTests: XCTestCase {
// MARK: Properties
private let makeURLRequest = MakeURLRequestUseCase()
private let sessionConfiguration = {
let configuration = URLSessionConfiguration.default
configuration.protocolClasses = [MockURLProtocol.self]
return configuration
}()
private var client: LocationsClient!
private var url: URL!
private var data: Data!
// MARK: Setup
override func setUp() async throws {
client = .init(configuration: sessionConfiguration)
}
override func tearDown() async throws {
client = nil
}
// MARK: Tests
func test_request_withGetLocationsEndpoint_forLocations_whenResponseOK() async throws {
// GIVEN
let endpoint = GetLocationsEndpoint()
url = try makeURLRequest(endpoint: endpoint).url
data = .locations
MockURLProtocol.mockData[url] = MockURLResponse(
status: 200,
headers: [:],
data: data
)
// WHEN
let result = try await client.request(endpoint: endpoint, for: Locations.self)
// THEN
XCTAssertEqual(result, Locations(locations: [
.init(
name: "Amsterdam",
latitude: 52.3547498,
longitude: 4.8339215
),
.init(
name: "Mumbai",
latitude: 19.0823998,
longitude: 72.8111468
),
.init(
name: "Copenhagen",
latitude: 55.6713442,
longitude: 12.523785
),
.init(
latitude: 40.4380638,
longitude: -3.7495758
)
]))
}
func test_request_withGetLocationsEndpoint_forLocations_whenResponseClientError() async throws {
// GIVEN
let endpoint = GetLocationsEndpoint()
url = try makeURLRequest(endpoint: endpoint).url
data = .locations
MockURLProtocol.mockData[url] = MockURLResponse(
status: 404,
headers: [:],
data: data
)
// WHEN & THEN
do {
_ = try await client.request(endpoint: endpoint, for: Locations.self)
} catch LocationsClientError.statusErrorClient {
XCTAssertTrue(true)
} catch {
XCTAssertTrue(false)
}
}
func test_request_withGetLocationsEndpoint_forLocations_whenResponseServerError() async throws {
// GIVEN
let endpoint = GetLocationsEndpoint()
url = try makeURLRequest(endpoint: endpoint).url
data = .locations
MockURLProtocol.mockData[url] = MockURLResponse(
status: 500,
headers: [:],
data: data
)
// WHEN & THEN
do {
_ = try await client.request(endpoint: endpoint, for: Locations.self)
} catch LocationsClientError.statusErrorServer {
XCTAssertTrue(true)
} catch {
XCTAssertTrue(false)
}
}
func test_request_withGetLocationsEndpoint_forLocations_whenResponseUnexpectedError() async throws {
// GIVEN
let endpoint = GetLocationsEndpoint()
url = try makeURLRequest(endpoint: endpoint).url
data = .locations
MockURLProtocol.mockData[url] = MockURLResponse(
status: 302,
headers: [:],
data: data
)
// WHEN & THEN
do {
_ = try await client.request(endpoint: endpoint, for: Locations.self)
} catch LocationsClientError.statusErrorUnexpected {
XCTAssertTrue(true)
} catch {
XCTAssertTrue(false)
}
}
}
// MARK: - Models
private struct Locations: Decodable, Equatable {
public let locations: [Location]
}
// MARK: - String+Constants
private extension Data {
static let locations = "{\"locations\":[{\"name\":\"Amsterdam\",\"lat\":52.3547498,\"long\":4.8339215},{\"name\":\"Mumbai\",\"lat\":19.0823998,\"long\":72.8111468},{\"name\":\"Copenhagen\",\"lat\":55.6713442,\"long\":12.523785},{\"lat\":40.4380638,\"long\":-3.7495758}]}".data(using: .utf8)
}