session-ios/SessionUtilitiesKitTests/Networking/BatchResponseSpec.swift
Morgan Pretty e3a080dd5b Updated to the latest version of the libSession-utl (contacts size)
Fixed some broken unit tests (still some broken ones)
2022-12-21 18:29:57 +11:00

283 lines
11 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import Combine
import Quick
import Nimble
@testable import SessionUtilitiesKit
class BatchResponseSpec: QuickSpec {
struct TestType: Codable, Equatable {
let stringValue: String
}
struct TestType2: Codable, Equatable {
let intValue: Int
let stringValue2: String
}
// MARK: - Spec
override func spec() {
// MARK: - HTTP.BatchSubResponse<T>
describe("an HTTP.BatchSubResponse<T>") {
context("when decoding") {
it("decodes correctly") {
let jsonString: String = """
{
"code": 200,
"headers": {
"testKey": "testValue"
},
"body": {
"stringValue": "testValue"
}
}
"""
let subResponse: HTTP.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
HTTP.BatchSubResponse<TestType>.self,
from: jsonString.data(using: .utf8)!
)
expect(subResponse).toNot(beNil())
expect(subResponse?.body).toNot(beNil())
}
it("decodes with invalid body data") {
let jsonString: String = """
{
"code": 200,
"headers": {
"testKey": "testValue"
},
"body": "Hello!!!"
}
"""
let subResponse: HTTP.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
HTTP.BatchSubResponse<TestType>.self,
from: jsonString.data(using: .utf8)!
)
expect(subResponse).toNot(beNil())
}
it("flags invalid body data as invalid") {
let jsonString: String = """
{
"code": 200,
"headers": {
"testKey": "testValue"
},
"body": "Hello!!!"
}
"""
let subResponse: HTTP.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
HTTP.BatchSubResponse<TestType>.self,
from: jsonString.data(using: .utf8)!
)
expect(subResponse).toNot(beNil())
expect(subResponse?.body).to(beNil())
expect(subResponse?.failedToParseBody).to(beTrue())
}
it("does not flag a missing or invalid optional body as invalid") {
let jsonString: String = """
{
"code": 200,
"headers": {
"testKey": "testValue"
},
}
"""
let subResponse: HTTP.BatchSubResponse<TestType?>? = try? JSONDecoder().decode(
HTTP.BatchSubResponse<TestType?>.self,
from: jsonString.data(using: .utf8)!
)
expect(subResponse).toNot(beNil())
expect(subResponse?.body).to(beNil())
expect(subResponse?.failedToParseBody).to(beFalse())
}
it("does not flag a NoResponse body as invalid") {
let jsonString: String = """
{
"code": 200,
"headers": {
"testKey": "testValue"
},
}
"""
let subResponse: HTTP.BatchSubResponse<NoResponse>? = try? JSONDecoder().decode(
HTTP.BatchSubResponse<NoResponse>.self,
from: jsonString.data(using: .utf8)!
)
expect(subResponse).toNot(beNil())
expect(subResponse?.body).to(beNil())
expect(subResponse?.failedToParseBody).to(beFalse())
}
}
}
// MARK: - Convenience
// MARK: --Decodable
describe("a Decodable") {
it("decodes correctly") {
let jsonData: Data = "{\"stringValue\":\"testValue\"}".data(using: .utf8)!
let result: TestType? = try? TestType.decoded(from: jsonData)
expect(result).to(equal(TestType(stringValue: "testValue")))
}
}
// MARK: - --Combine
describe("a (ResponseInfoType, Data?) Publisher") {
var responseInfo: ResponseInfoType!
var testType: TestType!
var testType2: TestType2!
var data: Data!
beforeEach {
responseInfo = HTTP.ResponseInfo(code: 200, headers: [:])
testType = TestType(stringValue: "test1")
testType2 = TestType2(intValue: 123, stringValue2: "test2")
data = """
[\([
try! JSONEncoder().encode(
HTTP.BatchSubResponse(
code: 200,
headers: [:],
body: testType,
failedToParseBody: false
)
),
try! JSONEncoder().encode(
HTTP.BatchSubResponse(
code: 200,
headers: [:],
body: testType2,
failedToParseBody: false
)
)
]
.map { String(data: $0, encoding: .utf8)! }
.joined(separator: ","))]
""".data(using: .utf8)!
}
it("decodes valid data correctly") {
var result: HTTP.BatchResponse?
Just((responseInfo, data))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [
HTTP.BatchSubResponse<TestType>.self,
HTTP.BatchSubResponse<TestType2>.self
])
.sinkUntilComplete(
receiveValue: { result = $0 }
)
expect(result).toNot(beNil())
expect((result?.responses[0] as? HTTP.BatchSubResponse<TestType>)?.body)
.to(equal(testType))
expect((result?.responses[1] as? HTTP.BatchSubResponse<TestType2>)?.body)
.to(equal(testType2))
}
it("fails if there is no data") {
var error: Error?
Just((responseInfo, nil))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [])
.mapError { error.setting(to: $0) }
.sinkUntilComplete()
expect(error?.localizedDescription)
.to(equal(HTTPError.parsingFailed.localizedDescription))
}
it("fails if the data is not JSON") {
var error: Error?
Just((responseInfo, Data([1, 2, 3])))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [])
.mapError { error.setting(to: $0) }
.sinkUntilComplete()
expect(error?.localizedDescription)
.to(equal(HTTPError.parsingFailed.localizedDescription))
}
it("fails if the data is not a JSON array") {
var error: Error?
Just((responseInfo, "{}".data(using: .utf8)))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [])
.mapError { error.setting(to: $0) }
.sinkUntilComplete()
expect(error?.localizedDescription)
.to(equal(HTTPError.parsingFailed.localizedDescription))
}
it("fails if the JSON array does not have the same number of items as the expected types") {
var error: Error?
Just((responseInfo, data))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [
HTTP.BatchSubResponse<TestType>.self,
HTTP.BatchSubResponse<TestType2>.self,
HTTP.BatchSubResponse<TestType2>.self
])
.mapError { error.setting(to: $0) }
.sinkUntilComplete()
expect(error?.localizedDescription)
.to(equal(HTTPError.parsingFailed.localizedDescription))
}
it("fails if one of the JSON array values fails to decode") {
data = """
[\([
try! JSONEncoder().encode(
HTTP.BatchSubResponse(
code: 200,
headers: [:],
body: testType,
failedToParseBody: false
)
)
]
.map { String(data: $0, encoding: .utf8)! }
.joined(separator: ",")),{"test": "test"}]
""".data(using: .utf8)!
var error: Error?
Just((responseInfo, data))
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
.decoded(as: [
HTTP.BatchSubResponse<TestType>.self,
HTTP.BatchSubResponse<TestType2>.self
])
.mapError { error.setting(to: $0) }
.sinkUntilComplete()
expect(error?.localizedDescription)
.to(equal(HTTPError.parsingFailed.localizedDescription))
}
}
}
}