2020-07-29 23:50:30 +00:00
|
|
|
// Copyright © 2020 Metabolist. All rights reserved.
|
|
|
|
|
|
|
|
import Foundation
|
2020-08-31 01:40:58 +00:00
|
|
|
import HTTP
|
2020-07-29 23:50:30 +00:00
|
|
|
|
2020-11-09 06:22:20 +00:00
|
|
|
public final class StubbingURLProtocol: URLProtocol {
|
2020-08-31 01:40:58 +00:00
|
|
|
private static var targetsForURLs = [URL: Target]()
|
2020-09-07 04:56:18 +00:00
|
|
|
private static var stubsForURLs = [URL: HTTPStub]()
|
2020-07-29 23:50:30 +00:00
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
override public class func canInit(with task: URLSessionTask) -> Bool {
|
2020-07-29 23:50:30 +00:00
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
override public class func canInit(with request: URLRequest) -> Bool {
|
2020-07-29 23:50:30 +00:00
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
override public class func canonicalRequest(for request: URLRequest) -> URLRequest {
|
2020-07-29 23:50:30 +00:00
|
|
|
request
|
|
|
|
}
|
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
override public func startLoading() {
|
2020-07-29 23:50:30 +00:00
|
|
|
guard
|
|
|
|
let url = request.url,
|
2020-09-07 04:56:18 +00:00
|
|
|
let stub = Self.stubsForURLs[url]
|
|
|
|
?? Self.stub(request: request, target: Self.targetsForURLs[url]) else {
|
2020-09-01 07:33:49 +00:00
|
|
|
return
|
2020-07-29 23:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch stub {
|
|
|
|
case let .success((response, data)):
|
2020-09-07 04:56:18 +00:00
|
|
|
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
|
2020-07-29 23:50:30 +00:00
|
|
|
client?.urlProtocol(self, didLoad: data)
|
|
|
|
case let .failure(error):
|
|
|
|
client?.urlProtocol(self, didFailWithError: error)
|
|
|
|
}
|
2020-09-07 04:56:18 +00:00
|
|
|
|
|
|
|
client?.urlProtocolDidFinishLoading(self)
|
2020-07-29 23:50:30 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
override public func stopLoading() {}
|
|
|
|
}
|
|
|
|
|
2020-09-07 04:56:18 +00:00
|
|
|
public extension StubbingURLProtocol {
|
|
|
|
static func setStub(_ stub: HTTPStub, forURL url: URL) {
|
|
|
|
stubsForURLs[url] = stub
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 10:21:01 +00:00
|
|
|
private extension StubbingURLProtocol {
|
|
|
|
class func stub(
|
|
|
|
request: URLRequest,
|
|
|
|
target: Target? = nil,
|
|
|
|
userInfo: [String: Any] = [:]) -> HTTPStub? {
|
|
|
|
guard let url = request.url else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return (target as? Stubbing)?.stub(url: url)
|
|
|
|
}
|
2020-07-29 23:50:30 +00:00
|
|
|
}
|
2020-08-31 01:40:58 +00:00
|
|
|
|
|
|
|
extension StubbingURLProtocol: TargetProcessing {
|
2020-08-31 10:21:01 +00:00
|
|
|
public static func process(target: Target) {
|
2020-09-23 07:04:37 +00:00
|
|
|
if let url = target.urlRequest().url {
|
2020-08-31 01:40:58 +00:00
|
|
|
targetsForURLs[url] = target
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|