From bd7c6b0a9aaa1411e6ce1e299aacf76f9cbe1718 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Fri, 20 Dec 2024 08:59:30 -0800 Subject: [PATCH] Re-Enable History Sync (#452) * performance follow ups * write a test * re-enable history syncing and add more tests * bring back sync consent --- Sources/XMTPiOS/Client.swift | 6 +- Tests/XMTPTests/ClientTests.swift | 28 ++-- Tests/XMTPTests/ConversationTests.swift | 119 ----------------- Tests/XMTPTests/HistorySyncTests.swift | 171 ++++++++++++++++++++++++ 4 files changed, 188 insertions(+), 136 deletions(-) create mode 100644 Tests/XMTPTests/HistorySyncTests.swift diff --git a/Sources/XMTPiOS/Client.swift b/Sources/XMTPiOS/Client.swift index b7b54728..c9d47ad0 100644 --- a/Sources/XMTPiOS/Client.swift +++ b/Sources/XMTPiOS/Client.swift @@ -227,7 +227,7 @@ public final class Client { accountAddress: address, nonce: 0, legacySignedPrivateKeyProto: nil, - historySyncUrl: nil + historySyncUrl: options.historySyncUrl ) try await options.preAuthenticateToInboxCallback?() @@ -540,10 +540,6 @@ public final class Client { } } - public func requestMessageHistorySync() async throws { - try await ffiClient.sendSyncRequest(kind: .messages) - } - public func inboxState(refreshFromNetwork: Bool) async throws -> InboxState { return InboxState( diff --git a/Tests/XMTPTests/ClientTests.swift b/Tests/XMTPTests/ClientTests.swift index 2266571b..14bda0a4 100644 --- a/Tests/XMTPTests/ClientTests.swift +++ b/Tests/XMTPTests/ClientTests.swift @@ -304,28 +304,31 @@ class ClientTests: XCTestCase { func testRevokesAllOtherInstallations() async throws { let key = try Crypto.secureRandomBytes(count: 32) let alix = try PrivateKey.generate() - let options = ClientOptions.init( - api: .init(env: .local, isSecure: false), - dbEncryptionKey: key - ) let alixClient = try await Client.create( account: alix, - options: options + options: ClientOptions.init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key + ) ) - try alixClient.dropLocalDatabaseConnection() - try alixClient.deleteLocalDatabase() let alixClient2 = try await Client.create( account: alix, - options: options + options: ClientOptions.init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db1" + ) ) - try alixClient2.dropLocalDatabaseConnection() - try alixClient2.deleteLocalDatabase() let alixClient3 = try await Client.create( account: alix, - options: options + options: ClientOptions.init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db2" + ) ) let state = try await alixClient3.inboxState(refreshFromNetwork: true) @@ -532,7 +535,8 @@ class ClientTests: XCTestCase { print("PERF: Built a client with inboxId in \(time3)s") // Measure time to build a client with an inboxId and apiClient - try await Client.connectToApiBackend(api: ClientOptions.Api(env: .dev, isSecure: true)) + try await Client.connectToApiBackend( + api: ClientOptions.Api(env: .dev, isSecure: true)) let start4 = Date() try await Client.create( account: fakeWallet, diff --git a/Tests/XMTPTests/ConversationTests.swift b/Tests/XMTPTests/ConversationTests.swift index 69c81326..430ea4bd 100644 --- a/Tests/XMTPTests/ConversationTests.swift +++ b/Tests/XMTPTests/ConversationTests.swift @@ -189,123 +189,4 @@ class ConversationTests: XCTestCase { await fulfillment(of: [expectation1], timeout: 3) } - - func testSyncConsent() async throws { - let fixtures = try await fixtures() - - let key = try Crypto.secureRandomBytes(count: 32) - let alix = try PrivateKey.generate() - var alixClient = try await Client.create( - account: alix, - options: .init( - api: .init(env: .local, isSecure: false), - dbEncryptionKey: key, - dbDirectory: "xmtp_db" - ) - ) - - let dm = try await alixClient.conversations.findOrCreateDm( - with: fixtures.bo.walletAddress) - try await dm.updateConsentState(state: .denied) - XCTAssertEqual(try dm.consentState(), .denied) - - try await fixtures.boClient.conversations.sync() - let boDm = try await fixtures.boClient.findConversation(conversationId: dm.id) - - var alixClient2 = try await Client.create( - account: alix, - options: .init( - api: .init(env: .local, isSecure: false), - dbEncryptionKey: key, - dbDirectory: "xmtp_db2" - ) - ) - - let state = try await alixClient2.inboxState(refreshFromNetwork: true) - XCTAssertEqual(state.installations.count, 2) - - try await fixtures.boClient.conversations.sync() - try await boDm?.sync() - try await alixClient2.preferences.syncConsent() - try await alixClient.conversations.syncAllConversations() - sleep(2) - try await alixClient2.conversations.syncAllConversations() - sleep(2) - - if let dm2 = try await alixClient2.findConversation(conversationId: dm.id) { - XCTAssertEqual(try dm2.consentState(), .denied) - - try await alixClient2.preferences.setConsentState( - entries: [ - ConsentRecord( - value: dm2.id, - entryType: .conversation_id, - consentType: .allowed - ) - ] - ) - let convoState = try await alixClient2.preferences - .conversationState( - conversationId: dm2.id) - XCTAssertEqual(convoState, .allowed) - XCTAssertEqual(try dm2.consentState(), .allowed) - } - } - - func testStreamConsent() async throws { - let fixtures = try await fixtures() - - let key = try Crypto.secureRandomBytes(count: 32) - let alix = try PrivateKey.generate() - - let alixClient = try await Client.create( - account: alix, - options: .init( - api: .init(env: .local, isSecure: false), - dbEncryptionKey: key, - dbDirectory: "xmtp_db" - ) - ) - - let alixGroup = try await alixClient.conversations.newGroup(with: [fixtures.bo.walletAddress]) - - let alixClient2 = try await Client.create( - account: alix, - options: .init( - api: .init(env: .local, isSecure: false), - dbEncryptionKey: key, - dbDirectory: "xmtp_db2" - ) - ) - - try await alixGroup.send(content: "Hello") - try await alixClient.conversations.syncAllConversations() - try await alixClient2.conversations.syncAllConversations() - let alixGroup2 = try alixClient2.findGroup(groupId: alixGroup.id)! - - var consentList = [ConsentRecord]() - let expectation = XCTestExpectation(description: "Stream Consent") - expectation.expectedFulfillmentCount = 3 - - Task(priority: .userInitiated) { - for try await entry in await alixClient.preferences.streamConsent() { - consentList.append(entry) - expectation.fulfill() - } - } - sleep(1) - try await alixGroup2.updateConsentState(state: .denied) - let dm = try await alixClient2.conversations.newConversation(with: fixtures.caro.walletAddress) - try await dm.updateConsentState(state: .denied) - - sleep(5) - try await alixClient.conversations.syncAllConversations() - try await alixClient2.conversations.syncAllConversations() - - await fulfillment(of: [expectation], timeout: 3) - print(consentList) - XCTAssertEqual(try alixGroup.consentState(), .denied) - } - - } diff --git a/Tests/XMTPTests/HistorySyncTests.swift b/Tests/XMTPTests/HistorySyncTests.swift new file mode 100644 index 00000000..5a16d483 --- /dev/null +++ b/Tests/XMTPTests/HistorySyncTests.swift @@ -0,0 +1,171 @@ +// +// HistorySyncTests.swift +// XMTPiOS +// +// Created by Naomi Plasterer on 12/19/24. +// + +import Foundation +import XCTest + +@testable import XMTPiOS + +@available(iOS 15, *) +class HistorySyncTests: XCTestCase { + func testSyncConsent() async throws { + let fixtures = try await fixtures() + + let key = try Crypto.secureRandomBytes(count: 32) + let alix = try PrivateKey.generate() + let alixClient = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db" + ) + ) + + let group = try await alixClient.conversations.newGroup( + with: [fixtures.bo.walletAddress]) + try await group.updateConsentState(state: .denied) + XCTAssertEqual(try group.consentState(), .denied) + + + let alixClient2 = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db2" + ) + ) + + let state = try await alixClient2.inboxState(refreshFromNetwork: true) + XCTAssertEqual(state.installations.count, 2) + + try await alixClient2.preferences.syncConsent() + try await alixClient.conversations.syncAllConversations() + sleep(2) + try await alixClient2.conversations.syncAllConversations() + sleep(2) + + if let dm2 = try await alixClient2.findConversation(conversationId: group.id) { + XCTAssertEqual(try dm2.consentState(), .denied) + + try await alixClient2.preferences.setConsentState( + entries: [ + ConsentRecord( + value: dm2.id, + entryType: .conversation_id, + consentType: .allowed + ) + ] + ) + let convoState = try await alixClient2.preferences + .conversationState( + conversationId: dm2.id) + XCTAssertEqual(convoState, .allowed) + XCTAssertEqual(try dm2.consentState(), .allowed) + } + } + + func testSyncMessages() async throws { + let fixtures = try await fixtures() + + let key = try Crypto.secureRandomBytes(count: 32) + let alix = try PrivateKey.generate() + let alixClient = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db" + ) + ) + + let group = try await alixClient.conversations.newGroup( + with: [fixtures.bo.walletAddress]) + try await group.send(content: "hi") + let messageCount = try await group.messages().count + XCTAssertEqual(messageCount, 2) + + let alixClient2 = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db2" + ) + ) + + let state = try await alixClient2.inboxState(refreshFromNetwork: true) + XCTAssertEqual(state.installations.count, 2) + + try await alixClient.conversations.syncAllConversations() + sleep(2) + try await alixClient2.conversations.syncAllConversations() + sleep(2) + + if let dm2 = try await alixClient2.findConversation(conversationId: group.id) { + let messageCount = try await group.messages().count + XCTAssertEqual(messageCount, 2) + } + } + + + func testStreamConsent() async throws { + let fixtures = try await fixtures() + + let key = try Crypto.secureRandomBytes(count: 32) + let alix = try PrivateKey.generate() + + let alixClient = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db" + ) + ) + + let alixGroup = try await alixClient.conversations.newGroup(with: [fixtures.bo.walletAddress]) + + let alixClient2 = try await Client.create( + account: alix, + options: .init( + api: .init(env: .local, isSecure: false), + dbEncryptionKey: key, + dbDirectory: "xmtp_db2" + ) + ) + + try await alixGroup.send(content: "Hello") + try await alixClient.conversations.syncAllConversations() + try await alixClient2.conversations.syncAllConversations() + let alixGroup2 = try alixClient2.findGroup(groupId: alixGroup.id)! + + var consentList = [ConsentRecord]() + let expectation = XCTestExpectation(description: "Stream Consent") + expectation.expectedFulfillmentCount = 3 + + Task(priority: .userInitiated) { + for try await entry in await alixClient.preferences.streamConsent() { + consentList.append(entry) + expectation.fulfill() + } + } + sleep(1) + try await alixGroup2.updateConsentState(state: .denied) + let dm = try await alixClient2.conversations.newConversation(with: fixtures.caro.walletAddress) + try await dm.updateConsentState(state: .denied) + + sleep(5) + try await alixClient.conversations.syncAllConversations() + try await alixClient2.conversations.syncAllConversations() + + await fulfillment(of: [expectation], timeout: 3) + print(consentList) + XCTAssertEqual(try alixGroup.consentState(), .denied) + } +}