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.
		
		
		
		
		
			
		
			
				
	
	
		
			307 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			307 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import Foundation
 | |
| 
 | |
| import Quick
 | |
| import Nimble
 | |
| import SessionUtilitiesKit
 | |
| 
 | |
| @testable import SessionMessagingKit
 | |
| 
 | |
| class SOGSMessageSpec: QuickSpec {
 | |
|     override class func spec() {
 | |
|         // MARK: Configuration
 | |
|         
 | |
|         @TestState var messageJson: String! = """
 | |
|         {
 | |
|             "id": 123,
 | |
|             "session_id": "05\(TestConstants.publicKey)",
 | |
|             "posted": 234,
 | |
|             "seqno": 345,
 | |
|             "whisper": false,
 | |
|             "whisper_mods": false,
 | |
|                     
 | |
|             "data": "VGVzdERhdGE=",
 | |
|             "signature": "VGVzdFNpZ25hdHVyZQ=="
 | |
|         }
 | |
|         """
 | |
|         @TestState var messageData: Data! = messageJson.data(using: .utf8)!
 | |
|         @TestState var mockCrypto: MockCrypto! = MockCrypto()
 | |
|         @TestState var dependencies: Dependencies! = Dependencies(
 | |
|             crypto: mockCrypto
 | |
|         )
 | |
|         @TestState var decoder: JSONDecoder! = {
 | |
|             let result = JSONDecoder()
 | |
|             result.userInfo = [ Dependencies.userInfoKey: dependencies as Any ]
 | |
|             return result
 | |
|         }()
 | |
|         
 | |
|         // MARK: - a SOGSMessage
 | |
|         describe("a SOGSMessage") {
 | |
|             // MARK: -- when decoding
 | |
|             context("when decoding") {
 | |
|                 // MARK: ---- defaults the whisper values to false
 | |
|                 it("defaults the whisper values to false") {
 | |
|                     messageJson = """
 | |
|                     {
 | |
|                         "id": 123,
 | |
|                         "posted": 234,
 | |
|                         "seqno": 345
 | |
|                     }
 | |
|                     """
 | |
|                     messageData = messageJson.data(using: .utf8)!
 | |
|                     let result: OpenGroupAPI.Message? = try? decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                     
 | |
|                     expect(result).toNot(beNil())
 | |
|                     expect(result?.whisper).to(beFalse())
 | |
|                     expect(result?.whisperMods).to(beFalse())
 | |
|                 }
 | |
|                 
 | |
|                 // MARK: ---- and there is no content
 | |
|                 context("and there is no content") {
 | |
|                     // MARK: ------ does not need a sender
 | |
|                     it("does not need a sender") {
 | |
|                         messageJson = """
 | |
|                         {
 | |
|                             "id": 123,
 | |
|                             "posted": 234,
 | |
|                             "seqno": 345,
 | |
|                             "whisper": false,
 | |
|                             "whisper_mods": false
 | |
|                         }
 | |
|                         """
 | |
|                         messageData = messageJson.data(using: .utf8)!
 | |
|                         let result: OpenGroupAPI.Message? = try? decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         
 | |
|                         expect(result).toNot(beNil())
 | |
|                         expect(result?.sender).to(beNil())
 | |
|                         expect(result?.base64EncodedData).to(beNil())
 | |
|                         expect(result?.base64EncodedSignature).to(beNil())
 | |
|                     }
 | |
|                 }
 | |
|                 
 | |
|                 // MARK: ---- and there is content
 | |
|                 context("and there is content") {
 | |
|                     // MARK: ------ errors if there is no sender
 | |
|                     it("errors if there is no sender") {
 | |
|                         messageJson = """
 | |
|                         {
 | |
|                             "id": 123,
 | |
|                             "posted": 234,
 | |
|                             "seqno": 345,
 | |
|                             "whisper": false,
 | |
|                             "whisper_mods": false,
 | |
|                         
 | |
|                             "data": "VGVzdERhdGE=",
 | |
|                             "signature": "VGVzdFNpZ25hdHVyZQ=="
 | |
|                         }
 | |
|                         """
 | |
|                         messageData = messageJson.data(using: .utf8)!
 | |
|                         
 | |
|                         expect {
 | |
|                             try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         }
 | |
|                         .to(throwError(HTTPError.parsingFailed))
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ errors if the data is not a base64 encoded string
 | |
|                     it("errors if the data is not a base64 encoded string") {
 | |
|                         messageJson = """
 | |
|                         {
 | |
|                             "id": 123,
 | |
|                             "session_id": "05\(TestConstants.publicKey)",
 | |
|                             "posted": 234,
 | |
|                             "seqno": 345,
 | |
|                             "whisper": false,
 | |
|                             "whisper_mods": false,
 | |
|                         
 | |
|                             "data": "Test!!!",
 | |
|                             "signature": "VGVzdFNpZ25hdHVyZQ=="
 | |
|                         }
 | |
|                         """
 | |
|                         messageData = messageJson.data(using: .utf8)!
 | |
|                         
 | |
|                         expect {
 | |
|                             try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         }
 | |
|                         .to(throwError(HTTPError.parsingFailed))
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ errors if the signature is not a base64 encoded string
 | |
|                     it("errors if the signature is not a base64 encoded string") {
 | |
|                         messageJson = """
 | |
|                         {
 | |
|                             "id": 123,
 | |
|                             "session_id": "05\(TestConstants.publicKey)",
 | |
|                             "posted": 234,
 | |
|                             "seqno": 345,
 | |
|                             "whisper": false,
 | |
|                             "whisper_mods": false,
 | |
|                         
 | |
|                             "data": "VGVzdERhdGE=",
 | |
|                             "signature": "Test!!!"
 | |
|                         }
 | |
|                         """
 | |
|                         messageData = messageJson.data(using: .utf8)!
 | |
|                         
 | |
|                         expect {
 | |
|                             try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         }
 | |
|                         .to(throwError(HTTPError.parsingFailed))
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ errors if the dependencies are not provided to the JSONDecoder
 | |
|                     it("errors if the dependencies are not provided to the JSONDecoder") {
 | |
|                         decoder = JSONDecoder()
 | |
|                         
 | |
|                         expect {
 | |
|                             try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         }
 | |
|                         .to(throwError(HTTPError.parsingFailed))
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ errors if the session_id value is not valid
 | |
|                     it("errors if the session_id value is not valid") {
 | |
|                         messageJson = """
 | |
|                         {
 | |
|                             "id": 123,
 | |
|                             "session_id": "TestId",
 | |
|                             "posted": 234,
 | |
|                             "seqno": 345,
 | |
|                             "whisper": false,
 | |
|                             "whisper_mods": false,
 | |
|                         
 | |
|                             "data": "VGVzdERhdGE=",
 | |
|                             "signature": "VGVzdFNpZ25hdHVyZQ=="
 | |
|                         }
 | |
|                         """
 | |
|                         messageData = messageJson.data(using: .utf8)!
 | |
|                         
 | |
|                         expect {
 | |
|                             try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                         }
 | |
|                         .to(throwError(HTTPError.parsingFailed))
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ that is blinded
 | |
|                     context("that is blinded") {
 | |
|                         beforeEach {
 | |
|                             messageJson = """
 | |
|                             {
 | |
|                                 "id": 123,
 | |
|                                 "session_id": "15\(TestConstants.publicKey)",
 | |
|                                 "posted": 234,
 | |
|                                 "seqno": 345,
 | |
|                                 "whisper": false,
 | |
|                                 "whisper_mods": false,
 | |
|                                         
 | |
|                                 "data": "VGVzdERhdGE=",
 | |
|                                 "signature": "VGVzdFNpZ25hdHVyZQ=="
 | |
|                             }
 | |
|                             """
 | |
|                             messageData = messageJson.data(using: .utf8)!
 | |
|                         }
 | |
|                         
 | |
|                         // MARK: -------- succeeds if it succeeds verification
 | |
|                         it("succeeds if it succeeds verification") {
 | |
|                             mockCrypto
 | |
|                                 .when {
 | |
|                                     $0.verify(.signature(message: anyArray(), publicKey: anyArray(), signature: anyArray()))
 | |
|                                 }
 | |
|                                 .thenReturn(true)
 | |
|                             
 | |
|                             expect {
 | |
|                                 try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             }
 | |
|                             .toNot(beNil())
 | |
|                         }
 | |
|                         
 | |
|                         // MARK: -------- provides the correct values as parameters
 | |
|                         it("provides the correct values as parameters") {
 | |
|                             mockCrypto
 | |
|                                 .when {
 | |
|                                     $0.verify(.signature(message: anyArray(), publicKey: anyArray(), signature: anyArray()))
 | |
|                                 }
 | |
|                                 .thenReturn(true)
 | |
|                             
 | |
|                             _ = try? decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             
 | |
|                             expect(mockCrypto)
 | |
|                                 .to(call(matchingParameters: true) {
 | |
|                                     $0.verify(
 | |
|                                         .signature(
 | |
|                                             message: Data(base64Encoded: "VGVzdERhdGE=")!.bytes,
 | |
|                                             publicKey: Data(hex: TestConstants.publicKey).bytes,
 | |
|                                             signature: Data(base64Encoded: "VGVzdFNpZ25hdHVyZQ==")!.bytes
 | |
|                                         )
 | |
|                                     )
 | |
|                                 })
 | |
|                         }
 | |
|                         
 | |
|                         // MARK: -------- throws if it fails verification
 | |
|                         it("throws if it fails verification") {
 | |
|                             mockCrypto
 | |
|                                 .when {
 | |
|                                     $0.verify(.signature(message: anyArray(), publicKey: anyArray(), signature: anyArray()))
 | |
|                                 }
 | |
|                                 .thenReturn(false)
 | |
|                             
 | |
|                             expect {
 | |
|                                 try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             }
 | |
|                             .to(throwError(HTTPError.parsingFailed))
 | |
|                         }
 | |
|                     }
 | |
|                     
 | |
|                     // MARK: ------ that is unblinded
 | |
|                     context("that is unblinded") {
 | |
|                         // MARK: -------- succeeds if it succeeds verification
 | |
|                         it("succeeds if it succeeds verification") {
 | |
|                             mockCrypto
 | |
|                                 .when { $0.verify(.signatureEd25519(any(), publicKey: any(), data: any())) }
 | |
|                                 .thenReturn(true)
 | |
|                             
 | |
|                             expect {
 | |
|                                 try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             }
 | |
|                             .toNot(beNil())
 | |
|                         }
 | |
|                         
 | |
|                         // MARK: -------- provides the correct values as parameters
 | |
|                         it("provides the correct values as parameters") {
 | |
|                             mockCrypto
 | |
|                                 .when { $0.verify(.signatureEd25519(any(), publicKey: any(), data: any())) }
 | |
|                                 .thenReturn(true)
 | |
|                             
 | |
|                             _ = try? decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             
 | |
|                             expect(mockCrypto)
 | |
|                                 .to(call(matchingParameters: true) {
 | |
|                                     $0.verify(
 | |
|                                         .signatureEd25519(
 | |
|                                             Data(base64Encoded: "VGVzdFNpZ25hdHVyZQ==")!,
 | |
|                                             publicKey: Data(hex: TestConstants.publicKey),
 | |
|                                             data: Data(base64Encoded: "VGVzdERhdGE=")!
 | |
|                                         )
 | |
|                                     )
 | |
|                                 })
 | |
|                         }
 | |
|                         
 | |
|                         // MARK: -------- throws if it fails verification
 | |
|                         it("throws if it fails verification") {
 | |
|                             mockCrypto
 | |
|                                 .when { $0.verify(.signatureEd25519(any(), publicKey: any(), data: any())) }
 | |
|                                 .thenReturn(false)
 | |
|                             
 | |
|                             expect {
 | |
|                                 try decoder.decode(OpenGroupAPI.Message.self, from: messageData)
 | |
|                             }
 | |
|                             .to(throwError(HTTPError.parsingFailed))
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |