Skip to content

Commit

Permalink
Re-Enable History Sync (#346)
Browse files Browse the repository at this point in the history
* renable history sync

* move history sync tests into their own file

* small test mod

* add more tests

* fix up the linter issues

* try to make the test less flaky
  • Loading branch information
nplasterer authored Dec 19, 2024
1 parent 2d294af commit 021ea9f
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import uniffi.xmtpv3.GenericException
import java.io.File
import java.security.SecureRandom
import java.util.Date
import java.util.concurrent.CompletableFuture
Expand Down Expand Up @@ -315,19 +316,16 @@ class ClientTest {
dbEncryptionKey = key
)
)
alixClient.dropLocalDatabaseConnection()
alixClient.deleteLocalDatabase()

val alixClient2 = Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
alixClient2.dropLocalDatabaseConnection()
alixClient2.deleteLocalDatabase()
}

val alixClient3 = runBlocking {
Expand All @@ -336,7 +334,8 @@ class ClientTest {
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
dbEncryptionKey = key,
dbDirectory = File(context.filesDir.absolutePath, "xmtp_db3").toPath().toString()
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.xmtp.android.library

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -13,7 +12,6 @@ import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import java.security.SecureRandom

@RunWith(AndroidJUnit4::class)
class ConversationsTest {
Expand Down Expand Up @@ -188,133 +186,4 @@ class ConversationsTest {
assertEquals(2, allMessages.size)
job.cancel()
}

@Test
fun testSyncConsent() {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext
val alixWallet = PrivateKeyBuilder()

val alixClient = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
)
)
}
val dm = runBlocking { alixClient.conversations.findOrCreateDm(bo.walletAddress) }
runBlocking {
dm.updateConsentState(ConsentState.DENIED)
assertEquals(dm.consentState(), ConsentState.DENIED)
boClient.conversations.sync()
}
val boDm = runBlocking { boClient.findConversation(dm.id) }

val alixClient2 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
}

val state = runBlocking { alixClient2.inboxState(true) }
assertEquals(state.installations.size, 2)

runBlocking {
boClient.conversations.sync()
boDm?.sync()
alixClient2.preferences.syncConsent()
alixClient.conversations.syncAllConversations()
Thread.sleep(2000)
alixClient2.conversations.syncAllConversations()
Thread.sleep(2000)
val dm2 = alixClient2.findConversation(dm.id)!!
assertEquals(ConsentState.DENIED, dm2.consentState())
alixClient2.preferences.setConsentState(
listOf(
ConsentRecord(
dm2.id,
EntryType.CONVERSATION_ID,
ConsentState.ALLOWED
)
)
)
assertEquals(
alixClient2.preferences.conversationState(dm2.id),
ConsentState.ALLOWED
)
assertEquals(dm2.consentState(), ConsentState.ALLOWED)
}
}

@Test
fun testStreamConsent() {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext
val alixWallet = PrivateKeyBuilder()

val alixClient = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key
)
)
}
val alixGroup = runBlocking { alixClient.conversations.newGroup(listOf(bo.walletAddress)) }

val alixClient2 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)
)
}

runBlocking {
alixGroup.send("Hello")
alixClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
}
val alix2Group = alixClient2.findGroup(alixGroup.id)!!
val consent = mutableListOf<ConsentRecord>()
val job = CoroutineScope(Dispatchers.IO).launch {
try {
alixClient.preferences.streamConsent()
.collect { entry ->
consent.add(entry)
}
} catch (e: Exception) {
}
}

Thread.sleep(1000)

runBlocking {
alix2Group.updateConsentState(ConsentState.DENIED)
val dm3 = alixClient2.conversations.newConversation(caro.walletAddress)
dm3.updateConsentState(ConsentState.DENIED)
alixClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
}

Thread.sleep(2000)
assertEquals(3, consent.size)
assertEquals(alixGroup.consentState(), ConsentState.DENIED)
job.cancel()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package org.xmtp.android.library

import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import java.io.File

@RunWith(AndroidJUnit4::class)
class HistorySyncTest {
private lateinit var alixWallet: PrivateKeyBuilder
private lateinit var boWallet: PrivateKeyBuilder
private lateinit var alix: PrivateKey
private lateinit var alixClient: Client
private lateinit var alixClient2: Client
private lateinit var bo: PrivateKey
private lateinit var boClient: Client
private lateinit var caroWallet: PrivateKeyBuilder
private lateinit var caro: PrivateKey
private lateinit var caroClient: Client
private lateinit var fixtures: Fixtures
private lateinit var alixGroup: Group
private lateinit var alix2Group: Group

@Before
fun setUp() {
fixtures = fixtures()
alixWallet = fixtures.alixAccount
alix = fixtures.alix
boWallet = fixtures.boAccount
bo = fixtures.bo
caroWallet = fixtures.caroAccount
caro = fixtures.caro

boClient = fixtures.boClient
caroClient = fixtures.caroClient
alixClient = fixtures.alixClient

alixGroup = runBlocking { alixClient.conversations.newGroup(listOf(bo.walletAddress)) }

alixClient2 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = fixtures.context,
dbEncryptionKey = fixtures.key,
dbDirectory = fixtures.context.filesDir.absolutePath.toString()
)
)
}

runBlocking {
alixGroup.updateConsentState(ConsentState.DENIED)
alixClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
alix2Group = alixClient2.findGroup(alixGroup.id)!!
}
}

@Test
fun testSyncConsent() {
assertEquals(alixGroup.consentState(), ConsentState.DENIED)
assertEquals(alix2Group.consentState(), ConsentState.UNKNOWN)
val state = runBlocking { alixClient2.inboxState(true) }
assertEquals(state.installations.size, 2)

runBlocking {
alixClient2.preferences.syncConsent()
Thread.sleep(2000)
alixClient.conversations.syncAllConversations()
Thread.sleep(2000)
alixClient2.conversations.syncAllConversations()
Thread.sleep(2000)
assertEquals(ConsentState.DENIED, alix2Group.consentState())
alixClient2.preferences.setConsentState(
listOf(
ConsentRecord(
alix2Group.id,
EntryType.CONVERSATION_ID,
ConsentState.ALLOWED
)
)
)
assertEquals(
alixClient2.preferences.conversationState(alix2Group.id),
ConsentState.ALLOWED
)
assertEquals(alix2Group.consentState(), ConsentState.ALLOWED)
}
}

@Test
fun testSyncMessages() {
runBlocking {
alixGroup.send("A message")
alixGroup.send("A second message")
}
assertEquals(runBlocking { alixGroup.messages() }.size, 3)
assertEquals(runBlocking { alix2Group.messages() }.size, 0)
val state = runBlocking { alixClient2.inboxState(true) }
assertEquals(state.installations.size, 2)

val alixClient3 = runBlocking {
Client().create(
account = alixWallet,
options = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = fixtures.context,
dbEncryptionKey = fixtures.key,
dbDirectory = File(fixtures.context.filesDir.absolutePath, "xmtp_db3").toPath()
.toString()
)
)
}

runBlocking {
alix2Group.send("A message")
alix2Group.send("A second message")
alixClient3.requestMessageHistorySync()
Thread.sleep(1000)
alixClient.conversations.syncAllConversations()
Thread.sleep(2000)
alixClient2.conversations.syncAllConversations()
Thread.sleep(2000)
alixClient3.conversations.syncAllConversations()
Thread.sleep(2000)
val alix3Group = alixClient3.findGroup(alixGroup.id)!!
assertEquals(runBlocking { alixGroup.messages() }.size, 5)
assertEquals(runBlocking { alix2Group.messages() }.size, 5)
assertEquals(runBlocking { alix3Group.messages() }.size, 5)
}
}

@Test
fun testStreamConsent() {
val consent = mutableListOf<ConsentRecord>()
val job = CoroutineScope(Dispatchers.IO).launch {
try {
alixClient.preferences.streamConsent()
.collect { entry ->
consent.add(entry)
}
} catch (e: Exception) {
}
}

Thread.sleep(2000)

runBlocking {
alix2Group.updateConsentState(ConsentState.DENIED)
val dm3 = alixClient2.conversations.newConversation(caro.walletAddress)
dm3.updateConsentState(ConsentState.DENIED)
alixClient.conversations.syncAllConversations()
Thread.sleep(2000)
alixClient2.conversations.syncAllConversations()
Thread.sleep(2000)
}

Thread.sleep(2000)
assertEquals(3, consent.size)
assertEquals(alixGroup.consentState(), ConsentState.DENIED)
job.cancel()
}
}
2 changes: 1 addition & 1 deletion library/src/main/java/org/xmtp/android/library/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class Client() {
inboxId = inboxId,
nonce = 0.toULong(),
legacySignedPrivateKeyProto = null,
historySyncUrl = null
historySyncUrl = options.historySyncUrl
)

options.preAuthenticateToInboxCallback?.let {
Expand Down

0 comments on commit 021ea9f

Please sign in to comment.