This PR contains the work that implements the Locations service, which is used to retrieve location data from a remote server. To give further details on what was done: - [x] created the `APICore` and `Locations` libraries into the **Libraries** package; - [x] defined the `Endpoint` and `Client` protocols; - [x] implemented the `MakeURLRequestUseCase` use case; - [x] implemented the `MockURLProtocol` protocol and the `MockURLResponse` models; - [x] implemented the `Location` model; - [x] implemented the `GetLocationsEndpoint` endpoint; - [x] implemented the `LocationsClient` client; - [x] implemented the `LocationsService` service. Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Reviewed-on: rock-n-code/deep-linking-assignment#4
153 lines
3.8 KiB
Swift
153 lines
3.8 KiB
Swift
//
|
|
// LocationsServiceTests.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 LocationsServiceTests: XCTestCase {
|
|
|
|
// MARK: Properties
|
|
|
|
private let makeURLRequest = MakeURLRequestUseCase()
|
|
private let sessionConfiguration = {
|
|
let configuration = URLSessionConfiguration.default
|
|
|
|
configuration.protocolClasses = [MockURLProtocol.self]
|
|
|
|
return configuration
|
|
}()
|
|
|
|
private var service: LocationsService!
|
|
private var url: URL!
|
|
private var data: Data!
|
|
|
|
// MARK: Setup
|
|
|
|
override func setUp() async throws {
|
|
service = .init(configuration: sessionConfiguration)
|
|
}
|
|
|
|
override func tearDown() async throws {
|
|
service = nil
|
|
}
|
|
|
|
// MARK: Tests
|
|
|
|
func test_getLocations_whenResponseOK() async throws {
|
|
// GIVEN
|
|
let endpoint = GetLocationsEndpoint()
|
|
|
|
url = try makeURLRequest(endpoint: endpoint).url
|
|
data = .Responses.locations
|
|
|
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
|
status: 200,
|
|
headers: [:],
|
|
data: data
|
|
)
|
|
|
|
// WHEN
|
|
let result = try await service.getLocations()
|
|
|
|
// THEN
|
|
XCTAssertEqual(result, [
|
|
.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_getLocations_whenResponseClientError() async throws {
|
|
// GIVEN
|
|
let endpoint = GetLocationsEndpoint()
|
|
|
|
url = try makeURLRequest(endpoint: endpoint).url
|
|
data = .Responses.locations
|
|
|
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
|
status: 404,
|
|
headers: [:],
|
|
data: data
|
|
)
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
_ = try await service.getLocations()
|
|
} catch LocationsClientError.statusErrorClient {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
func test_getLocations_whenResponseServerError() async throws {
|
|
// GIVEN
|
|
let endpoint = GetLocationsEndpoint()
|
|
|
|
url = try makeURLRequest(endpoint: endpoint).url
|
|
data = .Responses.locations
|
|
|
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
|
status: 500,
|
|
headers: [:],
|
|
data: data
|
|
)
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
_ = try await service.getLocations()
|
|
} catch LocationsClientError.statusErrorServer {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
func test_getLocations_whenResponseUnexpectedError() async throws {
|
|
// GIVEN
|
|
let endpoint = GetLocationsEndpoint()
|
|
|
|
url = try makeURLRequest(endpoint: endpoint).url
|
|
data = .Responses.locations
|
|
|
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
|
status: 302,
|
|
headers: [:],
|
|
data: data
|
|
)
|
|
|
|
// WHEN & THEN
|
|
do {
|
|
_ = try await service.getLocations()
|
|
} catch LocationsClientError.statusErrorUnexpected {
|
|
XCTAssertTrue(true)
|
|
} catch {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
|
|
}
|