53 lines
3.2 KiB
Swift
53 lines
3.2 KiB
Swift
import XCTest
|
|
@testable import Voice
|
|
|
|
private final class ChatURLProtocol: URLProtocol {
|
|
static var handler: ((URLRequest) throws -> (Int, Data))?
|
|
override class func canInit(with request: URLRequest) -> Bool { true }
|
|
override class func canonicalRequest(for request: URLRequest) -> URLRequest { request }
|
|
override func startLoading() {
|
|
do {
|
|
let (status, body) = try Self.handler!(request)
|
|
client?.urlProtocol(self, didReceive: HTTPURLResponse(url: request.url!, statusCode: status, httpVersion: nil, headerFields: nil)!, cacheStoragePolicy: .notAllowed)
|
|
client?.urlProtocol(self, didLoad: body); client?.urlProtocolDidFinishLoading(self)
|
|
} catch { client?.urlProtocol(self, didFailWithError: error) }
|
|
}
|
|
override func stopLoading() {}
|
|
}
|
|
final class ChatTransportTests: XCTestCase {
|
|
func testBearerSameOriginQueryAndRawUpload() async throws {
|
|
guard case .success(let config) = ServerConfig.parse("https://hope.example:9178") else { XCTFail(); return }
|
|
let configuration = URLSessionConfiguration.ephemeral
|
|
configuration.protocolClasses = [ChatURLProtocol.self]
|
|
let api = ChatAPI(config: config, token: "offline-test-bearer", session: URLSession(configuration: configuration))
|
|
ChatURLProtocol.handler = { request in
|
|
XCTAssertEqual(request.url?.host, "hope.example")
|
|
XCTAssertEqual(request.url?.scheme, "https")
|
|
XCTAssertEqual(request.value(forHTTPHeaderField: "Authorization"), "Bearer offline-test-bearer")
|
|
XCTAssertEqual(URLComponents(url: request.url!, resolvingAgainstBaseURL: false)?.queryItems?.first?.value, "a & b")
|
|
return (200, Data("{\"conversations\":[],\"next_cursor\":null}".utf8))
|
|
}
|
|
_ = try await api.request("api/conversations", query: [URLQueryItem(name: "q", value: "a & b")])
|
|
ChatURLProtocol.handler = { request in
|
|
XCTAssertEqual(request.httpMethod, "POST")
|
|
XCTAssertEqual(request.url?.path, "/api/attachments")
|
|
XCTAssertEqual(request.value(forHTTPHeaderField: "X-Filename"), "notes.txt")
|
|
XCTAssertEqual(request.value(forHTTPHeaderField: "Content-Type"), "text/plain")
|
|
return (201, Data("{}".utf8))
|
|
}
|
|
_ = try await api.upload(data: Data("test".utf8), filename: "notes.txt", mime: "text/plain")
|
|
api.cancel(); ChatURLProtocol.handler = nil
|
|
}
|
|
func testUnauthorizedAndRedirectStatusCannotBecomeSuccess() async throws {
|
|
guard case .success(let config) = ServerConfig.parse("https://hope.example") else { XCTFail(); return }
|
|
let configuration = URLSessionConfiguration.ephemeral; configuration.protocolClasses = [ChatURLProtocol.self]
|
|
let api = ChatAPI(config: config, token: "offline", session: URLSession(configuration: configuration))
|
|
for status in [401, 403, 302, 409] {
|
|
ChatURLProtocol.handler = { _ in (status, Data()) }
|
|
do { _ = try await api.request("api/conversations"); XCTFail("Expected rejection") }
|
|
catch ChatFailure.status(let actual) { XCTAssertEqual(actual, status) }
|
|
}
|
|
api.cancel(); ChatURLProtocol.handler = nil
|
|
}
|
|
}
|