kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add androidTest for inserting a direct reply via MessageContentProcessor.
rodzic
dbbae7f13f
commit
9bdf65c4e4
|
@ -5,8 +5,12 @@ import androidx.test.core.app.ApplicationProvider
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.thoughtcrime.securesms.messages.MessageContentProcessor.ExceptionMetadata
|
import org.thoughtcrime.securesms.messages.MessageContentProcessor.ExceptionMetadata
|
||||||
import org.thoughtcrime.securesms.messages.MessageContentProcessor.MessageState
|
import org.thoughtcrime.securesms.messages.MessageContentProcessor.MessageState
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
||||||
|
import org.thoughtcrime.securesms.testing.TestProtos
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
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 {
|
abstract class MessageContentProcessorTest {
|
||||||
|
|
||||||
|
@ -28,4 +32,31 @@ abstract class MessageContentProcessorTest {
|
||||||
|
|
||||||
return MessageContentProcessor.forNormalContent(context)
|
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.MessageDatabase
|
||||||
import org.thoughtcrime.securesms.database.MmsHelper
|
import org.thoughtcrime.securesms.database.MmsHelper
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
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.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||||
import org.thoughtcrime.securesms.database.model.StoryType
|
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.testing.TestProtos
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlagsTestUtil
|
import org.thoughtcrime.securesms.util.FeatureFlagsTestUtil
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
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 org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
@ -37,6 +40,52 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
||||||
SignalDatabase.mms.deleteAllThreads()
|
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
|
@Test
|
||||||
fun givenContentWithAGroupStoryReplyWhenIProcessThenIInsertAReplyToTheCorrectStory() {
|
fun givenContentWithAGroupStoryReplyWhenIProcessThenIInsertAReplyToTheCorrectStory() {
|
||||||
val sender = Recipient.resolved(harness.others[0])
|
val sender = Recipient.resolved(harness.others[0])
|
||||||
|
@ -79,25 +128,13 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
||||||
)
|
)
|
||||||
|
|
||||||
val expectedBody = "Hello, World!"
|
val expectedBody = "Hello, World!"
|
||||||
val storyContent: SignalServiceContentProto = TestProtos.build {
|
val storyContent: SignalServiceContentProto = createServiceContentWithStoryContext(
|
||||||
serviceContent(
|
messageSender = sender,
|
||||||
localAddress = address(uuid = harness.self.requireServiceId().uuid()).build(),
|
storyAuthor = sender,
|
||||||
metadata = metadata(
|
storySentTimestamp = 100L
|
||||||
address = address(uuid = sender.requireServiceId().uuid()).build()
|
) {
|
||||||
).build()
|
groupV2 = TestProtos.build { groupContextV2(masterKeyBytes = groupMasterKey.serialize()).build() }
|
||||||
).apply {
|
body = expectedBody
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runTestWithContent(storyContent)
|
runTestWithContent(storyContent)
|
||||||
|
@ -114,6 +151,28 @@ class MessageContentProcessor__handleStoryMessageTest : MessageContentProcessorT
|
||||||
assertEquals(expectedBody, replyRecord.body)
|
assertEquals(expectedBody, replyRecord.body)
|
||||||
|
|
||||||
SignalDatabase.mms.deleteGroupStoryReplies(insertResult.get().messageId)
|
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) {
|
private fun runTestWithContent(contentProto: SignalServiceContentProto) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.testing.TestProtos
|
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
||||||
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto
|
||||||
|
|
||||||
|
@ -14,11 +13,9 @@ class MessageContentProcessor__handleTextMessageTest : MessageContentProcessorTe
|
||||||
fun givenContentWithATextMessageWhenIProcessThenIInsertTheTextMessage() {
|
fun givenContentWithATextMessageWhenIProcessThenIInsertTheTextMessage() {
|
||||||
val testSubject: MessageContentProcessor = createNormalContentTestSubject()
|
val testSubject: MessageContentProcessor = createNormalContentTestSubject()
|
||||||
val expectedBody = "Hello, World!"
|
val expectedBody = "Hello, World!"
|
||||||
val contentProto: SignalServiceContentProto = TestProtos.build {
|
val contentProto: SignalServiceContentProto = createServiceContentWithDataMessage {
|
||||||
val dataMessage = dataMessage().apply { body = expectedBody }
|
body = expectedBody
|
||||||
val content = content().apply { this.dataMessage = dataMessage.build() }
|
}
|
||||||
serviceContent().apply { this.content = content.build() }
|
|
||||||
}.build()
|
|
||||||
|
|
||||||
val content = SignalServiceContent.createFromProto(contentProto)
|
val content = SignalServiceContent.createFromProto(contentProto)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue