|
|
|
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
import Quick
|
|
|
|
import Nimble
|
|
|
|
|
|
|
|
@testable import SessionUtilitiesKit
|
|
|
|
|
|
|
|
class RequestSpec: QuickSpec {
|
|
|
|
override class func spec() {
|
|
|
|
// MARK: Configuration
|
|
|
|
|
|
|
|
@TestState var dependencies: Dependencies! = Dependencies()
|
|
|
|
@TestState var urlRequest: URLRequest?
|
|
|
|
@TestState var request: Request<NoBody, TestEndpoint>!
|
|
|
|
@TestState var responseInfo: ResponseInfoType! = Network.ResponseInfo(code: 200, headers: [:])
|
|
|
|
|
|
|
|
// MARK: - a Request
|
|
|
|
describe("a Request") {
|
|
|
|
// MARK: -- is initialized with the correct default values
|
|
|
|
it("is initialized with the correct default values") {
|
|
|
|
let request: Request<NoBody, TestEndpoint> = Request(
|
|
|
|
endpoint: .test1,
|
|
|
|
target: Network.ServerTarget(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: TestEndpoint.test1,
|
|
|
|
queryParameters: [:],
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(request.method.rawValue).to(equal("GET"))
|
|
|
|
expect(request.headers).to(equal([:]))
|
|
|
|
expect(request.body).to(beNil())
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: -- when generating a URLRequest
|
|
|
|
context("when generating a URLRequest") {
|
|
|
|
// MARK: ---- generates the request correctly
|
|
|
|
it("generates the request correctly") {
|
|
|
|
request = Request<NoBody, TestEndpoint>(
|
|
|
|
method: .post,
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
queryParameters: [:],
|
|
|
|
headers: [
|
|
|
|
"TestCustomHeader": "TestCustom",
|
|
|
|
HTTPHeader.testHeader: "Test"
|
|
|
|
],
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: nil
|
|
|
|
)
|
|
|
|
urlRequest = try? request.generateUrlRequest(using: dependencies)
|
|
|
|
|
|
|
|
expect(urlRequest?.url?.absoluteString).to(equal("testServer/test1"))
|
|
|
|
expect(urlRequest?.httpMethod).to(equal("POST"))
|
|
|
|
expect(urlRequest?.allHTTPHeaderFields).to(equal([
|
|
|
|
"TestCustomHeader": "TestCustom",
|
|
|
|
HTTPHeader.testHeader: "Test"
|
|
|
|
]))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- sets all the values correctly
|
|
|
|
it("sets all the values correctly") {
|
|
|
|
let request: Request<NoBody, TestEndpoint> = Request(
|
|
|
|
method: .delete,
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
headers: [
|
|
|
|
.authorization: "test"
|
|
|
|
],
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
let urlRequest: URLRequest? = try? request.generateUrlRequest(using: dependencies)
|
|
|
|
|
|
|
|
expect(urlRequest?.httpMethod).to(equal("DELETE"))
|
|
|
|
expect(urlRequest?.allHTTPHeaderFields).to(equal(["Authorization": "test"]))
|
|
|
|
expect(urlRequest?.httpBody).to(beNil())
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- throws an error if the URL is invalid
|
|
|
|
it("throws an error if the URL is invalid") {
|
|
|
|
let request: Request<NoBody, TestEndpoint> = Request(
|
|
|
|
server: "ftp:// test Server",
|
|
|
|
endpoint: .testParams("test", 123),
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
|
|
|
|
expect {
|
|
|
|
try request.generateUrlRequest(using: dependencies)
|
|
|
|
}
|
|
|
|
.to(throwError(NetworkError.invalidURL))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- with a base64 string body
|
|
|
|
context("with a base64 string body") {
|
|
|
|
// MARK: ------ successfully encodes the body
|
|
|
|
it("successfully encodes the body") {
|
|
|
|
let request: Request<String, TestEndpoint> = Request(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: "TestMessage".data(using: .utf8)!.base64EncodedString()
|
|
|
|
)
|
|
|
|
|
|
|
|
let urlRequest: URLRequest? = try? request.generateUrlRequest(using: dependencies)
|
|
|
|
let requestBody: Data? = Data(base64Encoded: urlRequest?.httpBody?.base64EncodedString() ?? "")
|
|
|
|
let requestBodyString: String? = String(data: requestBody ?? Data(), encoding: .utf8)
|
|
|
|
|
|
|
|
expect(requestBodyString).to(equal("TestMessage"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ------ throws an error if the body is not base64 encoded
|
|
|
|
it("throws an error if the body is not base64 encoded") {
|
|
|
|
let request: Request<String, TestEndpoint> = Request(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: "TestMessage"
|
|
|
|
)
|
|
|
|
|
|
|
|
expect {
|
|
|
|
try request.generateUrlRequest(using: dependencies)
|
|
|
|
}
|
|
|
|
.to(throwError(NetworkError.parsingFailed))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- with a byte body
|
|
|
|
context("with a byte body") {
|
|
|
|
// MARK: ------ successfully encodes the body
|
|
|
|
it("successfully encodes the body") {
|
|
|
|
let request: Request<[UInt8], TestEndpoint> = Request(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: [1, 2, 3]
|
|
|
|
)
|
|
|
|
|
|
|
|
let urlRequest: URLRequest? = try? request.generateUrlRequest(using: dependencies)
|
|
|
|
|
|
|
|
expect(urlRequest?.httpBody?.bytes).to(equal([1, 2, 3]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- with a JSON body
|
|
|
|
context("with a JSON body") {
|
|
|
|
// MARK: ------ successfully encodes the body
|
|
|
|
it("successfully encodes the body") {
|
|
|
|
let request: Request<TestType, TestEndpoint> = Request(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: TestType(stringValue: "test")
|
|
|
|
)
|
|
|
|
|
|
|
|
let urlRequest: URLRequest? = try? request.generateUrlRequest(using: dependencies)
|
|
|
|
let requestBody: TestType? = try? JSONDecoder(using: dependencies).decode(
|
|
|
|
TestType.self,
|
|
|
|
from: urlRequest?.httpBody ?? Data()
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(requestBody).to(equal(TestType(stringValue: "test")))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ------ successfully encodes no body
|
|
|
|
it("successfully encodes no body") {
|
|
|
|
let request: Request<NoBody, TestEndpoint> = Request(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: .test1,
|
|
|
|
x25519PublicKey: "",
|
|
|
|
body: nil
|
|
|
|
)
|
|
|
|
|
|
|
|
expect {
|
|
|
|
try request.generateUrlRequest(using: dependencies)
|
|
|
|
}.toNot(throwError())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - a HTTP ServerTarget
|
|
|
|
describe("a HTTP ServerTarget") {
|
|
|
|
// MARK: ---- adds a leading forward slash to the endpoint path
|
|
|
|
it("adds a leading forward slash to the endpoint path") {
|
|
|
|
let target: Network.ServerTarget = Network.ServerTarget(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: TestEndpoint.test1,
|
|
|
|
queryParameters: [:],
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(target.urlPathAndParamsString).to(equal("/test1"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- creates a valid URL with no query parameters
|
|
|
|
it("creates a valid URL with no query parameters") {
|
|
|
|
let target: Network.ServerTarget = Network.ServerTarget(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: TestEndpoint.test1,
|
|
|
|
queryParameters: [:],
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(target.urlPathAndParamsString).to(equal("/test1"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: ---- creates a valid URL when query parameters are provided
|
|
|
|
it("creates a valid URL when query parameters are provided") {
|
|
|
|
let target: Network.ServerTarget = Network.ServerTarget(
|
|
|
|
server: "testServer",
|
|
|
|
endpoint: TestEndpoint.test1,
|
|
|
|
queryParameters: [
|
|
|
|
.testParam: "123"
|
|
|
|
],
|
|
|
|
x25519PublicKey: ""
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(target.urlPathAndParamsString).to(equal("/test1?testParam=123"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Test Types
|
|
|
|
|
|
|
|
fileprivate extension HTTPHeader {
|
|
|
|
static let testHeader: HTTPHeader = "TestHeader"
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate extension HTTPQueryParam {
|
|
|
|
static let testParam: HTTPQueryParam = "testParam"
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate enum TestEndpoint: EndpointType {
|
|
|
|
case test1
|
|
|
|
case testParams(String, Int)
|
|
|
|
|
|
|
|
static var name: String { "TestEndpoint" }
|
|
|
|
static var batchRequestVariant: Network.BatchRequest.Child.Variant { .storageServer }
|
|
|
|
static var excludedSubRequestHeaders: [HTTPHeader] { [] }
|
|
|
|
|
|
|
|
var path: String {
|
|
|
|
switch self {
|
|
|
|
case .test1: return "test1"
|
|
|
|
case .testParams(let str, let int): return "testParams/\(str)/int/\(int)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate struct TestType: Codable, Equatable {
|
|
|
|
let stringValue: String
|
|
|
|
}
|