diff --git a/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt b/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt index 568e7927..69db1001 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/AttachmentTest.kt @@ -2,6 +2,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.protobuf.kotlin.toByteStringUtf8 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -27,10 +28,12 @@ class AttachmentTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send( - content = attachment, - options = SendOptions(contentType = ContentTypeAttachment), - ) + runBlocking { + aliceConversation.send( + content = attachment, + options = SendOptions(contentType = ContentTypeAttachment), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 1) if (messages.size == 1) { diff --git a/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt b/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt index 3d746434..a02dbbb1 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/CodecTest.kt @@ -2,6 +2,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.protobuf.kotlin.toByteStringUtf8 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test @@ -60,10 +61,12 @@ class CodecTest { val aliceClient = fixtures.aliceClient val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send( - content = 3.14, - options = SendOptions(contentType = NumberCodec().contentType), - ) + runBlocking { + aliceConversation.send( + content = 3.14, + options = SendOptions(contentType = NumberCodec().contentType), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 1) if (messages.size == 1) { @@ -82,10 +85,12 @@ class CodecTest { aliceClient.conversations.newConversation(fixtures.bob.walletAddress) val textContent = TextCodec().encode(content = "hiya") val source = DecodedComposite(encodedContent = textContent) - aliceConversation.send( - content = source, - options = SendOptions(contentType = CompositeCodec().contentType), - ) + runBlocking { + aliceConversation.send( + content = source, + options = SendOptions(contentType = CompositeCodec().contentType), + ) + } val messages = aliceConversation.messages() val decoded: DecodedComposite? = messages[0].content() assertEquals("hiya", decoded?.content()) @@ -107,10 +112,12 @@ class CodecTest { DecodedComposite(parts = listOf(DecodedComposite(encodedContent = numberContent))), ), ) - aliceConversation.send( - content = source, - options = SendOptions(contentType = CompositeCodec().contentType), - ) + runBlocking { + aliceConversation.send( + content = source, + options = SendOptions(contentType = CompositeCodec().contentType), + ) + } val messages = aliceConversation.messages() val decoded: DecodedComposite? = messages[0].content() val part1 = decoded!!.parts[0] @@ -127,10 +134,12 @@ class CodecTest { val aliceClient = fixtures.aliceClient!! val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send( - content = 3.14, - options = SendOptions(contentType = codec.contentType), - ) + runBlocking { + aliceConversation.send( + content = 3.14, + options = SendOptions(contentType = codec.contentType), + ) + } val messages = aliceConversation.messages() assert(messages.isNotEmpty()) diff --git a/library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt index 2ab2dc4a..ce047784 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt @@ -5,6 +5,7 @@ import app.cash.turbine.test import com.google.protobuf.kotlin.toByteString import com.google.protobuf.kotlin.toByteStringUtf8 import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -108,28 +109,30 @@ class ConversationTest { // Overwrite contact as legacy bobClient.publishUserContact(legacy = true) aliceClient.publishUserContact(legacy = true) - bobClient.publish( - envelopes = listOf( - EnvelopeBuilder.buildFromTopic( - topic = Topic.userIntro(bob.walletAddress), - timestamp = someTimeAgo, - message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), - ), - EnvelopeBuilder.buildFromTopic( - topic = Topic.userIntro(alice.walletAddress), - timestamp = someTimeAgo, - message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), - ), - EnvelopeBuilder.buildFromTopic( - topic = Topic.directMessageV1( - bob.walletAddress, - alice.walletAddress, + runBlocking { + bobClient.publish( + envelopes = listOf( + EnvelopeBuilder.buildFromTopic( + topic = Topic.userIntro(bob.walletAddress), + timestamp = someTimeAgo, + message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), + ), + EnvelopeBuilder.buildFromTopic( + topic = Topic.userIntro(alice.walletAddress), + timestamp = someTimeAgo, + message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), + ), + EnvelopeBuilder.buildFromTopic( + topic = Topic.directMessageV1( + bob.walletAddress, + alice.walletAddress, + ), + timestamp = someTimeAgo, + message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), ), - timestamp = someTimeAgo, - message = MessageBuilder.buildFromMessageV1(v1 = messageV1).toByteArray(), ), - ), - ) + ) + } var conversation = aliceClient.conversations.newConversation(bob.walletAddress) assertEquals(conversation.peerAddress, bob.walletAddress) assertEquals(conversation.createdAt, someTimeAgo) @@ -173,8 +176,8 @@ class ConversationTest { val bobConversation = bobClient.conversations.newConversation(aliceWallet.address) val aliceConversation = aliceClient.conversations.newConversation(bobWallet.address) - bobConversation.send(content = "hey alice") - bobConversation.send(content = "hey alice again") + runBlocking { bobConversation.send(content = "hey alice") } + runBlocking { bobConversation.send(content = "hey alice again") } val messages = aliceConversation.messages() assertEquals(2, messages.size) assertEquals("hey alice", messages[1].body) @@ -192,7 +195,7 @@ class ConversationTest { bobWallet.address, InvitationV1ContextBuilder.buildFromConversation("hi"), ) - bobConversation.send(content = "hey alice") + runBlocking { bobConversation.send(content = "hey alice") } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals("hey alice", messages[0].body) @@ -248,9 +251,10 @@ class ConversationTest { val tamperedEnvelope = EnvelopeBuilder.buildFromString( topic = aliceConversation.topic, timestamp = Date(), - message = MessageBuilder.buildFromMessageV2(v2 = tamperedMessage.messageV2).toByteArray(), + message = MessageBuilder.buildFromMessageV2(v2 = tamperedMessage.messageV2) + .toByteArray(), ) - aliceClient.publish(envelopes = listOf(tamperedEnvelope)) + runBlocking { aliceClient.publish(envelopes = listOf(tamperedEnvelope)) } val bobConversation = bobClient.conversations.newConversation( aliceWallet.address, InvitationV1ContextBuilder.buildFromConversation("hi"), @@ -268,10 +272,12 @@ class ConversationTest { fixtures.publishLegacyContact(client = aliceClient) val bobConversation = bobClient.conversations.newConversation(aliceWallet.address) val aliceConversation = aliceClient.conversations.newConversation(bobWallet.address) - bobConversation.send( - text = MutableList(1000) { "A" }.toString(), - sendOptions = SendOptions(compression = EncodedContentCompression.GZIP), - ) + runBlocking { + bobConversation.send( + text = MutableList(1000) { "A" }.toString(), + sendOptions = SendOptions(compression = EncodedContentCompression.GZIP), + ) + } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals(MutableList(1000) { "A" }.toString(), messages[0].content()) @@ -283,10 +289,12 @@ class ConversationTest { fixtures.publishLegacyContact(client = aliceClient) val bobConversation = bobClient.conversations.newConversation(aliceWallet.address) val aliceConversation = aliceClient.conversations.newConversation(bobWallet.address) - bobConversation.send( - content = MutableList(1000) { "A" }.toString(), - options = SendOptions(compression = EncodedContentCompression.DEFLATE), - ) + runBlocking { + bobConversation.send( + content = MutableList(1000) { "A" }.toString(), + options = SendOptions(compression = EncodedContentCompression.DEFLATE), + ) + } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals(MutableList(1000) { "A" }.toString(), messages[0].content()) @@ -302,10 +310,12 @@ class ConversationTest { bobWallet.address, InvitationV1ContextBuilder.buildFromConversation(conversationId = "hi"), ) - bobConversation.send( - text = MutableList(1000) { "A" }.toString(), - sendOptions = SendOptions(compression = EncodedContentCompression.GZIP), - ) + runBlocking { + bobConversation.send( + text = MutableList(1000) { "A" }.toString(), + sendOptions = SendOptions(compression = EncodedContentCompression.GZIP), + ) + } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals(MutableList(1000) { "A" }.toString(), messages[0].body) @@ -322,10 +332,12 @@ class ConversationTest { bobWallet.address, InvitationV1ContextBuilder.buildFromConversation(conversationId = "hi"), ) - bobConversation.send( - content = MutableList(1000) { "A" }.toString(), - options = SendOptions(compression = EncodedContentCompression.DEFLATE), - ) + runBlocking { + bobConversation.send( + content = MutableList(1000) { "A" }.toString(), + options = SendOptions(compression = EncodedContentCompression.DEFLATE), + ) + } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals(MutableList(1000) { "A" }.toString(), messages[0].body) @@ -369,7 +381,7 @@ class ConversationTest { ConversationV2.create(client = client, invitation = invitationv1, header = header) assertEquals(fakeContactWallet.address, conversation.peerAddress) - conversation.send(content = "hello world") + runBlocking { conversation.send(content = "hello world") } val conversationList = client.conversations.list() val recipientConversation = conversationList.lastOrNull() @@ -401,9 +413,9 @@ class ConversationTest { val date = Date() date.time = date.time - 1000000 - bobConversation.send(text = "hey alice 1", sentAt = date) - bobConversation.send(text = "hey alice 2") - bobConversation.send(text = "hey alice 3") + runBlocking { bobConversation.send(text = "hey alice 1", sentAt = date) } + runBlocking { bobConversation.send(text = "hey alice 2") } + runBlocking { bobConversation.send(text = "hey alice 3") } val messages = aliceConversation.messages(limit = 1) assertEquals(1, messages.size) assertEquals("hey alice 3", messages[0].body) @@ -422,9 +434,9 @@ class ConversationTest { ) val date = Date() date.time = date.time - 1000000 - bobConversation.send(text = "hey alice 1", sentAt = date) - bobConversation.send(text = "hey alice 2") - bobConversation.send(text = "hey alice 3") + runBlocking { bobConversation.send(text = "hey alice 1", sentAt = date) } + runBlocking { bobConversation.send(text = "hey alice 2") } + runBlocking { bobConversation.send(text = "hey alice 3") } val messages = aliceConversation.messages(limit = 1) assertEquals(1, messages.size) assertEquals("hey alice 3", messages[0].body) @@ -445,9 +457,9 @@ class ConversationTest { val steveConversation = aliceClient.conversations.newConversation(fixtures.caro.walletAddress) - bobConversation.send(text = "hey alice 1") - bobConversation.send(text = "hey alice 2") - steveConversation.send(text = "hey alice 3") + runBlocking { bobConversation.send(text = "hey alice 1") } + runBlocking { bobConversation.send(text = "hey alice 2") } + runBlocking { steveConversation.send(text = "hey alice 3") } val messages = aliceClient.conversations.listBatchMessages( listOf( Pair(steveConversation.topic, null), @@ -469,9 +481,9 @@ class ConversationTest { val steveConversation = aliceClient.conversations.newConversation(fixtures.caro.walletAddress) - bobConversation.send(text = "hey alice 1") - bobConversation.send(text = "hey alice 2") - steveConversation.send(text = "hey alice 3") + runBlocking { bobConversation.send(text = "hey alice 1") } + runBlocking { bobConversation.send(text = "hey alice 2") } + runBlocking { steveConversation.send(text = "hey alice 3") } val messages = aliceClient.conversations.listBatchDecryptedMessages( listOf( Pair(steveConversation.topic, null), @@ -493,16 +505,16 @@ class ConversationTest { val steveConversation = aliceClient.conversations.newConversation(fixtures.caro.walletAddress) - bobConversation.send(text = "hey alice 1 bob") - steveConversation.send(text = "hey alice 1 steve") + runBlocking { bobConversation.send(text = "hey alice 1 bob") } + runBlocking { steveConversation.send(text = "hey alice 1 steve") } Thread.sleep(100) val date = Date() - bobConversation.send(text = "hey alice 2 bob") - bobConversation.send(text = "hey alice 3 bob") - steveConversation.send(text = "hey alice 2 steve") - steveConversation.send(text = "hey alice 3 steve") + runBlocking { bobConversation.send(text = "hey alice 2 bob") } + runBlocking { bobConversation.send(text = "hey alice 3 bob") } + runBlocking { steveConversation.send(text = "hey alice 2 steve") } + runBlocking { steveConversation.send(text = "hey alice 3 steve") } val messages = aliceClient.conversations.listBatchMessages( listOf( @@ -645,7 +657,7 @@ class ConversationTest { assertEquals(conversation.version, Conversation.Version.V1) val preparedMessage = conversation.prepareMessage(content = "hi") val messageID = preparedMessage.messageId - conversation.send(prepared = preparedMessage) + runBlocking { conversation.send(prepared = preparedMessage) } val messages = conversation.messages() val message = messages[0] assertEquals("hi", message.body) @@ -657,7 +669,7 @@ class ConversationTest { val conversation = aliceClient.conversations.newConversation(bob.walletAddress) val preparedMessage = conversation.prepareMessage(content = "hi") val messageID = preparedMessage.messageId - conversation.send(prepared = preparedMessage) + runBlocking { conversation.send(prepared = preparedMessage) } val messages = conversation.messages() val message = messages[0] assertEquals("hi", message.body) @@ -672,7 +684,7 @@ class ConversationTest { // This does not need the `conversation` to `.publish` the message. // This simulates a background task publishing all pending messages upon connection. - aliceClient.publish(envelopes = preparedMessage.envelopes) + runBlocking { aliceClient.publish(envelopes = preparedMessage.envelopes) } val messages = conversation.messages() val message = messages[0] @@ -753,7 +765,7 @@ class ConversationTest { val bobConversation = bobClient.conversations.newConversation(aliceWallet.address) val aliceConversation = aliceClient.conversations.newConversation(bobWallet.address) val encodedContent = TextCodec().encode(content = "hi") - bobConversation.send(encodedContent = encodedContent) + runBlocking { bobConversation.send(encodedContent = encodedContent) } val messages = aliceConversation.messages() assertEquals(1, messages.size) assertEquals("hi", messages[0].content()) @@ -763,7 +775,7 @@ class ConversationTest { fun testCanSendEncodedContentV2Message() { val bobConversation = bobClient.conversations.newConversation(aliceWallet.address) val encodedContent = TextCodec().encode(content = "hi") - bobConversation.send(encodedContent = encodedContent) + runBlocking { bobConversation.send(encodedContent = encodedContent) } val messages = bobConversation.messages() assertEquals(1, messages.size) assertEquals("hi", messages[0].content()) @@ -821,7 +833,7 @@ class ConversationTest { // Conversations you receive should start as unknown assertTrue(isUnknown) - aliceConversation.send(content = "hey bob") + runBlocking { aliceConversation.send(content = "hey bob") } aliceClient.contacts.refreshConsentList() val isNowAllowed = aliceConversation.consentState() == ConsentState.ALLOWED diff --git a/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt index e516281d..9fbe4200 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ConversationsTest.kt @@ -4,6 +4,7 @@ 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.Ignore import org.junit.Test @@ -101,7 +102,7 @@ class ConversationsTest { sleep(2500) for (i in 0 until 5) { - boConversation.send(text = "Message $i") + runBlocking { boConversation.send(text = "Message $i") } sleep(1000) } assertEquals(allMessages.size, 5) @@ -112,7 +113,7 @@ class ConversationsTest { sleep(2500) for (i in 0 until 5) { - caroConversation.send(text = "Message $i") + runBlocking { caroConversation.send(text = "Message $i") } sleep(1000) } @@ -131,7 +132,7 @@ class ConversationsTest { sleep(2500) for (i in 0 until 5) { - boConversation.send(text = "Message $i") + runBlocking { boConversation.send(text = "Message $i") } sleep(1000) } diff --git a/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt b/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt index 1758f694..670c064c 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt @@ -3,6 +3,9 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import app.cash.turbine.test +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertThrows @@ -277,8 +280,8 @@ class GroupTest { @Test fun testGroupStartsWithAllowedState() { val group = boClient.conversations.newGroup(listOf(alix.walletAddress)) - group.send("howdy") - group.send("gm") + runBlocking { group.send("howdy") } + runBlocking { group.send("gm") } runBlocking { group.sync() } assert(boClient.contacts.isGroupAllowed(group.id)) assertEquals(boClient.contacts.consentList.groupState(group.id), ConsentState.ALLOWED) @@ -287,8 +290,8 @@ class GroupTest { @Test fun testCanSendMessageToGroup() { val group = boClient.conversations.newGroup(listOf(alix.walletAddress)) - group.send("howdy") - group.send("gm") + runBlocking { group.send("howdy") } + runBlocking { group.send("gm") } runBlocking { group.sync() } assertEquals(group.messages().first().body, "gm") assertEquals(group.messages().size, 3) @@ -305,7 +308,7 @@ class GroupTest { Client.register(codec = ReactionCodec()) val group = boClient.conversations.newGroup(listOf(alix.walletAddress)) - group.send("gm") + runBlocking { group.send("gm") } runBlocking { group.sync() } val messageToReact = group.messages()[0] @@ -316,7 +319,12 @@ class GroupTest { schema = ReactionSchema.Unicode ) - group.send(content = reaction, options = SendOptions(contentType = ContentTypeReaction)) + runBlocking { + group.send( + content = reaction, + options = SendOptions(contentType = ContentTypeReaction) + ) + } runBlocking { group.sync() } val messages = group.messages() @@ -345,12 +353,22 @@ class GroupTest { fun testCanStreamAllGroupMessages() = kotlinx.coroutines.test.runTest { val group = caroClient.conversations.newGroup(listOf(alix.walletAddress)) alixClient.conversations.syncGroups() - alixClient.conversations.streamAllGroupMessages().test { - group.send("hi") - assertEquals("hi", awaitItem().encodedContent.content.toStringUtf8()) - group.send("hi again") - assertEquals("hi again", awaitItem().encodedContent.content.toStringUtf8()) + val flow = alixClient.conversations.streamAllGroupMessages() + var counter = 0 + val job = launch { + flow.catch { e -> + throw Exception("Error collecting flow: $e") + }.collect { message -> + counter++ + assertEquals("hi $counter", message.encodedContent.content.toStringUtf8()) + if (counter == 2) this.cancel() + } } + + group.send("hi 1") + group.send("hi 2") + + job.join() } @Test @@ -358,12 +376,24 @@ class GroupTest { val group = caroClient.conversations.newGroup(listOf(alix.walletAddress)) val conversation = boClient.conversations.newConversation(alix.walletAddress) alixClient.conversations.syncGroups() - alixClient.conversations.streamAllMessages(includeGroups = true).test { - group.send("hi") - assertEquals("hi", awaitItem().encodedContent.content.toStringUtf8()) - conversation.send("hi again") - assertEquals("hi again", awaitItem().encodedContent.content.toStringUtf8()) + + val flow = alixClient.conversations.streamAllMessages(includeGroups = true) + var counter = 0 + val job = launch { + flow.catch { e -> + throw Exception("Error collecting flow: $e") + }.collect { message -> + counter++ + assertEquals("hi $counter", message.encodedContent.content.toStringUtf8()) + if (counter == 2) this.cancel() + } } + + group.send("hi 1") + Thread.sleep(2000) + conversation.send("hi 2") + + job.join() } @Test @@ -383,12 +413,23 @@ class GroupTest { fun testCanStreamAllDecryptedGroupMessages() = kotlinx.coroutines.test.runTest { val group = caroClient.conversations.newGroup(listOf(alix.walletAddress)) alixClient.conversations.syncGroups() - alixClient.conversations.streamAllGroupDecryptedMessages().test { - group.send("hi") - assertEquals("hi", awaitItem().encodedContent.content.toStringUtf8()) - group.send("hi again") - assertEquals("hi again", awaitItem().encodedContent.content.toStringUtf8()) + + val flow = alixClient.conversations.streamAllGroupDecryptedMessages() + var counter = 0 + val job = launch { + flow.catch { e -> + throw Exception("Error collecting flow: $e") + }.collect { message -> + counter++ + assertEquals("hi $counter", message.encodedContent.content.toStringUtf8()) + if (counter == 2) this.cancel() + } } + + group.send("hi 1") + group.send("hi 2") + + job.join() } @Test @@ -396,12 +437,24 @@ class GroupTest { val group = caroClient.conversations.newGroup(listOf(alix.walletAddress)) val conversation = boClient.conversations.newConversation(alix.walletAddress) alixClient.conversations.syncGroups() - alixClient.conversations.streamAllDecryptedMessages(includeGroups = true).test { - group.send("hi") - assertEquals("hi", awaitItem().encodedContent.content.toStringUtf8()) - conversation.send("hi again") - assertEquals("hi again", awaitItem().encodedContent.content.toStringUtf8()) + + val flow = alixClient.conversations.streamAllDecryptedMessages(includeGroups = true) + var counter = 0 + val job = launch { + flow.catch { e -> + throw Exception("Error collecting flow: $e") + }.collect { message -> + counter++ + assertEquals("hi $counter", message.encodedContent.content.toStringUtf8()) + if (counter == 2) this.cancel() + } } + + group.send("hi 1") + Thread.sleep(2000) + conversation.send("hi 2") + + job.join() } @Test diff --git a/library/src/androidTest/java/org/xmtp/android/library/LocalInstrumentedTest.kt b/library/src/androidTest/java/org/xmtp/android/library/LocalInstrumentedTest.kt index c1836b4f..7fbb054a 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/LocalInstrumentedTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/LocalInstrumentedTest.kt @@ -30,14 +30,19 @@ import org.xmtp.proto.message.contents.PrivateKeyOuterClass.PrivateKeyBundle import java.util.Date @RunWith(AndroidJUnit4::class) -@Ignore("CI Issues") class LocalInstrumentedTest { @Test fun testPublishingAndFetchingContactBundlesWithWhileGeneratingKeys() { val aliceWallet = PrivateKeyBuilder() val alicePrivateKey = aliceWallet.getPrivateKey() val clientOptions = - ClientOptions(api = ClientOptions.Api(env = XMTPEnvironment.LOCAL, isSecure = false, appVersion = "XMTPTest/v1.0.0")) + ClientOptions( + api = ClientOptions.Api( + env = XMTPEnvironment.LOCAL, + isSecure = false, + appVersion = "XMTPTest/v1.0.0" + ) + ) val client = Client().create(aliceWallet, clientOptions) assertEquals(XMTPEnvironment.LOCAL, client.apiClient.environment) runBlocking { @@ -128,10 +133,10 @@ class LocalInstrumentedTest { // Say this message is sent in the past val date = Date() date.time = date.time - 5000 - convo.send(text = "10 seconds ago", sentAt = date) + runBlocking { convo.send(text = "10 seconds ago", sentAt = date) } Thread.sleep(5000) - convo.send(text = "now first") - convo.send(text = "now") + runBlocking { convo.send(text = "now first") } + runBlocking { convo.send(text = "now") } val messages = convo.messages() assertEquals(3, messages.size) val messagesLimit = convo.messages(limit = 2) @@ -144,9 +149,11 @@ class LocalInstrumentedTest { val messages3 = convo.messages(after = tenSecondsAgoMessage.sent) val nowMessage2 = messages3[0] assertEquals("now", nowMessage2.body) - val messagesAsc = convo.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_ASCENDING) + val messagesAsc = + convo.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_ASCENDING) assertEquals("10 seconds ago", messagesAsc[0].body) - val messagesDesc = convo.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_DESCENDING) + val messagesDesc = + convo.messages(direction = MessageApiOuterClass.SortDirection.SORT_DIRECTION_DESCENDING) assertEquals("now", messagesDesc[0].body) } @@ -169,7 +176,7 @@ class LocalInstrumentedTest { metadata["title"] = "First Chat" } ) - c1.send("hello Alice!") + runBlocking { c1.send("hello Alice!") } delayToPropagate() // So Alice should see just that one conversation. @@ -185,7 +192,7 @@ class LocalInstrumentedTest { metadata["title"] = "Second Chat" } ) - c2.send("hello again Alice!") + runBlocking { c2.send("hello again Alice!") } delayToPropagate() // Then Alice should see both conversations, the newer one first. @@ -209,7 +216,7 @@ class LocalInstrumentedTest { metadata["title"] = "Chatting Using Saved Credentials" } ) - aliceConvo.send("Hello Bob") + runBlocking { aliceConvo.send("Hello Bob") } delayToPropagate() // Alice stores her credentials and conversations to her device @@ -219,7 +226,7 @@ class LocalInstrumentedTest { // Meanwhile, Bob sends a reply. val bobConvos = bob.conversations.list() val bobConvo = bobConvos[0] - bobConvo.send("Oh, hello Alice") + runBlocking { bobConvo.send("Oh, hello Alice") } delayToPropagate() // When Alice's device wakes up, it uses her saved credentials @@ -250,9 +257,9 @@ class LocalInstrumentedTest { Client().create(account = alice, clientOptions) val convo = ConversationV1(client = bobClient, peerAddress = alice.address, sentAt = Date()) // Say this message is sent in the past - convo.send(text = "10 seconds ago") + runBlocking { convo.send(text = "10 seconds ago") } Thread.sleep(10000) - convo.send(text = "now") + runBlocking { convo.send(text = "now") } val allMessages = convo.messages() val messages = convo.messages() assertEquals(2, messages.size) @@ -273,7 +280,7 @@ class LocalInstrumentedTest { assertEquals("hi", it.encodedContent.content.toStringUtf8()) } val bobConversation = bobClient.conversations.newConversation(aliceClient.address) - bobConversation.send(text = "hi") + runBlocking { bobConversation.send(text = "hi") } } @OptIn(ExperimentalCoroutinesApi::class) @@ -295,7 +302,7 @@ class LocalInstrumentedTest { } val bobConversation = bobClient.conversations.newConversation(aliceClient.address) assertEquals(bobConversation.version, Conversation.Version.V1) - bobConversation.send(text = "hi") + runBlocking { bobConversation.send(text = "hi") } } private fun publishLegacyContact(client: Client) { @@ -310,14 +317,416 @@ class LocalInstrumentedTest { it.message = contactBundle.toByteString() }.build() - client.publish(envelopes = listOf(envelope)) + runBlocking { client.publish(envelopes = listOf(envelope)) } } @Test fun testBundleMatchesWhatJSGenerates() { - val jsBytes = arrayOf(10, 134, 3, 10, 192, 1, 8, 212, 239, 181, 224, 235, 48, 18, 34, 10, 32, 253, 223, 55, 200, 191, 179, 50, 251, 142, 186, 142, 144, 120, 55, 133, 66, 62, 227, 207, 137, 96, 29, 252, 171, 22, 50, 211, 201, 114, 170, 219, 35, 26, 146, 1, 8, 212, 239, 181, 224, 235, 48, 18, 68, 10, 66, 10, 64, 128, 94, 43, 155, 99, 38, 128, 57, 37, 120, 14, 252, 31, 231, 47, 9, 128, 134, 90, 150, 231, 9, 36, 119, 119, 177, 93, 241, 169, 185, 104, 166, 105, 25, 244, 26, 197, 83, 94, 171, 35, 9, 189, 13, 103, 141, 68, 129, 134, 121, 23, 84, 209, 102, 56, 207, 194, 238, 9, 213, 72, 74, 220, 198, 26, 67, 10, 65, 4, 93, 157, 228, 228, 120, 5, 159, 157, 196, 163, 132, 142, 147, 218, 144, 247, 192, 180, 221, 177, 31, 97, 59, 48, 110, 204, 155, 208, 233, 140, 180, 54, 136, 127, 78, 81, 49, 185, 30, 73, 110, 43, 50, 179, 76, 230, 99, 118, 58, 150, 51, 136, 13, 188, 69, 79, 81, 135, 70, 115, 91, 58, 177, 95, 18, 192, 1, 8, 215, 150, 182, 224, 235, 48, 18, 34, 10, 32, 157, 32, 14, 227, 139, 112, 46, 218, 54, 217, 214, 220, 159, 105, 220, 13, 164, 50, 168, 234, 81, 48, 224, 112, 187, 138, 18, 160, 129, 195, 187, 30, 26, 146, 1, 8, 215, 150, 182, 224, 235, 48, 18, 68, 10, 66, 10, 64, 248, 197, 168, 69, 172, 44, 172, 107, 56, 177, 111, 167, 54, 162, 189, 76, 115, 240, 113, 202, 235, 50, 168, 137, 161, 188, 111, 139, 185, 215, 159, 145, 38, 250, 224, 77, 107, 107, 9, 226, 93, 235, 71, 215, 85, 247, 141, 14, 156, 85, 144, 200, 94, 160, 108, 190, 111, 219, 29, 61, 11, 57, 237, 156, 26, 67, 10, 65, 4, 123, 22, 77, 71, 125, 86, 127, 27, 156, 189, 27, 30, 102, 185, 38, 134, 239, 69, 53, 232, 48, 104, 70, 118, 242, 114, 201, 89, 36, 94, 133, 210, 228, 205, 1, 17, 119, 121, 20, 113, 160, 64, 102, 224, 193, 9, 76, 166, 7, 4, 155, 241, 217, 116, 135, 206, 62, 77, 216, 54, 204, 39, 24, 96) - val bytes = jsBytes.foldIndexed(ByteArray(jsBytes.size)) { i, a, v -> a.apply { set(i, v.toByte()) } } - val options = ClientOptions(api = ClientOptions.Api(env = XMTPEnvironment.LOCAL, isSecure = true)) + val jsBytes = arrayOf( + 10, + 134, + 3, + 10, + 192, + 1, + 8, + 212, + 239, + 181, + 224, + 235, + 48, + 18, + 34, + 10, + 32, + 253, + 223, + 55, + 200, + 191, + 179, + 50, + 251, + 142, + 186, + 142, + 144, + 120, + 55, + 133, + 66, + 62, + 227, + 207, + 137, + 96, + 29, + 252, + 171, + 22, + 50, + 211, + 201, + 114, + 170, + 219, + 35, + 26, + 146, + 1, + 8, + 212, + 239, + 181, + 224, + 235, + 48, + 18, + 68, + 10, + 66, + 10, + 64, + 128, + 94, + 43, + 155, + 99, + 38, + 128, + 57, + 37, + 120, + 14, + 252, + 31, + 231, + 47, + 9, + 128, + 134, + 90, + 150, + 231, + 9, + 36, + 119, + 119, + 177, + 93, + 241, + 169, + 185, + 104, + 166, + 105, + 25, + 244, + 26, + 197, + 83, + 94, + 171, + 35, + 9, + 189, + 13, + 103, + 141, + 68, + 129, + 134, + 121, + 23, + 84, + 209, + 102, + 56, + 207, + 194, + 238, + 9, + 213, + 72, + 74, + 220, + 198, + 26, + 67, + 10, + 65, + 4, + 93, + 157, + 228, + 228, + 120, + 5, + 159, + 157, + 196, + 163, + 132, + 142, + 147, + 218, + 144, + 247, + 192, + 180, + 221, + 177, + 31, + 97, + 59, + 48, + 110, + 204, + 155, + 208, + 233, + 140, + 180, + 54, + 136, + 127, + 78, + 81, + 49, + 185, + 30, + 73, + 110, + 43, + 50, + 179, + 76, + 230, + 99, + 118, + 58, + 150, + 51, + 136, + 13, + 188, + 69, + 79, + 81, + 135, + 70, + 115, + 91, + 58, + 177, + 95, + 18, + 192, + 1, + 8, + 215, + 150, + 182, + 224, + 235, + 48, + 18, + 34, + 10, + 32, + 157, + 32, + 14, + 227, + 139, + 112, + 46, + 218, + 54, + 217, + 214, + 220, + 159, + 105, + 220, + 13, + 164, + 50, + 168, + 234, + 81, + 48, + 224, + 112, + 187, + 138, + 18, + 160, + 129, + 195, + 187, + 30, + 26, + 146, + 1, + 8, + 215, + 150, + 182, + 224, + 235, + 48, + 18, + 68, + 10, + 66, + 10, + 64, + 248, + 197, + 168, + 69, + 172, + 44, + 172, + 107, + 56, + 177, + 111, + 167, + 54, + 162, + 189, + 76, + 115, + 240, + 113, + 202, + 235, + 50, + 168, + 137, + 161, + 188, + 111, + 139, + 185, + 215, + 159, + 145, + 38, + 250, + 224, + 77, + 107, + 107, + 9, + 226, + 93, + 235, + 71, + 215, + 85, + 247, + 141, + 14, + 156, + 85, + 144, + 200, + 94, + 160, + 108, + 190, + 111, + 219, + 29, + 61, + 11, + 57, + 237, + 156, + 26, + 67, + 10, + 65, + 4, + 123, + 22, + 77, + 71, + 125, + 86, + 127, + 27, + 156, + 189, + 27, + 30, + 102, + 185, + 38, + 134, + 239, + 69, + 53, + 232, + 48, + 104, + 70, + 118, + 242, + 114, + 201, + 89, + 36, + 94, + 133, + 210, + 228, + 205, + 1, + 17, + 119, + 121, + 20, + 113, + 160, + 64, + 102, + 224, + 193, + 9, + 76, + 166, + 7, + 4, + 155, + 241, + 217, + 116, + 135, + 206, + 62, + 77, + 216, + 54, + 204, + 39, + 24, + 96 + ) + val bytes = jsBytes.foldIndexed(ByteArray(jsBytes.size)) { i, a, v -> + a.apply { + set( + i, + v.toByte() + ) + } + } + val options = + ClientOptions(api = ClientOptions.Api(env = XMTPEnvironment.LOCAL, isSecure = true)) val keys = PrivateKeyBundleV1Builder.buildFromBundle(bytes) Client().buildFrom(bundle = keys, options = options) } @@ -340,7 +749,9 @@ class LocalInstrumentedTest { api.publish(envelopes = listOf(envelope)) } Thread.sleep(2_000) - val request = QueryRequest.newBuilder().addContentTopics(Topic.userPrivateStoreKeyBundle(authorized.address).description).build() + val request = QueryRequest.newBuilder() + .addContentTopics(Topic.userPrivateStoreKeyBundle(authorized.address).description) + .build() val result = runBlocking { api.batchQuery(requests = listOf(request)) } @@ -366,7 +777,7 @@ class LocalInstrumentedTest { convo.streamEphemeral().mapLatest { assertEquals("hi", it.message.toStringUtf8()) } - convo.send(content = "hi", options = SendOptions(ephemeral = true)) + runBlocking { convo.send(content = "hi", options = SendOptions(ephemeral = true)) } val messages = convo.messages() assertEquals(0, messages.size) } @@ -391,7 +802,12 @@ class LocalInstrumentedTest { bobConversation.streamEphemeral().mapLatest { assertEquals("hi", it.message.toStringUtf8()) } - aliceConversation.send(content = "hi", options = SendOptions(ephemeral = true)) + runBlocking { + aliceConversation.send( + content = "hi", + options = SendOptions(ephemeral = true) + ) + } val messages = aliceConversation.messages() assertEquals(0, messages.size) } diff --git a/library/src/androidTest/java/org/xmtp/android/library/MessageTest.kt b/library/src/androidTest/java/org/xmtp/android/library/MessageTest.kt index d8945540..f7154086 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/MessageTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/MessageTest.kt @@ -3,6 +3,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.protobuf.kotlin.toByteString import com.google.protobuf.kotlin.toByteStringUtf8 +import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Ignore @@ -196,10 +197,12 @@ class MessageTest { val client = Client().create(account = PrivateKeyBuilder(key)) assertEquals(client.apiClient.environment, XMTPEnvironment.DEV) val convo = client.conversations.list()[0] - convo.send( - text = "hello deflate from kotlin again", - SendOptions(compression = EncodedContentCompression.DEFLATE), - ) + runBlocking { + convo.send( + text = "hello deflate from kotlin again", + SendOptions(compression = EncodedContentCompression.DEFLATE), + ) + } val message = convo.messages().lastOrNull()!! assertEquals("hello deflate from kotlin again", message.content()) } @@ -242,7 +245,7 @@ class MessageTest { peerAddress = "0xf4BF19Ed562651837bc11ff975472ABd239D35B5", sentAt = Date(), ) - convo.send(text = "hello from kotlin") + runBlocking { convo.send(text = "hello from kotlin") } val messages = convo.messages() assertEquals(1, messages.size) assertEquals("hello from kotlin", messages[0].body) @@ -258,7 +261,7 @@ class MessageTest { InvitationV1ContextBuilder.buildFromConversation("https://example.com/4"), ) - convo.send(content = "hello from kotlin") + runBlocking { convo.send(content = "hello from kotlin") } val messages = convo.messages() assertEquals(1, messages.size) assertEquals("hello from kotlin", messages[0].body) @@ -270,7 +273,7 @@ class MessageTest { val fixtures = fixtures() val conversation = fixtures.aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - conversation.send(text = "hi") + runBlocking { conversation.send(text = "hi") } val envelope = fixtures.fakeApiClient.published.lastOrNull()!! val decodedMessage = conversation.decode(envelope) assertEquals(Hash.sha256(envelope.message.toByteArray()).toHex(), decodedMessage.id) diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt index 0333f1c8..70427b5b 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt @@ -2,6 +2,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.protobuf.kotlin.toByteStringUtf8 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -70,7 +71,7 @@ class ReactionTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send(text = "hey alice 2 bob") + runBlocking { aliceConversation.send(text = "hey alice 2 bob") } val messageToReact = aliceConversation.messages()[0] @@ -81,10 +82,12 @@ class ReactionTest { schema = ReactionSchema.Unicode, ) - aliceConversation.send( - content = attachment, - options = SendOptions(contentType = ContentTypeReaction), - ) + runBlocking { + aliceConversation.send( + content = attachment, + options = SendOptions(contentType = ContentTypeReaction), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 2) if (messages.size == 2) { @@ -105,7 +108,7 @@ class ReactionTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send(text = "hey alice 2 bob") + runBlocking { aliceConversation.send(text = "hey alice 2 bob") } val messageToReact = aliceConversation.messages()[0] @@ -116,10 +119,12 @@ class ReactionTest { schema = ReactionSchema.Unicode, ) - aliceConversation.send( - content = attachment, - options = SendOptions(contentType = ContentTypeReaction), - ) + runBlocking { + aliceConversation.send( + content = attachment, + options = SendOptions(contentType = ContentTypeReaction), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 2) diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt index e16cc4be..32cbb713 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReadReceiptTest.kt @@ -1,6 +1,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -21,14 +22,16 @@ class ReadReceiptTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send(text = "hey alice 2 bob") + runBlocking { aliceConversation.send(text = "hey alice 2 bob") } val readReceipt = ReadReceipt - aliceConversation.send( - content = readReceipt, - options = SendOptions(contentType = ContentTypeReadReceipt), - ) + runBlocking { + aliceConversation.send( + content = readReceipt, + options = SendOptions(contentType = ContentTypeReadReceipt), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 2) if (messages.size == 2) { diff --git a/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt b/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt index 8fbf6545..a0e6ed78 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/ReplyTest.kt @@ -1,6 +1,7 @@ package org.xmtp.android.library import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -22,7 +23,7 @@ class ReplyTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send(text = "hey alice 2 bob") + runBlocking { aliceConversation.send(text = "hey alice 2 bob") } val messageToReact = aliceConversation.messages()[0] @@ -32,10 +33,12 @@ class ReplyTest { contentType = ContentTypeText ) - aliceConversation.send( - content = attachment, - options = SendOptions(contentType = ContentTypeReply), - ) + runBlocking { + aliceConversation.send( + content = attachment, + options = SendOptions(contentType = ContentTypeReply), + ) + } val messages = aliceConversation.messages() assertEquals(messages.size, 2) if (messages.size == 2) { diff --git a/library/src/androidTest/java/org/xmtp/android/library/TestHelpers.kt b/library/src/androidTest/java/org/xmtp/android/library/TestHelpers.kt index 4662fb93..db06a554 100644 --- a/library/src/androidTest/java/org/xmtp/android/library/TestHelpers.kt +++ b/library/src/androidTest/java/org/xmtp/android/library/TestHelpers.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.xmtp.android.library.codecs.Fetcher import org.xmtp.android.library.messages.ContactBundle @@ -242,7 +243,7 @@ data class Fixtures( message = contactBundle.toByteString() }.build() - client.publish(envelopes = listOf(envelope)) + runBlocking { client.publish(envelopes = listOf(envelope)) } } } diff --git a/library/src/main/java/org/xmtp/android/library/Client.kt b/library/src/main/java/org/xmtp/android/library/Client.kt index 7b39f3a0..a739f430 100644 --- a/library/src/main/java/org/xmtp/android/library/Client.kt +++ b/library/src/main/java/org/xmtp/android/library/Client.kt @@ -497,7 +497,7 @@ class Client() { } } - fun publish(envelopes: List): PublishResponse { + suspend fun publish(envelopes: List): PublishResponse { val authorized = AuthorizedIdentity( address = address, authorized = privateKeyBundleV1.identityKey.publicKey, @@ -506,7 +506,7 @@ class Client() { val authToken = authorized.createAuthToken() apiClient.setAuthToken(authToken) - return runBlocking { apiClient.publish(envelopes = envelopes) } + return apiClient.publish(envelopes = envelopes) } fun ensureUserContactPublished() { diff --git a/library/src/main/java/org/xmtp/android/library/Contacts.kt b/library/src/main/java/org/xmtp/android/library/Contacts.kt index 09bfa8f6..a64609bc 100644 --- a/library/src/main/java/org/xmtp/android/library/Contacts.kt +++ b/library/src/main/java/org/xmtp/android/library/Contacts.kt @@ -152,7 +152,7 @@ class ConsentList(val client: Client) { ByteArray(message.size) { message[it] }, ) - client.publish(listOf(envelope)) + runBlocking { client.publish(listOf(envelope)) } } fun allow(address: String): ConsentListEntry { diff --git a/library/src/main/java/org/xmtp/android/library/Conversation.kt b/library/src/main/java/org/xmtp/android/library/Conversation.kt index 51219b3a..f4b5d980 100644 --- a/library/src/main/java/org/xmtp/android/library/Conversation.kt +++ b/library/src/main/java/org/xmtp/android/library/Conversation.kt @@ -169,7 +169,7 @@ sealed class Conversation { } } - fun send(prepared: PreparedMessage): String { + suspend fun send(prepared: PreparedMessage): String { return when (this) { is V1 -> conversationV1.send(prepared = prepared) is V2 -> conversationV2.send(prepared = prepared) @@ -177,7 +177,7 @@ sealed class Conversation { } } - fun send(content: T, options: SendOptions? = null): String { + suspend fun send(content: T, options: SendOptions? = null): String { return when (this) { is V1 -> conversationV1.send(content = content, options = options) is V2 -> conversationV2.send(content = content, options = options) @@ -185,7 +185,7 @@ sealed class Conversation { } } - fun send(text: String, sendOptions: SendOptions? = null, sentAt: Date? = null): String { + suspend fun send(text: String, sendOptions: SendOptions? = null, sentAt: Date? = null): String { return when (this) { is V1 -> conversationV1.send(text = text, sendOptions, sentAt) is V2 -> conversationV2.send(text = text, sendOptions, sentAt) @@ -193,7 +193,7 @@ sealed class Conversation { } } - fun send(encodedContent: EncodedContent, options: SendOptions? = null): String { + suspend fun send(encodedContent: EncodedContent, options: SendOptions? = null): String { return when (this) { is V1 -> conversationV1.send(encodedContent = encodedContent, options = options) is V2 -> conversationV2.send(encodedContent = encodedContent, options = options) diff --git a/library/src/main/java/org/xmtp/android/library/ConversationV1.kt b/library/src/main/java/org/xmtp/android/library/ConversationV1.kt index f23c73f7..99bc9403 100644 --- a/library/src/main/java/org/xmtp/android/library/ConversationV1.kt +++ b/library/src/main/java/org/xmtp/android/library/ConversationV1.kt @@ -164,11 +164,11 @@ data class ConversationV1( } } - fun send(text: String, options: SendOptions? = null): String { + suspend fun send(text: String, options: SendOptions? = null): String { return send(text = text, sendOptions = options, sentAt = null) } - internal fun send( + internal suspend fun send( text: String, sendOptions: SendOptions? = null, sentAt: Date? = null, @@ -177,17 +177,17 @@ data class ConversationV1( return send(preparedMessage) } - fun send(content: T, options: SendOptions? = null): String { + suspend fun send(content: T, options: SendOptions? = null): String { val preparedMessage = prepareMessage(content = content, options = options) return send(preparedMessage) } - fun send(encodedContent: EncodedContent, options: SendOptions? = null): String { + suspend fun send(encodedContent: EncodedContent, options: SendOptions? = null): String { val preparedMessage = prepareMessage(encodedContent = encodedContent, options = options) return send(preparedMessage) } - fun send(prepared: PreparedMessage): String { + suspend fun send(prepared: PreparedMessage): String { client.publish(envelopes = prepared.envelopes) if (client.contacts.consentList.state(address = peerAddress) == ConsentState.UNKNOWN) { client.contacts.allow(addresses = listOf(peerAddress)) diff --git a/library/src/main/java/org/xmtp/android/library/ConversationV2.kt b/library/src/main/java/org/xmtp/android/library/ConversationV2.kt index a0c46fbf..13a9e033 100644 --- a/library/src/main/java/org/xmtp/android/library/ConversationV2.kt +++ b/library/src/main/java/org/xmtp/android/library/ConversationV2.kt @@ -173,22 +173,22 @@ data class ConversationV2( } } - fun send(content: T, options: SendOptions? = null): String { + suspend fun send(content: T, options: SendOptions? = null): String { val preparedMessage = prepareMessage(content = content, options = options) return send(preparedMessage) } - fun send(text: String, options: SendOptions? = null, sentAt: Date? = null): String { + suspend fun send(text: String, options: SendOptions? = null, sentAt: Date? = null): String { val preparedMessage = prepareMessage(content = text, options = options) return send(preparedMessage) } - fun send(encodedContent: EncodedContent, options: SendOptions?): String { + suspend fun send(encodedContent: EncodedContent, options: SendOptions?): String { val preparedMessage = prepareMessage(encodedContent = encodedContent, options = options) return send(preparedMessage) } - fun send(prepared: PreparedMessage): String { + suspend fun send(prepared: PreparedMessage): String { client.publish(envelopes = prepared.envelopes) if (client.contacts.consentList.state(address = peerAddress) == ConsentState.UNKNOWN) { client.contacts.allow(addresses = listOf(peerAddress)) diff --git a/library/src/main/java/org/xmtp/android/library/Group.kt b/library/src/main/java/org/xmtp/android/library/Group.kt index e2849c8f..5b1c4513 100644 --- a/library/src/main/java/org/xmtp/android/library/Group.kt +++ b/library/src/main/java/org/xmtp/android/library/Group.kt @@ -17,7 +17,6 @@ import uniffi.xmtpv3.FfiListMessagesOptions import uniffi.xmtpv3.FfiMessage import uniffi.xmtpv3.FfiMessageCallback import uniffi.xmtpv3.GroupPermissions -import java.lang.Exception import java.util.Date import kotlin.time.Duration.Companion.nanoseconds import kotlin.time.DurationUnit @@ -32,22 +31,20 @@ class Group(val client: Client, private val libXMTPGroup: FfiGroup) { private val metadata: FfiGroupMetadata get() = libXMTPGroup.groupMetadata() - fun send(text: String): String { + suspend fun send(text: String): String { return send(prepareMessage(content = text, options = null)) } - fun send(content: T, options: SendOptions? = null): String { + suspend fun send(content: T, options: SendOptions? = null): String { val preparedMessage = prepareMessage(content = content, options = options) return send(preparedMessage) } - fun send(encodedContent: EncodedContent): String { + suspend fun send(encodedContent: EncodedContent): String { if (client.contacts.consentList.groupState(groupId = id) == ConsentState.UNKNOWN) { client.contacts.allowGroup(groupIds = listOf(id)) } - runBlocking { - libXMTPGroup.send(contentBytes = encodedContent.toByteArray()) - } + libXMTPGroup.send(contentBytes = encodedContent.toByteArray()) return id.toHex() } diff --git a/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so b/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so index e1ef2e40..6b56ebc5 100755 Binary files a/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/arm64-v8a/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so b/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so index 76a714b7..a5e027b8 100755 Binary files a/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/armeabi-v7a/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so b/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so index 25c3f0ac..ade9f141 100755 Binary files a/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/x86/libuniffi_xmtpv3.so differ diff --git a/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so b/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so index 23cdf582..1b693be9 100755 Binary files a/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so and b/library/src/main/jniLibs/x86_64/libuniffi_xmtpv3.so differ diff --git a/library/src/test/java/org/xmtp/android/library/RemoteAttachmentTest.kt b/library/src/test/java/org/xmtp/android/library/RemoteAttachmentTest.kt index 44093f67..b038963d 100644 --- a/library/src/test/java/org/xmtp/android/library/RemoteAttachmentTest.kt +++ b/library/src/test/java/org/xmtp/android/library/RemoteAttachmentTest.kt @@ -71,10 +71,12 @@ class RemoteAttachmentTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send( - content = remoteAttachment, - options = SendOptions(contentType = ContentTypeRemoteAttachment), - ) + runBlocking { + aliceConversation.send( + content = remoteAttachment, + options = SendOptions(contentType = ContentTypeRemoteAttachment), + ) + } val messages = aliceConversation.messages() Assert.assertEquals(messages.size, 1) @@ -150,10 +152,12 @@ class RemoteAttachmentTest { val aliceConversation = aliceClient.conversations.newConversation(fixtures.bob.walletAddress) - aliceConversation.send( - content = remoteAttachment, - options = SendOptions(contentType = ContentTypeRemoteAttachment), - ) + runBlocking { + aliceConversation.send( + content = remoteAttachment, + options = SendOptions(contentType = ContentTypeRemoteAttachment), + ) + } val messages = aliceConversation.messages() Assert.assertEquals(messages.size, 1) diff --git a/library/src/test/java/org/xmtp/android/library/TestHelpers.kt b/library/src/test/java/org/xmtp/android/library/TestHelpers.kt index 8ac997b1..930b14fc 100644 --- a/library/src/test/java/org/xmtp/android/library/TestHelpers.kt +++ b/library/src/test/java/org/xmtp/android/library/TestHelpers.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.xmtp.android.library.codecs.Fetcher import org.xmtp.android.library.messages.ContactBundle @@ -226,7 +227,7 @@ data class Fixtures(val aliceAccount: PrivateKeyBuilder, val bobAccount: Private message = contactBundle.toByteString() }.build() - client.publish(envelopes = listOf(envelope)) + runBlocking { client.publish(envelopes = listOf(envelope)) } } }