Updated to the latest version of the libSession-utl (contacts size)

Fixed some broken unit tests (still some broken ones)
pull/856/head
Morgan Pretty 2 years ago
parent 14174e3fbd
commit e3a080dd5b

@ -155,7 +155,7 @@ internal extension SessionUtil {
.bytes .bytes
.map { CChar(bitPattern: $0) } .map { CChar(bitPattern: $0) }
var contact: contacts_contact = contacts_contact() var contact: contacts_contact = contacts_contact()
guard contacts_get_or_create(conf, &contact, &sessionId) else { guard contacts_get_or_construct(conf, &contact, &sessionId) else {
SNLog("Unable to upsert contact from Config Message") SNLog("Unable to upsert contact from Config Message")
return return
} }

@ -67,7 +67,7 @@ bool contacts_get(const config_object* conf, contacts_contact* contact, const ch
/// ///
/// This is the method that should usually be used to create or update a contact, followed by /// This is the method that should usually be used to create or update a contact, followed by
/// setting fields in the contact, and then giving it to contacts_set(). /// setting fields in the contact, and then giving it to contacts_set().
bool contacts_get_or_create( bool contacts_get_or_construct(
const config_object* conf, contacts_contact* contact, const char* session_id) const config_object* conf, contacts_contact* contact, const char* session_id)
__attribute__((warn_unused_result)); __attribute__((warn_unused_result));
@ -79,7 +79,7 @@ void contacts_set(config_object* conf, const contacts_contact* contact);
// is simple enough; for example to update `approved` and leave everything else unchanged: // is simple enough; for example to update `approved` and leave everything else unchanged:
// //
// contacts_contact c; // contacts_contact c;
// if (contacts_get_or_create(conf, &c, some_session_id)) { // if (contacts_get_or_construct(conf, &c, some_session_id)) {
// const char* new_nickname = "Joe"; // const char* new_nickname = "Joe";
// c.approved = new_nickname; // c.approved = new_nickname;
// contacts_set_or_create(conf, &c); // contacts_set_or_create(conf, &c);
@ -92,6 +92,9 @@ void contacts_set(config_object* conf, const contacts_contact* contact);
/// iteration; see details below. /// iteration; see details below.
bool contacts_erase(config_object* conf, const char* session_id); bool contacts_erase(config_object* conf, const char* session_id);
/// Returns the number of contacts.
size_t contacts_size(const config_object* conf);
/// Functions for iterating through the entire contact list, in sorted order. Intended use is: /// Functions for iterating through the entire contact list, in sorted order. Intended use is:
/// ///
/// contacts_contact c; /// contacts_contact c;

@ -84,16 +84,17 @@ class Contacts : public ConfigBase {
/// Similar to get(), but if the session ID does not exist this returns a filled-out /// Similar to get(), but if the session ID does not exist this returns a filled-out
/// contact_info containing the session_id (all other fields will be empty/defaulted). This is /// contact_info containing the session_id (all other fields will be empty/defaulted). This is
/// intended to be combined with `set` to set-or-create a record. Note that this does not add /// intended to be combined with `set` to set-or-create a record.
/// the session id to the contact list when called: that requires also calling `set` with this ///
/// value. /// NB: calling this does *not* add the session id to the contact list when called: that
contact_info get_or_create(std::string_view pubkey_hex) const; /// requires also calling `set` with this value.
contact_info get_or_construct(std::string_view pubkey_hex) const;
/// Sets or updates multiple contact info values at once with the given info. The usual use is /// Sets or updates multiple contact info values at once with the given info. The usual use is
/// to access the current info, change anything desired, then pass it back into set_contact, /// to access the current info, change anything desired, then pass it back into set_contact,
/// e.g.: /// e.g.:
/// ///
/// auto c = contacts.get_or_create(pubkey); /// auto c = contacts.get_or_construct(pubkey);
/// c.name = "Session User 42"; /// c.name = "Session User 42";
/// c.nickname = "BFF"; /// c.nickname = "BFF";
/// contacts.set(c); /// contacts.set(c);
@ -119,6 +120,12 @@ class Contacts : public ConfigBase {
/// example. /// example.
iterator erase(iterator it); iterator erase(iterator it);
/// Returns the number of contacts.
size_t size() const;
/// Returns true if the contact list is empty.
bool empty() const { return size() == 0; }
/// Iterators for iterating through all contacts. Typically you access this implicit via a for /// Iterators for iterating through all contacts. Typically you access this implicit via a for
/// loop over the `Contacts` object: /// loop over the `Contacts` object:
/// ///

@ -38,8 +38,10 @@ class ConfigContactsSpec: QuickSpec {
let contactPtr: UnsafeMutablePointer<contacts_contact>? = nil let contactPtr: UnsafeMutablePointer<contacts_contact>? = nil
expect(contacts_get(conf, contactPtr, &definitelyRealId)).to(beFalse()) expect(contacts_get(conf, contactPtr, &definitelyRealId)).to(beFalse())
expect(contacts_size(conf)).to(equal(0))
var contact2: contacts_contact = contacts_contact() var contact2: contacts_contact = contacts_contact()
expect(contacts_get_or_create(conf, &contact2, &definitelyRealId)).to(beTrue()) expect(contacts_get_or_construct(conf, &contact2, &definitelyRealId)).to(beTrue())
expect(contact2.name).to(beNil()) expect(contact2.name).to(beNil())
expect(contact2.nickname).to(beNil()) expect(contact2.nickname).to(beNil())
expect(contact2.approved).to(beFalse()) expect(contact2.approved).to(beFalse())
@ -155,7 +157,7 @@ class ConfigContactsSpec: QuickSpec {
.bytes .bytes
.map { CChar(bitPattern: $0) } .map { CChar(bitPattern: $0) }
var contact5: contacts_contact = contacts_contact() var contact5: contacts_contact = contacts_contact()
expect(contacts_get_or_create(conf2, &contact5, &anotherId)).to(beTrue()) expect(contacts_get_or_construct(conf2, &contact5, &anotherId)).to(beTrue())
expect(contact5.name).to(beNil()) expect(contact5.name).to(beNil())
expect(contact5.nickname).to(beNil()) expect(contact5.nickname).to(beNil())
expect(contact5.approved).to(beFalse()) expect(contact5.approved).to(beFalse())
@ -193,6 +195,8 @@ class ConfigContactsSpec: QuickSpec {
// Iterate through and make sure we got everything we expected // Iterate through and make sure we got everything we expected
var sessionIds: [String] = [] var sessionIds: [String] = []
var nicknames: [String] = [] var nicknames: [String] = []
expect(contacts_size(conf)).to(equal(2))
var contact6: contacts_contact = contacts_contact() var contact6: contacts_contact = contacts_contact()
let contactIterator: UnsafeMutablePointer<contacts_iterator> = contacts_iterator_new(conf) let contactIterator: UnsafeMutablePointer<contacts_iterator> = contacts_iterator_new(conf)
while !contacts_iterator_done(contactIterator, &contact6) { while !contacts_iterator_done(contactIterator, &contact6) {
@ -211,6 +215,7 @@ class ConfigContactsSpec: QuickSpec {
contacts_iterator_free(contactIterator) // Need to free the iterator contacts_iterator_free(contactIterator) // Need to free the iterator
expect(sessionIds.count).to(equal(2)) expect(sessionIds.count).to(equal(2))
expect(sessionIds.count).to(equal(contacts_size(conf)))
expect(sessionIds.first).to(equal(String(cString: definitelyRealId.nullTerminated()))) expect(sessionIds.first).to(equal(String(cString: definitelyRealId.nullTerminated())))
expect(sessionIds.last).to(equal(String(cString: anotherId.nullTerminated()))) expect(sessionIds.last).to(equal(String(cString: anotherId.nullTerminated())))
expect(nicknames.first).to(equal("Joey")) expect(nicknames.first).to(equal("Joey"))
@ -233,7 +238,7 @@ class ConfigContactsSpec: QuickSpec {
.map { CChar(bitPattern: $0) } .map { CChar(bitPattern: $0) }
let profileKey7: [UInt8] = "qwerty".bytes let profileKey7: [UInt8] = "qwerty".bytes
var contact7: contacts_contact = contacts_contact() var contact7: contacts_contact = contacts_contact()
expect(contacts_get_or_create(conf2, &contact7, &thirdId)).to(beTrue()) expect(contacts_get_or_construct(conf2, &contact7, &thirdId)).to(beTrue())
nickname7.withUnsafeBufferPointer { contact7.nickname = $0.baseAddress } nickname7.withUnsafeBufferPointer { contact7.nickname = $0.baseAddress }
contact7.approved = true contact7.approved = true
contact7.approved_me = true contact7.approved_me = true
@ -297,6 +302,8 @@ class ConfigContactsSpec: QuickSpec {
// Validate the changes // Validate the changes
var sessionIds2: [String] = [] var sessionIds2: [String] = []
var nicknames2: [String] = [] var nicknames2: [String] = []
expect(contacts_size(conf)).to(equal(2))
var contact8: contacts_contact = contacts_contact() var contact8: contacts_contact = contacts_contact()
let contactIterator2: UnsafeMutablePointer<contacts_iterator> = contacts_iterator_new(conf) let contactIterator2: UnsafeMutablePointer<contacts_iterator> = contacts_iterator_new(conf)
while !contacts_iterator_done(contactIterator2, &contact8) { while !contacts_iterator_done(contactIterator2, &contact8) {

@ -27,7 +27,7 @@ class OpenGroupAPISpec: QuickSpec {
var dependencies: SMKDependencies! var dependencies: SMKDependencies!
var response: (ResponseInfoType, Codable)? = nil var response: (ResponseInfoType, Codable)? = nil
var pollResponse: [OpenGroupAPI.Endpoint: (ResponseInfoType, Codable?)]? var pollResponse: (info: ResponseInfoType, data: [OpenGroupAPI.Endpoint: Codable])?
var error: Error? var error: Error?
describe("an OpenGroupAPI") { describe("an OpenGroupAPI") {
@ -205,14 +205,16 @@ class OpenGroupAPISpec: QuickSpec {
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
// Validate the response data // Validate the response data
expect(pollResponse?.values).to(haveCount(3))
expect(pollResponse?.keys).to(contain(.capabilities)) expect(pollResponse?.data.count).to(equal(3))
expect(pollResponse?.keys).to(contain(.roomPollInfo("testRoom", 0))) expect(pollResponse?.data.keys).to(contain(.capabilities))
expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) expect(pollResponse?.data.keys).to(contain(.roomPollInfo("testRoom", 0)))
expect(pollResponse?[.capabilities]?.0).to(beAKindOf(TestOnionRequestAPI.ResponseInfo.self)) expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom")))
expect(pollResponse?.data[.capabilities])
.to(beAKindOf(TestOnionRequestAPI.ResponseInfo.self))
// Validate request data // Validate request data
let requestData: TestOnionRequestAPI.RequestData? = (pollResponse?[.capabilities]?.0 as? TestOnionRequestAPI.ResponseInfo)?.requestData let requestData: TestOnionRequestAPI.RequestData? = (pollResponse?.data[.capabilities] as? TestOnionRequestAPI.ResponseInfo)?.requestData
expect(requestData?.urlString).to(equal("testserver/batch")) expect(requestData?.urlString).to(equal("testserver/batch"))
expect(requestData?.httpMethod).to(equal("POST")) expect(requestData?.httpMethod).to(equal("POST"))
expect(requestData?.publicKey).to(equal("88672ccb97f40bb57238989226cf429b575ba355443f47bc76c5ab144a96c65b")) expect(requestData?.publicKey).to(equal("88672ccb97f40bb57238989226cf429b575ba355443f47bc76c5ab144a96c65b"))
@ -241,7 +243,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom")))
} }
it("retrieves recent messages if there was a last message and it has not performed the initial poll and the last message was too long ago") { it("retrieves recent messages if there was a last message and it has not performed the initial poll and the last message was too long ago") {
@ -272,7 +274,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.roomMessagesRecent("testRoom"))) expect(pollResponse?.data.keys).to(contain(.roomMessagesRecent("testRoom")))
} }
it("retrieves recent messages if there was a last message and it has performed an initial poll but it was not too long ago") { it("retrieves recent messages if there was a last message and it has performed an initial poll but it was not too long ago") {
@ -303,7 +305,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) expect(pollResponse?.data.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123)))
} }
it("retrieves recent messages if there was a last message and there has already been a poll this session") { it("retrieves recent messages if there was a last message and there has already been a poll this session") {
@ -334,7 +336,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123))) expect(pollResponse?.data.keys).to(contain(.roomMessagesSince("testRoom", seqNo: 123)))
} }
context("when unblinded") { context("when unblinded") {
@ -370,8 +372,8 @@ class OpenGroupAPISpec: QuickSpec {
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
// Validate the response data // Validate the response data
expect(pollResponse?.keys).toNot(contain(.inbox)) expect(pollResponse?.data.keys).toNot(contain(.inbox))
expect(pollResponse?.keys).toNot(contain(.outbox)) expect(pollResponse?.data.keys).toNot(contain(.outbox))
} }
} }
@ -471,8 +473,8 @@ class OpenGroupAPISpec: QuickSpec {
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
// Validate the response data // Validate the response data
expect(pollResponse?.keys).to(contain(.inbox)) expect(pollResponse?.data.keys).to(contain(.inbox))
expect(pollResponse?.keys).to(contain(.outbox)) expect(pollResponse?.data.keys).to(contain(.outbox))
} }
it("retrieves recent inbox messages if there was no last message") { it("retrieves recent inbox messages if there was no last message") {
@ -498,7 +500,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.inbox)) expect(pollResponse?.data.keys).to(contain(.inbox))
} }
it("retrieves inbox messages since the last message if there was one") { it("retrieves inbox messages since the last message if there was one") {
@ -529,7 +531,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.inboxSince(id: 124))) expect(pollResponse?.data.keys).to(contain(.inboxSince(id: 124)))
} }
it("retrieves recent outbox messages if there was no last message") { it("retrieves recent outbox messages if there was no last message") {
@ -555,7 +557,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.outbox)) expect(pollResponse?.data.keys).to(contain(.outbox))
} }
it("retrieves outbox messages since the last message if there was one") { it("retrieves outbox messages since the last message if there was one") {
@ -586,7 +588,7 @@ class OpenGroupAPISpec: QuickSpec {
timeout: .milliseconds(100) timeout: .milliseconds(100)
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
expect(pollResponse?.keys).to(contain(.outboxSince(id: 125))) expect(pollResponse?.data.keys).to(contain(.outboxSince(id: 125)))
} }
} }
} }
@ -650,9 +652,9 @@ class OpenGroupAPISpec: QuickSpec {
) )
expect(error?.localizedDescription).to(beNil()) expect(error?.localizedDescription).to(beNil())
let capabilitiesResponse: HTTP.BatchSubResponse<OpenGroupAPI.Capabilities>? = (pollResponse?[.capabilities]?.1 as? HTTP.BatchSubResponse<OpenGroupAPI.Capabilities>) let capabilitiesResponse: HTTP.BatchSubResponse<OpenGroupAPI.Capabilities>? = (pollResponse?.data[.capabilities] as? HTTP.BatchSubResponse<OpenGroupAPI.Capabilities>)
let pollInfoResponse: HTTP.BatchSubResponse<OpenGroupAPI.RoomPollInfo>? = (pollResponse?[.roomPollInfo("testRoom", 0)]?.1 as? HTTP.BatchSubResponse<OpenGroupAPI.RoomPollInfo>) let pollInfoResponse: HTTP.BatchSubResponse<OpenGroupAPI.RoomPollInfo>? = (pollResponse?.data[.roomPollInfo("testRoom", 0)] as? HTTP.BatchSubResponse<OpenGroupAPI.RoomPollInfo>)
let messagesResponse: HTTP.BatchSubResponse<[Failable<OpenGroupAPI.Message>]>? = (pollResponse?[.roomMessagesRecent("testRoom")]?.1 as? HTTP.BatchSubResponse<[Failable<OpenGroupAPI.Message>]>) let messagesResponse: HTTP.BatchSubResponse<[Failable<OpenGroupAPI.Message>]>? = (pollResponse?.data[.roomMessagesRecent("testRoom")] as? HTTP.BatchSubResponse<[Failable<OpenGroupAPI.Message>]>)
expect(capabilitiesResponse?.failedToParseBody).to(beFalse()) expect(capabilitiesResponse?.failedToParseBody).to(beFalse())
expect(pollInfoResponse?.failedToParseBody).to(beTrue()) expect(pollInfoResponse?.failedToParseBody).to(beTrue())
expect(messagesResponse?.failedToParseBody).to(beTrue()) expect(messagesResponse?.failedToParseBody).to(beTrue())

@ -56,11 +56,14 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
it("can encrypt correctly") { it("can encrypt correctly") {
let result = try? MessageSender.encryptWithSessionProtocol( let result = mockStorage.write { db in
"TestMessage".data(using: .utf8)!, try? MessageSender.encryptWithSessionProtocol(
db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
using: SMKDependencies(storage: mockStorage) using: SMKDependencies(storage: mockStorage)
) )
}
// Note: A Nonce is used for this so we can't compare the exact value when not mocked // Note: A Nonce is used for this so we can't compare the exact value when not mocked
expect(result).toNot(beNil()) expect(result).toNot(beNil())
@ -68,11 +71,14 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
it("returns the correct value when mocked") { it("returns the correct value when mocked") {
let result = try? MessageSender.encryptWithSessionProtocol( let result = mockStorage.write { db in
"TestMessage".data(using: .utf8)!, try? MessageSender.encryptWithSessionProtocol(
db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
using: dependencies using: dependencies
) )
}
expect(result?.bytes).to(equal([1, 2, 3])) expect(result?.bytes).to(equal([1, 2, 3]))
} }
@ -83,35 +89,43 @@ class MessageSenderEncryptionSpec: QuickSpec {
_ = try Identity.filter(id: .ed25519SecretKey).deleteAll(db) _ = try Identity.filter(id: .ed25519SecretKey).deleteAll(db)
} }
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionProtocol( try MessageSender.encryptWithSessionProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
using: dependencies using: dependencies
) )
} }
.to(throwError(MessageSenderError.noUserED25519KeyPair)) .to(throwError(MessageSenderError.noUserED25519KeyPair))
} }
}
it("throws an error if the signature generation fails") { it("throws an error if the signature generation fails") {
mockSign.when { $0.signature(message: anyArray(), secretKey: anyArray()) }.thenReturn(nil) mockSign.when { $0.signature(message: anyArray(), secretKey: anyArray()) }.thenReturn(nil)
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionProtocol( try MessageSender.encryptWithSessionProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
using: dependencies using: dependencies
) )
} }
.to(throwError(MessageSenderError.signingFailed)) .to(throwError(MessageSenderError.signingFailed))
} }
}
it("throws an error if the encryption fails") { it("throws an error if the encryption fails") {
mockBox.when { $0.seal(message: anyArray(), recipientPublicKey: anyArray()) }.thenReturn(nil) mockBox.when { $0.seal(message: anyArray(), recipientPublicKey: anyArray()) }.thenReturn(nil)
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionProtocol( try MessageSender.encryptWithSessionProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
using: dependencies using: dependencies
) )
@ -119,15 +133,19 @@ class MessageSenderEncryptionSpec: QuickSpec {
.to(throwError(MessageSenderError.encryptionFailed)) .to(throwError(MessageSenderError.encryptionFailed))
} }
} }
}
context("when encrypting with the blinded session protocol") { context("when encrypting with the blinded session protocol") {
it("successfully encrypts") { it("successfully encrypts") {
let result = try? MessageSender.encryptWithSessionBlindingProtocol( let result = mockStorage.write { db in
"TestMessage".data(using: .utf8)!, try? MessageSender.encryptWithSessionBlindingProtocol(
db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
) )
}
expect(result?.toHexString()) expect(result?.toHexString())
.to(equal( .to(equal(
@ -138,23 +156,29 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
it("includes a version at the start of the encrypted value") { it("includes a version at the start of the encrypted value") {
let result = try? MessageSender.encryptWithSessionBlindingProtocol( let result = mockStorage.write { db in
"TestMessage".data(using: .utf8)!, try? MessageSender.encryptWithSessionBlindingProtocol(
db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
) )
}
expect(result?.toHexString().prefix(2)).to(equal("00")) expect(result?.toHexString().prefix(2)).to(equal("00"))
} }
it("includes the nonce at the end of the encrypted value") { it("includes the nonce at the end of the encrypted value") {
let maybeResult = try? MessageSender.encryptWithSessionBlindingProtocol( let maybeResult = mockStorage.write { db in
"TestMessage".data(using: .utf8)!, try? MessageSender.encryptWithSessionBlindingProtocol(
db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
) )
}
let result: [UInt8] = (maybeResult?.bytes ?? []) let result: [UInt8] = (maybeResult?.bytes ?? [])
let nonceBytes: [UInt8] = Array(result[max(0, (result.count - 24))..<result.count]) let nonceBytes: [UInt8] = Array(result[max(0, (result.count - 24))..<result.count])
@ -163,9 +187,11 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
it("throws an error if the recipient isn't a blinded id") { it("throws an error if the recipient isn't a blinded id") {
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionBlindingProtocol( try MessageSender.encryptWithSessionBlindingProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "05\(TestConstants.publicKey)", for: "05\(TestConstants.publicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
@ -173,6 +199,7 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.to(throwError(MessageSenderError.signingFailed)) .to(throwError(MessageSenderError.signingFailed))
} }
}
it("throws an error if there is no ed25519 keyPair") { it("throws an error if there is no ed25519 keyPair") {
mockStorage.write { db in mockStorage.write { db in
@ -180,9 +207,11 @@ class MessageSenderEncryptionSpec: QuickSpec {
_ = try Identity.filter(id: .ed25519SecretKey).deleteAll(db) _ = try Identity.filter(id: .ed25519SecretKey).deleteAll(db)
} }
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionBlindingProtocol( try MessageSender.encryptWithSessionBlindingProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
@ -190,6 +219,7 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.to(throwError(MessageSenderError.noUserED25519KeyPair)) .to(throwError(MessageSenderError.noUserED25519KeyPair))
} }
}
it("throws an error if it fails to generate a blinded keyPair") { it("throws an error if it fails to generate a blinded keyPair") {
let mockSodium: MockSodium = MockSodium() let mockSodium: MockSodium = MockSodium()
@ -206,9 +236,11 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.thenReturn(nil) .thenReturn(nil)
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionBlindingProtocol( try MessageSender.encryptWithSessionBlindingProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
@ -216,6 +248,7 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.to(throwError(MessageSenderError.signingFailed)) .to(throwError(MessageSenderError.signingFailed))
} }
}
it("throws an error if it fails to generate an encryption key") { it("throws an error if it fails to generate an encryption key") {
let mockSodium: MockSodium = MockSodium() let mockSodium: MockSodium = MockSodium()
@ -248,9 +281,11 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.thenReturn(nil) .thenReturn(nil)
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionBlindingProtocol( try MessageSender.encryptWithSessionBlindingProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
@ -258,6 +293,7 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
.to(throwError(MessageSenderError.signingFailed)) .to(throwError(MessageSenderError.signingFailed))
} }
}
it("throws an error if it fails to encrypt") { it("throws an error if it fails to encrypt") {
let mockAeadXChaCha: MockAeadXChaCha20Poly1305Ietf = MockAeadXChaCha20Poly1305Ietf() let mockAeadXChaCha: MockAeadXChaCha20Poly1305Ietf = MockAeadXChaCha20Poly1305Ietf()
@ -267,9 +303,11 @@ class MessageSenderEncryptionSpec: QuickSpec {
.when { $0.encrypt(message: anyArray(), secretKey: anyArray(), nonce: anyArray()) } .when { $0.encrypt(message: anyArray(), secretKey: anyArray(), nonce: anyArray()) }
.thenReturn(nil) .thenReturn(nil)
mockStorage.write { db in
expect { expect {
try MessageSender.encryptWithSessionBlindingProtocol( try MessageSender.encryptWithSessionBlindingProtocol(
"TestMessage".data(using: .utf8)!, db,
plaintext: "TestMessage".data(using: .utf8)!,
for: "15\(TestConstants.blindedPublicKey)", for: "15\(TestConstants.blindedPublicKey)",
openGroupPublicKey: TestConstants.serverPublicKey, openGroupPublicKey: TestConstants.serverPublicKey,
using: dependencies using: dependencies
@ -281,3 +319,4 @@ class MessageSenderEncryptionSpec: QuickSpec {
} }
} }
} }
}

@ -185,9 +185,9 @@ class BatchResponseSpec: QuickSpec {
) )
expect(result).toNot(beNil()) expect(result).toNot(beNil())
expect((result?[0].1 as? HTTP.BatchSubResponse<TestType>)?.body) expect((result?.responses[0] as? HTTP.BatchSubResponse<TestType>)?.body)
.to(equal(testType)) .to(equal(testType))
expect((result?[1].1 as? HTTP.BatchSubResponse<TestType2>)?.body) expect((result?.responses[1] as? HTTP.BatchSubResponse<TestType2>)?.body)
.to(equal(testType2)) .to(equal(testType2))
} }

Loading…
Cancel
Save