88 lines
2.8 KiB
Swift
88 lines
2.8 KiB
Swift
//
|
|
// TestTransport.swift
|
|
// AccountTests
|
|
//
|
|
// Created by Maurice Parker on 5/4/19.
|
|
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import RSWeb
|
|
import XCTest
|
|
|
|
protocol TestTransportMockResponseProviding: AnyObject {
|
|
func mockResponseFileUrl(for components: URLComponents) -> URL?
|
|
}
|
|
|
|
final class TestTransport: Transport {
|
|
|
|
enum TestTransportError: String, Error {
|
|
case invalidState = "The test wasn't set up correctly."
|
|
}
|
|
|
|
var testFiles = [String: String]()
|
|
var testStatusCodes = [String: Int]()
|
|
|
|
weak var mockResponseFileUrlProvider: TestTransportMockResponseProviding?
|
|
|
|
private func httpResponse(for request: URLRequest, statusCode: Int = 200) -> HTTPURLResponse {
|
|
guard let url = request.url else {
|
|
fatalError("Attempting to mock a http response for a request without a URL \(request).")
|
|
}
|
|
return HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: "HTTP/1.1", headerFields: nil)!
|
|
}
|
|
|
|
func cancelAll() { }
|
|
|
|
func send(request: URLRequest, completion: @escaping (Result<(HTTPURLResponse, Data?), Error>) -> Void) {
|
|
|
|
guard let url = request.url, let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
|
|
completion(.failure(TestTransportError.invalidState))
|
|
return
|
|
}
|
|
|
|
let urlString = url.absoluteString
|
|
let response = httpResponse(for: request, statusCode: testStatusCodes[urlString] ?? 200)
|
|
let testFileURL: URL
|
|
|
|
if let provider = mockResponseFileUrlProvider {
|
|
guard let providerUrl = provider.mockResponseFileUrl(for: components) else {
|
|
XCTFail("Test behaviour undefined. Mock provider failed to provide non-nil URL for \(components).")
|
|
return
|
|
}
|
|
testFileURL = providerUrl
|
|
|
|
} else if let testKeyAndFileName = testFiles.first(where: { urlString.contains($0.key) }) {
|
|
testFileURL = Bundle.module.resourceURL!.appendingPathComponent(testKeyAndFileName.value)
|
|
|
|
} else {
|
|
// XCTFail("Missing mock response for: \(urlString)")
|
|
print("***\nWARNING: \(self) missing mock response for:\n\(urlString)\n***")
|
|
DispatchQueue.global(qos: .background).async {
|
|
completion(.success((response, nil)))
|
|
}
|
|
return
|
|
}
|
|
|
|
do {
|
|
let data = try Data(contentsOf: testFileURL)
|
|
DispatchQueue.global(qos: .background).async {
|
|
completion(.success((response, data)))
|
|
}
|
|
} catch {
|
|
XCTFail("Unable to read file at \(testFileURL) because \(error).")
|
|
DispatchQueue.global(qos: .background).async {
|
|
completion(.failure(error))
|
|
}
|
|
}
|
|
}
|
|
|
|
func send(request: URLRequest, method: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
|
fatalError("Unimplemented.")
|
|
}
|
|
|
|
func send(request: URLRequest, method: String, payload: Data, completion: @escaping (Result<(HTTPURLResponse, Data?), Error>) -> Void) {
|
|
fatalError("Unimplemented.")
|
|
}
|
|
}
|