Files
hyungi_document_server/clients/ds-app/Tests/AITests/MockURLProtocol.swift
T

87 lines
3.2 KiB
Swift

import Foundation
/// URLProtocol URLSession canned / , .
/// 0 LocalMLX probe/complete call-shape .
final class MockURLProtocol: URLProtocol {
/// (request) -> (response, body). throw URLSession .
nonisolated(unsafe) static var handler: (@Sendable (URLRequest) throws -> (HTTPURLResponse, Data))?
/// (body ) .
nonisolated(unsafe) static var recorder = RequestRecorder()
static func reset() {
handler = nil
recorder = RequestRecorder()
}
override class func canInit(with request: URLRequest) -> Bool { true }
override class func canonicalRequest(for request: URLRequest) -> URLRequest { request }
override func startLoading() {
Self.recorder.record(request)
guard let handler = Self.handler else {
client?.urlProtocol(self, didFailWithError: URLError(.unsupportedURL))
return
}
do {
let (response, data) = try handler(request)
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
client?.urlProtocol(self, didLoad: data)
client?.urlProtocolDidFinishLoading(self)
} catch {
client?.urlProtocol(self, didFailWithError: error)
}
}
override func stopLoading() {}
// MARK: helpers
static func session() -> URLSession {
let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [MockURLProtocol.self]
return URLSession(configuration: config)
}
static func ok(_ url: URL, json: Data) -> (HTTPURLResponse, Data) {
(HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)!, json)
}
static func status(_ url: URL, _ code: Int, body: String = "") -> (HTTPURLResponse, Data) {
(HTTPURLResponse(url: url, statusCode: code, httpVersion: nil, headerFields: nil)!, Data(body.utf8))
}
}
/// (body httpBody httpBodyStream URLProtocol stream ).
final class RequestRecorder: @unchecked Sendable {
private(set) var lastURL: URL?
private(set) var lastMethod: String?
private(set) var lastBody: Data?
private(set) var callCount = 0
func record(_ request: URLRequest) {
callCount += 1
lastURL = request.url
lastMethod = request.httpMethod
lastBody = request.bodyData
}
}
extension URLRequest {
/// URLProtocol body httpBody nil httpBodyStream .
var bodyData: Data? {
if let httpBody { return httpBody }
guard let stream = httpBodyStream else { return nil }
stream.open()
defer { stream.close() }
var data = Data()
let bufSize = 8192
var buffer = [UInt8](repeating: 0, count: bufSize)
while stream.hasBytesAvailable {
let read = stream.read(&buffer, maxLength: bufSize)
if read <= 0 { break }
data.append(buffer, count: read)
}
return data
}
}