Add androidTest for inserting a direct reply via MessageContentProcessor.
This commit is contained in:
parent
dbbae7f13f
commit
9bdf65c4e4
3 changed files with 112 additions and 25 deletions
|
@ -5,8 +5,12 @@ import androidx.test.core.app.ApplicationProvider
|
|||
import org.junit.Rule
|
||||
import org.thoughtcrime.securesms.messages.MessageContentProcessor.ExceptionMetadata
|
||||
import org.thoughtcrime.securesms.messages.MessageContentProcessor.MessageState
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
||||
import org.thoughtcrime.securesms.testing.TestProtos
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos
|
||||
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
||||
|
||||
abstract class MessageContentProcessorTest {
|
||||
|
||||
|
@ -28,4 +32,31 @@ abstract class MessageContentProcessorTest {
|
|||
|
||||
return MessageContentProcessor.forNormalContent(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a valid ServiceContentProto with a data message which can be built via
|
||||
* `injectDataMessage`. This function is intended to be built on-top of for more
|
||||
* specific scenario in subclasses.
|
||||
*
|
||||
* Example can be seen in __handleStoryMessageTest
|
||||
*/
|
||||
protected fun createServiceContentWithDataMessage(
|
||||
messageSender: Recipient = Recipient.resolved(harness.others.first()),
|
||||
injectDataMessage: SignalServiceProtos.DataMessage.Builder.() -> Unit
|
||||
): SignalServiceContentProto {
|
||||
return TestProtos.build {
|
||||
serviceContent(
|
||||
localAddress = address(uuid = harness.self.requireServiceId().uuid()).build(),
|
||||
metadata = metadata(
|
||||
address = address(uuid = messageSender.requireServiceId().uuid()).build()
|
||||
).build()
|
||||
).apply {
|
||||
content = content().apply {
|
||||
dataMessage = dataMessage().apply {
|
||||
injectDataMessage()
|
||||
}.build()
|
||||
}.build()
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember
|
|||
import org.thoughtcrime.securesms.database.MessageDatabase
|
||||
import org.thoughtcrime.securesms.database.MmsHelper
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.database.model.StoryType
|
||||
|
@ -20,6 +21,8 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
|||
import org.thoughtcrime.securesms.testing.TestProtos
|
||||
import org.thoughtcrime.securesms.util.FeatureFlagsTestUtil
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||
import org.whispersystems.signalservice.api.push.DistributionId
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage
|
||||
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
||||
import kotlin.random.Random
|
||||
|
||||
|
@ -37,6 +40,52 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
|||
SignalDatabase.mms.deleteAllThreads()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenContentWithADirectStoryReplyWhenIProcessThenIInsertAReplyInTheCorrectThread() {
|
||||
val sender = Recipient.resolved(harness.others.first())
|
||||
val senderThreadId = SignalDatabase.threads.getOrCreateThreadIdFor(sender)
|
||||
val myStory = Recipient.resolved(SignalDatabase.distributionLists.getRecipientId(DistributionListId.MY_STORY)!!)
|
||||
val myStoryThread = SignalDatabase.threads.getOrCreateThreadIdFor(myStory)
|
||||
val expectedSentTime = 200L
|
||||
val storyMessageId = MmsHelper.insert(
|
||||
sentTimeMillis = expectedSentTime,
|
||||
recipient = myStory,
|
||||
storyType = StoryType.STORY_WITH_REPLIES,
|
||||
threadId = myStoryThread
|
||||
)
|
||||
|
||||
SignalDatabase.storySends.insert(
|
||||
messageId = storyMessageId,
|
||||
recipientIds = listOf(sender.id),
|
||||
sentTimestamp = expectedSentTime,
|
||||
allowsReplies = true,
|
||||
distributionId = DistributionId.MY_STORY
|
||||
)
|
||||
|
||||
val expectedBody = "Hello!"
|
||||
|
||||
val storyContent: SignalServiceContentProto = createServiceContentWithStoryContext(
|
||||
messageSender = sender,
|
||||
storyAuthor = harness.self,
|
||||
storySentTimestamp = expectedSentTime
|
||||
) {
|
||||
body = expectedBody
|
||||
}
|
||||
|
||||
runTestWithContent(contentProto = storyContent)
|
||||
|
||||
val replyId = SignalDatabase.mmsSms.getConversation(senderThreadId, 0, 1).use {
|
||||
it.moveToFirst()
|
||||
it.requireLong(MessageDatabase.ID)
|
||||
}
|
||||
|
||||
val replyRecord = SignalDatabase.mms.getMessageRecord(replyId) as MediaMmsMessageRecord
|
||||
assertEquals(ParentStoryId.DirectReply(storyMessageId).serialize(), replyRecord.parentStoryId!!.serialize())
|
||||
assertEquals(expectedBody, replyRecord.body)
|
||||
|
||||
SignalDatabase.mms.deleteAllThreads()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenContentWithAGroupStoryReplyWhenIProcessThenIInsertAReplyToTheCorrectStory() {
|
||||
val sender = Recipient.resolved(harness.others[0])
|
||||
|
@ -79,25 +128,13 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
|||
)
|
||||
|
||||
val expectedBody = "Hello, World!"
|
||||
val storyContent: SignalServiceContentProto = TestProtos.build {
|
||||
serviceContent(
|
||||
localAddress = address(uuid = harness.self.requireServiceId().uuid()).build(),
|
||||
metadata = metadata(
|
||||
address = address(uuid = sender.requireServiceId().uuid()).build()
|
||||
).build()
|
||||
).apply {
|
||||
content = content().apply {
|
||||
dataMessage = dataMessage().apply {
|
||||
storyContext = storyContext(
|
||||
sentTimestamp = 100L,
|
||||
authorUuid = sender.requireServiceId().toString()
|
||||
).build()
|
||||
|
||||
groupV2 = groupContextV2(masterKeyBytes = groupMasterKey.serialize()).build()
|
||||
body = expectedBody
|
||||
}.build()
|
||||
}.build()
|
||||
}.build()
|
||||
val storyContent: SignalServiceContentProto = createServiceContentWithStoryContext(
|
||||
messageSender = sender,
|
||||
storyAuthor = sender,
|
||||
storySentTimestamp = 100L
|
||||
) {
|
||||
groupV2 = TestProtos.build { groupContextV2(masterKeyBytes = groupMasterKey.serialize()).build() }
|
||||
body = expectedBody
|
||||
}
|
||||
|
||||
runTestWithContent(storyContent)
|
||||
|
@ -114,6 +151,28 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
|||
assertEquals(expectedBody, replyRecord.body)
|
||||
|
||||
SignalDatabase.mms.deleteGroupStoryReplies(insertResult.get().messageId)
|
||||
SignalDatabase.mms.deleteAllThreads()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ServiceContent proto with a StoryContext, and then
|
||||
* uses `injectDataMessage` to fill in the data message object.
|
||||
*/
|
||||
private fun createServiceContentWithStoryContext(
|
||||
messageSender: Recipient,
|
||||
storyAuthor: Recipient,
|
||||
storySentTimestamp: Long,
|
||||
injectDataMessage: DataMessage.Builder.() -> Unit
|
||||
): SignalServiceContentProto {
|
||||
return createServiceContentWithDataMessage(messageSender) {
|
||||
storyContext = TestProtos.build {
|
||||
storyContext(
|
||||
sentTimestamp = storySentTimestamp,
|
||||
authorUuid = storyAuthor.requireServiceId().toString()
|
||||
).build()
|
||||
}
|
||||
injectDataMessage()
|
||||
}
|
||||
}
|
||||
|
||||
private fun runTestWithContent(contentProto: SignalServiceContentProto) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.testing.TestProtos
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
||||
|
||||
|
@ -14,11 +13,9 @@ class MessageContentProcessor__handleTextMessageTest : MessageContentProcessorTe
|
|||
fun givenContentWithATextMessageWhenIProcessThenIInsertTheTextMessage() {
|
||||
val testSubject: MessageContentProcessor = createNormalContentTestSubject()
|
||||
val expectedBody = "Hello, World!"
|
||||
val contentProto: SignalServiceContentProto = TestProtos.build {
|
||||
val dataMessage = dataMessage().apply { body = expectedBody }
|
||||
val content = content().apply { this.dataMessage = dataMessage.build() }
|
||||
serviceContent().apply { this.content = content.build() }
|
||||
}.build()
|
||||
val contentProto: SignalServiceContentProto = createServiceContentWithDataMessage {
|
||||
body = expectedBody
|
||||
}
|
||||
|
||||
val content = SignalServiceContent.createFromProto(contentProto)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue