mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			387 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			387 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import Foundation
 | |
| import PromiseKit
 | |
| import SessionSnodeKit
 | |
| import SessionUtilitiesKit
 | |
| 
 | |
| import Quick
 | |
| import Nimble
 | |
| 
 | |
| @testable import SessionMessagingKit
 | |
| import AVFoundation
 | |
| 
 | |
| class BatchRequestInfoSpec: QuickSpec {
 | |
|     struct TestType: Codable, Equatable {
 | |
|         let stringValue: String
 | |
|     }
 | |
|     
 | |
|     // MARK: - Spec
 | |
| 
 | |
|     override func spec() {
 | |
|         // MARK: - BatchSubRequest
 | |
|         
 | |
|         describe("a BatchSubRequest") {
 | |
|             var subRequest: OpenGroupAPI.BatchSubRequest!
 | |
|             
 | |
|             context("when initializing") {
 | |
|                 it("sets the headers to nil if there aren't any") {
 | |
|                     subRequest = OpenGroupAPI.BatchSubRequest(
 | |
|                         request: Request<NoBody, OpenGroupAPI.Endpoint>(
 | |
|                             server: "testServer",
 | |
|                             endpoint: .batch
 | |
|                         )
 | |
|                     )
 | |
|                     
 | |
|                     expect(subRequest.headers).to(beNil())
 | |
|                 }
 | |
|                 
 | |
|                 it("converts the headers to HTTP headers") {
 | |
|                     subRequest = OpenGroupAPI.BatchSubRequest(
 | |
|                         request: Request<NoBody, OpenGroupAPI.Endpoint>(
 | |
|                             method: .get,
 | |
|                             server: "testServer",
 | |
|                             endpoint: .batch,
 | |
|                             queryParameters: [:],
 | |
|                             headers: [.authorization: "testAuth"],
 | |
|                             body: nil
 | |
|                         )
 | |
|                     )
 | |
|                     
 | |
|                     expect(subRequest.headers).to(equal(["Authorization": "testAuth"]))
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             context("when encoding") {
 | |
|                 it("successfully encodes a string body") {
 | |
|                     subRequest = OpenGroupAPI.BatchSubRequest(
 | |
|                         request: Request<String, OpenGroupAPI.Endpoint>(
 | |
|                             method: .get,
 | |
|                             server: "testServer",
 | |
|                             endpoint: .batch,
 | |
|                             queryParameters: [:],
 | |
|                             headers: [:],
 | |
|                             body: "testBody"
 | |
|                         )
 | |
|                     )
 | |
|                     let subRequestData: Data = try! JSONEncoder().encode(subRequest)
 | |
|                     let subRequestString: String? = String(data: subRequestData, encoding: .utf8)
 | |
|                     
 | |
|                     expect(subRequestString)
 | |
|                         .to(equal("{\"path\":\"\\/batch\",\"method\":\"GET\",\"b64\":\"testBody\"}"))
 | |
|                 }
 | |
|                 
 | |
|                 it("successfully encodes a byte body") {
 | |
|                     subRequest = OpenGroupAPI.BatchSubRequest(
 | |
|                         request: Request<[UInt8], OpenGroupAPI.Endpoint>(
 | |
|                             method: .get,
 | |
|                             server: "testServer",
 | |
|                             endpoint: .batch,
 | |
|                             queryParameters: [:],
 | |
|                             headers: [:],
 | |
|                             body: [1, 2, 3]
 | |
|                         )
 | |
|                     )
 | |
|                     let subRequestData: Data = try! JSONEncoder().encode(subRequest)
 | |
|                     let subRequestString: String? = String(data: subRequestData, encoding: .utf8)
 | |
|                     
 | |
|                     expect(subRequestString)
 | |
|                         .to(equal("{\"path\":\"\\/batch\",\"method\":\"GET\",\"bytes\":[1,2,3]}"))
 | |
|                 }
 | |
|                 
 | |
|                 it("successfully encodes a JSON body") {
 | |
|                     subRequest = OpenGroupAPI.BatchSubRequest(
 | |
|                         request: Request<TestType, OpenGroupAPI.Endpoint>(
 | |
|                             method: .get,
 | |
|                             server: "testServer",
 | |
|                             endpoint: .batch,
 | |
|                             queryParameters: [:],
 | |
|                             headers: [:],
 | |
|                             body: TestType(stringValue: "testValue")
 | |
|                         )
 | |
|                     )
 | |
|                     let subRequestData: Data = try! JSONEncoder().encode(subRequest)
 | |
|                     let subRequestString: String? = String(data: subRequestData, encoding: .utf8)
 | |
|                     
 | |
|                     expect(subRequestString)
 | |
|                         .to(equal("{\"path\":\"\\/batch\",\"method\":\"GET\",\"json\":{\"stringValue\":\"testValue\"}}"))
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // MARK: - BatchSubResponse<T>
 | |
|         
 | |
|         describe("a BatchSubResponse<T>") {
 | |
|             context("when decoding") {
 | |
|                 it("decodes correctly") {
 | |
|                     let jsonString: String = """
 | |
|                     {
 | |
|                         "code": 200,
 | |
|                         "headers": {
 | |
|                             "testKey": "testValue"
 | |
|                         },
 | |
|                         "body": {
 | |
|                             "stringValue": "testValue"
 | |
|                         }
 | |
|                     }
 | |
|                     """
 | |
|                     let subResponse: OpenGroupAPI.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
 | |
|                         OpenGroupAPI.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: OpenGroupAPI.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
 | |
|                         OpenGroupAPI.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: OpenGroupAPI.BatchSubResponse<TestType>? = try? JSONDecoder().decode(
 | |
|                         OpenGroupAPI.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: OpenGroupAPI.BatchSubResponse<TestType?>? = try? JSONDecoder().decode(
 | |
|                         OpenGroupAPI.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: OpenGroupAPI.BatchSubResponse<NoResponse>? = try? JSONDecoder().decode(
 | |
|                         OpenGroupAPI.BatchSubResponse<NoResponse>.self,
 | |
|                         from: jsonString.data(using: .utf8)!
 | |
|                     )
 | |
|                     
 | |
|                     expect(subResponse).toNot(beNil())
 | |
|                     expect(subResponse?.body).to(beNil())
 | |
|                     expect(subResponse?.failedToParseBody).to(beFalse())
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // MARK: - BatchRequestInfo<T, R>
 | |
|         
 | |
|         describe("a BatchRequestInfo<T, R>") {
 | |
|             var request: Request<TestType, OpenGroupAPI.Endpoint>!
 | |
|             
 | |
|             beforeEach {
 | |
|                 request = Request(
 | |
|                     method: .get,
 | |
|                     server: "testServer",
 | |
|                     endpoint: .batch,
 | |
|                     queryParameters: [:],
 | |
|                     headers: [:],
 | |
|                     body: TestType(stringValue: "testValue")
 | |
|                 )
 | |
|             }
 | |
|             
 | |
|             it("initializes correctly when given a request") {
 | |
|                 let requestInfo: OpenGroupAPI.BatchRequestInfo<TestType> = OpenGroupAPI.BatchRequestInfo(
 | |
|                     request: request
 | |
|                 )
 | |
|                 
 | |
|                 expect(requestInfo.request).to(equal(request))
 | |
|                 expect(requestInfo.responseType == OpenGroupAPI.BatchSubResponse<NoResponse>.self).to(beTrue())
 | |
|             }
 | |
|             
 | |
|             it("initializes correctly when given a request and a response type") {
 | |
|                 let requestInfo: OpenGroupAPI.BatchRequestInfo<TestType> = OpenGroupAPI.BatchRequestInfo(
 | |
|                     request: request,
 | |
|                     responseType: TestType.self
 | |
|                 )
 | |
|                 
 | |
|                 expect(requestInfo.request).to(equal(request))
 | |
|                 expect(requestInfo.responseType == OpenGroupAPI.BatchSubResponse<TestType>.self).to(beTrue())
 | |
|             }
 | |
|             
 | |
|             it("exposes the endpoint correctly") {
 | |
|                 let requestInfo: OpenGroupAPI.BatchRequestInfo<TestType> = OpenGroupAPI.BatchRequestInfo(
 | |
|                     request: request
 | |
|                 )
 | |
|                 
 | |
|                 expect(requestInfo.endpoint.path).to(equal(request.endpoint.path))
 | |
|             }
 | |
|             
 | |
|             it("generates a sub request correctly") {
 | |
|                 let requestInfo: OpenGroupAPI.BatchRequestInfo<TestType> = OpenGroupAPI.BatchRequestInfo(
 | |
|                     request: request
 | |
|                 )
 | |
|                 let subRequest: OpenGroupAPI.BatchSubRequest = requestInfo.toSubRequest()
 | |
|                 
 | |
|                 expect(subRequest.method).to(equal(request.method))
 | |
|                 expect(subRequest.path).to(equal(request.urlPathAndParamsString))
 | |
|                 expect(subRequest.headers).to(beNil())
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // 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: - --Promise
 | |
|         
 | |
|         describe("an (OnionRequestResponseInfoType, Data?) Promise") {
 | |
|             var responseInfo: OnionRequestResponseInfoType!
 | |
|             var capabilities: OpenGroupAPI.Capabilities!
 | |
|             var pinnedMessage: OpenGroupAPI.PinnedMessage!
 | |
|             var data: Data!
 | |
|             
 | |
|             beforeEach {
 | |
|                 responseInfo = OnionRequestAPI.ResponseInfo(code: 200, headers: [:])
 | |
|                 capabilities = OpenGroupAPI.Capabilities(capabilities: [], missing: nil)
 | |
|                 pinnedMessage = OpenGroupAPI.PinnedMessage(id: 1, pinnedAt: 123, pinnedBy: "test")
 | |
|                 data = """
 | |
|                 [\([
 | |
|                     try! JSONEncoder().encode(
 | |
|                         OpenGroupAPI.BatchSubResponse(
 | |
|                             code: 200,
 | |
|                             headers: [:],
 | |
|                             body: capabilities,
 | |
|                             failedToParseBody: false
 | |
|                         )
 | |
|                     ),
 | |
|                     try! JSONEncoder().encode(
 | |
|                         OpenGroupAPI.BatchSubResponse(
 | |
|                             code: 200,
 | |
|                             headers: [:],
 | |
|                             body: pinnedMessage,
 | |
|                             failedToParseBody: false
 | |
|                         )
 | |
|                     )
 | |
|                 ]
 | |
|                 .map { String(data: $0, encoding: .utf8)! }
 | |
|                 .joined(separator: ","))]
 | |
|                 """.data(using: .utf8)!
 | |
|             }
 | |
|             
 | |
|             it("decodes valid data correctly") {
 | |
|                 let result = Promise.value((responseInfo, data))
 | |
|                     .decoded(as: [
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.Capabilities>.self,
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.PinnedMessage>.self
 | |
|                     ])
 | |
|                 
 | |
|                 expect(result.value).toNot(beNil())
 | |
|                 expect((result.value?[0].1 as? OpenGroupAPI.BatchSubResponse<OpenGroupAPI.Capabilities>)?.body)
 | |
|                     .to(equal(capabilities))
 | |
|                 expect((result.value?[1].1 as? OpenGroupAPI.BatchSubResponse<OpenGroupAPI.PinnedMessage>)?.body)
 | |
|                     .to(equal(pinnedMessage))
 | |
|             }
 | |
|             
 | |
|             it("fails if there is no data") {
 | |
|                 let result = Promise.value((responseInfo, nil)).decoded(as: [])
 | |
|                 
 | |
|                 expect(result.error?.localizedDescription).to(equal(HTTP.Error.parsingFailed.localizedDescription))
 | |
|             }
 | |
|             
 | |
|             it("fails if the data is not JSON") {
 | |
|                 let result = Promise.value((responseInfo, Data([1, 2, 3]))).decoded(as: [])
 | |
|                 
 | |
|                 expect(result.error?.localizedDescription).to(equal(HTTP.Error.parsingFailed.localizedDescription))
 | |
|             }
 | |
|             
 | |
|             it("fails if the data is not a JSON array") {
 | |
|                 let result = Promise.value((responseInfo, "{}".data(using: .utf8))).decoded(as: [])
 | |
|                 
 | |
|                 expect(result.error?.localizedDescription).to(equal(HTTP.Error.parsingFailed.localizedDescription))
 | |
|             }
 | |
|             
 | |
|             it("fails if the JSON array does not have the same number of items as the expected types") {
 | |
|                 let result = Promise.value((responseInfo, data))
 | |
|                     .decoded(as: [
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.Capabilities>.self,
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.PinnedMessage>.self,
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.PinnedMessage>.self
 | |
|                     ])
 | |
|                 
 | |
|                 expect(result.error?.localizedDescription).to(equal(HTTP.Error.parsingFailed.localizedDescription))
 | |
|             }
 | |
|             
 | |
|             it("fails if one of the JSON array values fails to decode") {
 | |
|                 data = """
 | |
|                 [\([
 | |
|                     try! JSONEncoder().encode(
 | |
|                         OpenGroupAPI.BatchSubResponse(
 | |
|                             code: 200,
 | |
|                             headers: [:],
 | |
|                             body: capabilities,
 | |
|                             failedToParseBody: false
 | |
|                         )
 | |
|                     )
 | |
|                 ]
 | |
|                 .map { String(data: $0, encoding: .utf8)! }
 | |
|                 .joined(separator: ",")),{"test": "test"}]
 | |
|                 """.data(using: .utf8)!
 | |
|                 let result = Promise.value((responseInfo, data))
 | |
|                     .decoded(as: [
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.Capabilities>.self,
 | |
|                         OpenGroupAPI.BatchSubResponse<OpenGroupAPI.PinnedMessage>.self
 | |
|                     ])
 | |
|                 
 | |
|                 expect(result.error?.localizedDescription).to(equal(HTTP.Error.parsingFailed.localizedDescription))
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |