Merge pull request #2087 from element-hq/feature/bma/enablechatBackup
Enable Chat backup, Mentions and Read Receipt in release.
This commit is contained in:
commit
deff2d8fc5
7 changed files with 101 additions and 109 deletions
1
changelog.d/2087.misc
Normal file
1
changelog.d/2087.misc
Normal file
|
|
@ -0,0 +1 @@
|
|||
Enable Chat backup, Mentions and Read Receipt in release.
|
||||
|
|
@ -186,7 +186,7 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
showReadReceipts = readReceiptsEnabled,
|
||||
newEventState = newItemState.value,
|
||||
sessionState = sessionState,
|
||||
eventSink = ::handleEvents
|
||||
eventSink = { handleEvents(it) }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package io.element.android.features.messages.impl
|
|||
import android.net.Uri
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.ReceiveTurbine
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
||||
|
|
@ -171,8 +172,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID))
|
||||
assertThat(room.myReactions.count()).isEqualTo(1)
|
||||
|
||||
|
|
@ -188,6 +188,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent()))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
|
|
@ -203,8 +204,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Copy, event))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
assertThat(clipboardHelper.clipboardContents).isEqualTo((event.content as TimelineItemTextContent).body)
|
||||
|
|
@ -217,8 +217,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent()))
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Reply::class.java)
|
||||
|
|
@ -232,6 +231,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(3)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent(eventId = null)))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
|
|
@ -246,8 +246,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
val mediaMessage = aMessageEvent(
|
||||
content = TimelineItemImageContent(
|
||||
body = "image.jpg",
|
||||
|
|
@ -277,8 +276,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
val mediaMessage = aMessageEvent(
|
||||
content = TimelineItemVideoContent(
|
||||
body = "video.mp4",
|
||||
|
|
@ -309,8 +307,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
val mediaMessage = aMessageEvent(
|
||||
content = TimelineItemFileContent(
|
||||
body = "file.pdf",
|
||||
|
|
@ -336,8 +333,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent()))
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Edit::class.java)
|
||||
|
|
@ -352,8 +348,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent(content = aTimelineItemPollContent())))
|
||||
assertThat(navigator.onEditPollClickedCount).isEqualTo(1)
|
||||
}
|
||||
|
|
@ -383,6 +378,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent()))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
|
|
@ -396,10 +392,10 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.Dismiss)
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -410,6 +406,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.ViewSource, aMessageEvent()))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
|
|
@ -450,8 +447,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.showReinvitePrompt).isFalse()
|
||||
initialState.composerState.richTextEditorState.requestFocus()
|
||||
val focusedState = awaitItem()
|
||||
|
|
@ -466,8 +462,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.showReinvitePrompt).isFalse()
|
||||
initialState.composerState.richTextEditorState.requestFocus()
|
||||
val focusedState = awaitItem()
|
||||
|
|
@ -585,8 +580,8 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
assertThat(awaitItem().userHasPermissionToSendMessage).isTrue()
|
||||
val state = awaitFirstItem()
|
||||
assertThat(state.userHasPermissionToSendMessage).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -625,8 +620,7 @@ class MessagesPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
val poll = aMessageEvent(
|
||||
content = aTimelineItemPollContent()
|
||||
)
|
||||
|
|
@ -641,6 +635,12 @@ class MessagesPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
||||
// Skip 2 item if Mentions feature is enabled, else 1
|
||||
skipItems(if (FeatureFlags.Mentions.defaultValue) 2 else 1)
|
||||
return awaitItem()
|
||||
}
|
||||
|
||||
private fun TestScope.createMessagesPresenter(
|
||||
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||
matrixRoom: MatrixRoom = FakeMatrixRoom().apply {
|
||||
|
|
|
|||
|
|
@ -112,8 +112,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.isFullScreen).isFalse()
|
||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
||||
assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal)
|
||||
|
|
@ -129,8 +128,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(MessageComposerEvents.ToggleFullScreenState)
|
||||
val fullscreenState = awaitItem()
|
||||
assertThat(fullscreenState.isFullScreen).isTrue()
|
||||
|
|
@ -146,8 +144,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.richTextEditorState.setHtml(A_MESSAGE)
|
||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE)
|
||||
initialState.richTextEditorState.setHtml("")
|
||||
|
|
@ -162,8 +159,7 @@ class MessageComposerPresenterTest {
|
|||
val state = presenter.present()
|
||||
remember(state, state.richTextEditorState.messageHtml) { state }
|
||||
}.test {
|
||||
skipItems(1)
|
||||
var state = awaitItem()
|
||||
var state = awaitFirstItem()
|
||||
val mode = anEditMode()
|
||||
state.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
state = awaitItem()
|
||||
|
|
@ -183,8 +179,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
var state = awaitItem()
|
||||
var state = awaitFirstItem()
|
||||
val mode = aReplyMode()
|
||||
state.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
state = awaitItem()
|
||||
|
|
@ -200,8 +195,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
var state = awaitItem()
|
||||
var state = awaitFirstItem()
|
||||
val mode = aReplyMode()
|
||||
state.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
state = awaitItem()
|
||||
|
|
@ -220,8 +214,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
var state = awaitItem()
|
||||
var state = awaitFirstItem()
|
||||
val mode = aQuoteMode()
|
||||
state.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
state = awaitItem()
|
||||
|
|
@ -238,8 +231,7 @@ class MessageComposerPresenterTest {
|
|||
val state = presenter.present()
|
||||
remember(state, state.richTextEditorState.messageHtml) { state }
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.richTextEditorState.setHtml(A_MESSAGE)
|
||||
val withMessageState = awaitItem()
|
||||
assertThat(withMessageState.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE)
|
||||
|
|
@ -269,8 +261,7 @@ class MessageComposerPresenterTest {
|
|||
val state = presenter.present()
|
||||
remember(state, state.richTextEditorState.messageHtml) { state }
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
||||
val mode = anEditMode()
|
||||
initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
|
|
@ -308,8 +299,7 @@ class MessageComposerPresenterTest {
|
|||
val state = presenter.present()
|
||||
remember(state, state.richTextEditorState.messageHtml) { state }
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
||||
val mode = anEditMode(eventId = null, transactionId = A_TRANSACTION_ID)
|
||||
initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
|
|
@ -346,8 +336,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
||||
val mode = aReplyMode()
|
||||
initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||
|
|
@ -377,8 +366,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.showAttachmentSourcePicker).isFalse()
|
||||
initialState.eventSink(MessageComposerEvents.AddAttachment)
|
||||
assertThat(awaitItem().showAttachmentSourcePicker).isTrue()
|
||||
|
|
@ -391,8 +379,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.AddAttachment)
|
||||
skipItems(1)
|
||||
|
||||
|
|
@ -426,8 +413,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery)
|
||||
val previewingState = awaitItem()
|
||||
assertThat(previewingState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -461,8 +447,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery)
|
||||
val previewingState = awaitItem()
|
||||
assertThat(previewingState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -480,8 +465,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery)
|
||||
// No crashes here, otherwise it fails
|
||||
}
|
||||
|
|
@ -501,8 +485,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles)
|
||||
val sendingState = awaitItem()
|
||||
assertThat(sendingState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -523,8 +506,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.AddAttachment)
|
||||
val attachmentOpenState = awaitItem()
|
||||
assertThat(attachmentOpenState.showAttachmentSourcePicker).isTrue()
|
||||
|
|
@ -541,8 +523,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.AddAttachment)
|
||||
val attachmentOpenState = awaitItem()
|
||||
assertThat(attachmentOpenState.showAttachmentSourcePicker).isTrue()
|
||||
|
|
@ -564,8 +545,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera)
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java)
|
||||
|
|
@ -585,8 +565,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera)
|
||||
val permissionState = awaitItem()
|
||||
assertThat(permissionState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -611,8 +590,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera)
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java)
|
||||
|
|
@ -632,8 +610,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera)
|
||||
val permissionState = awaitItem()
|
||||
assertThat(permissionState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -655,8 +632,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles)
|
||||
val sendingState = awaitItem()
|
||||
assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending::class.java)
|
||||
|
|
@ -675,8 +651,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles)
|
||||
val sendingState = awaitItem()
|
||||
assertThat(sendingState.showAttachmentSourcePicker).isFalse()
|
||||
|
|
@ -693,8 +668,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink(MessageComposerEvents.Error(testException))
|
||||
assertThat(analyticsService.trackedErrors).containsExactly(testException)
|
||||
}
|
||||
|
|
@ -706,8 +680,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.showTextFormatting).isFalse()
|
||||
initialState.eventSink(MessageComposerEvents.AddAttachment)
|
||||
val composerOptions = awaitItem()
|
||||
|
|
@ -733,9 +706,11 @@ class MessageComposerPresenterTest {
|
|||
isDirect = false,
|
||||
isOneToOne = false,
|
||||
).apply {
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
))
|
||||
givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
)
|
||||
)
|
||||
givenCanTriggerRoomNotification(Result.success(true))
|
||||
}
|
||||
val flagsService = FakeFeatureFlagService(
|
||||
|
|
@ -797,9 +772,11 @@ class MessageComposerPresenterTest {
|
|||
isDirect = true,
|
||||
isOneToOne = true,
|
||||
).apply {
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
))
|
||||
givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
)
|
||||
)
|
||||
givenCanTriggerRoomNotification(Result.success(true))
|
||||
}
|
||||
val flagsService = FakeFeatureFlagService(
|
||||
|
|
@ -828,8 +805,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.richTextEditorState.setHtml("Hey @bo")
|
||||
initialState.eventSink(MessageComposerEvents.InsertMention(MentionSuggestion.Member(aRoomMember(userId = A_USER_ID_2))))
|
||||
|
||||
|
|
@ -846,8 +822,7 @@ class MessageComposerPresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
|
||||
// Check intentional mentions on message sent
|
||||
val mentionUser1 = listOf(A_USER_ID.value)
|
||||
|
|
@ -929,6 +904,12 @@ class MessageComposerPresenterTest {
|
|||
currentSessionIdHolder = CurrentSessionIdHolder(FakeMatrixClient(A_SESSION_ID)),
|
||||
permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionPresenter),
|
||||
)
|
||||
|
||||
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
||||
// Skip 2 item if Mentions feature is enabled, else 1
|
||||
skipItems(if (FeatureFlags.Mentions.defaultValue) 2 else 1)
|
||||
return awaitItem()
|
||||
}
|
||||
}
|
||||
|
||||
fun anEditMode(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.messages.impl.timeline
|
|||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.ReceiveTurbine
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.messages.impl.FakeMessagesNavigator
|
||||
|
|
@ -33,6 +34,7 @@ import io.element.android.features.poll.api.actions.EndPollAction
|
|||
import io.element.android.features.poll.api.actions.SendPollResponseAction
|
||||
import io.element.android.features.poll.test.actions.FakeEndPollAction
|
||||
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
|
|
@ -73,7 +75,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.timelineItems).isEmpty()
|
||||
val loadedNoTimelineState = awaitItem()
|
||||
assertThat(loadedNoTimelineState.timelineItems).isEmpty()
|
||||
|
|
@ -87,7 +89,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.paginationState.hasMoreToLoadBackwards).isTrue()
|
||||
assertThat(initialState.paginationState.isBackPaginating).isFalse()
|
||||
initialState.eventSink.invoke(TimelineEvents.LoadMore)
|
||||
|
|
@ -106,7 +108,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
skipItems(1)
|
||||
assertThat(initialState.highlightedEventId).isNull()
|
||||
initialState.eventSink.invoke(TimelineEvents.SetHighlightedEvent(AN_EVENT_ID))
|
||||
|
|
@ -130,7 +132,7 @@ class TimelinePresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
assertThat(timeline.sendReadReceiptCount).isEqualTo(0)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
// Wait for timeline items to be populated
|
||||
skipItems(1)
|
||||
awaitWithLatch { latch ->
|
||||
|
|
@ -154,7 +156,7 @@ class TimelinePresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
assertThat(timeline.sendReadReceiptCount).isEqualTo(0)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
// Wait for timeline items to be populated
|
||||
skipItems(1)
|
||||
awaitWithLatch { latch ->
|
||||
|
|
@ -178,7 +180,7 @@ class TimelinePresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
assertThat(timeline.sendReadReceiptCount).isEqualTo(0)
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
// Wait for timeline items to be populated
|
||||
skipItems(1)
|
||||
awaitWithLatch { latch ->
|
||||
|
|
@ -197,7 +199,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.newEventState).isEqualTo(NewEventState.None)
|
||||
assertThat(initialState.timelineItems.size).isEqualTo(0)
|
||||
timeline.updateTimelineItems {
|
||||
|
|
@ -245,7 +247,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
assertThat(initialState.newEventState).isEqualTo(NewEventState.None)
|
||||
assertThat(initialState.timelineItems.size).isEqualTo(0)
|
||||
val now = Date().time
|
||||
|
|
@ -302,7 +304,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(TimelineEvents.PollAnswerSelected(AN_EVENT_ID, "anAnswerId"))
|
||||
}
|
||||
delay(1)
|
||||
|
|
@ -318,7 +320,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val initialState = awaitFirstItem()
|
||||
initialState.eventSink.invoke(TimelineEvents.PollEndClicked(AN_EVENT_ID))
|
||||
}
|
||||
delay(1)
|
||||
|
|
@ -334,7 +336,7 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
awaitItem().eventSink(TimelineEvents.PollEditClicked(AN_EVENT_ID))
|
||||
awaitFirstItem().eventSink(TimelineEvents.PollEditClicked(AN_EVENT_ID))
|
||||
assertThat(navigator.onEditPollClickedCount).isEqualTo(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -351,15 +353,23 @@ class TimelinePresenterTest {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1) // skip initial state
|
||||
assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(0)
|
||||
awaitFirstItem()
|
||||
awaitItem().let {
|
||||
assertThat(it.timelineItems).isNotEmpty()
|
||||
assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(1)
|
||||
}
|
||||
assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(1)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
||||
// Skip 1 item if Mentions feature is enabled
|
||||
if (FeatureFlags.Mentions.defaultValue) {
|
||||
skipItems(1)
|
||||
}
|
||||
return awaitItem()
|
||||
}
|
||||
|
||||
private fun TestScope.createTimelinePresenter(
|
||||
timeline: MatrixTimeline = FakeMatrixTimeline(),
|
||||
timelineItemsFactory: TimelineItemsFactory = aTimelineItemsFactory(),
|
||||
|
|
|
|||
|
|
@ -65,21 +65,21 @@ enum class FeatureFlags(
|
|||
key = "feature.mentions",
|
||||
title = "Mentions",
|
||||
description = "Type `@` to get mention suggestions and insert them",
|
||||
defaultValue = false,
|
||||
defaultValue = true,
|
||||
isFinished = false,
|
||||
),
|
||||
SecureStorage(
|
||||
key = "feature.securestorage",
|
||||
title = "Chat backup",
|
||||
description = "Allow access to backup and restore chat history settings",
|
||||
defaultValue = false,
|
||||
defaultValue = true,
|
||||
isFinished = false,
|
||||
),
|
||||
ReadReceipts(
|
||||
key = "feature.readreceipts",
|
||||
title = "Show read receipts",
|
||||
description = null,
|
||||
defaultValue = false,
|
||||
defaultValue = true,
|
||||
isFinished = false,
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ class StaticFeatureFlagProvider @Inject constructor() :
|
|||
FeatureFlags.NotificationSettings -> true
|
||||
FeatureFlags.VoiceMessages -> true
|
||||
FeatureFlags.PinUnlock -> true
|
||||
FeatureFlags.Mentions -> false
|
||||
FeatureFlags.SecureStorage -> false
|
||||
FeatureFlags.ReadReceipts -> false
|
||||
FeatureFlags.Mentions -> true
|
||||
FeatureFlags.SecureStorage -> true
|
||||
FeatureFlags.ReadReceipts -> true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue