|
|
|
@ -20,7 +20,6 @@ import android.net.Uri
@@ -20,7 +20,6 @@ import android.net.Uri
|
|
|
|
|
import app.cash.molecule.RecompositionMode |
|
|
|
|
import app.cash.molecule.moleculeFlow |
|
|
|
|
import app.cash.turbine.test |
|
|
|
|
import com.google.common.collect.Iterables.skip |
|
|
|
|
import com.google.common.truth.Truth.assertThat |
|
|
|
|
import io.element.android.features.analytics.test.FakeAnalyticsService |
|
|
|
|
import io.element.android.features.messages.fixtures.aMessageEvent |
|
|
|
@ -46,8 +45,6 @@ import io.element.android.features.messages.utils.messagesummary.FakeMessageSumm
@@ -46,8 +45,6 @@ import io.element.android.features.messages.utils.messagesummary.FakeMessageSumm
|
|
|
|
|
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor |
|
|
|
|
import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper |
|
|
|
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers |
|
|
|
|
import io.element.android.libraries.core.meta.BuildMeta |
|
|
|
|
import io.element.android.libraries.core.meta.BuildType |
|
|
|
|
import io.element.android.libraries.core.mimetype.MimeTypes |
|
|
|
|
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher |
|
|
|
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService |
|
|
|
@ -84,7 +81,6 @@ class MessagesPresenterTest {
@@ -84,7 +81,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
assertThat(initialState.roomId).isEqualTo(A_ROOM_ID) |
|
|
|
|
} |
|
|
|
@ -98,11 +94,9 @@ class MessagesPresenterTest {
@@ -98,11 +94,9 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID)) |
|
|
|
|
assertThat(room.myReactions.count()).isEqualTo(1) |
|
|
|
|
|
|
|
|
|
// No crashes when sending a reaction failed |
|
|
|
|
room.givenToggleReactionResult(Result.failure(IllegalStateException("Failed to send reaction"))) |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID)) |
|
|
|
@ -119,7 +113,6 @@ class MessagesPresenterTest {
@@ -119,7 +113,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID)) |
|
|
|
|
assertThat(room.myReactions.count()).isEqualTo(1) |
|
|
|
@ -136,7 +129,6 @@ class MessagesPresenterTest {
@@ -136,7 +129,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent())) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -152,7 +144,6 @@ class MessagesPresenterTest {
@@ -152,7 +144,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Copy, event)) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -166,10 +157,8 @@ class MessagesPresenterTest {
@@ -166,10 +157,8 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent())) |
|
|
|
|
|
|
|
|
|
val finalState = awaitItem() |
|
|
|
|
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Reply::class.java) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -182,7 +171,6 @@ class MessagesPresenterTest {
@@ -182,7 +171,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent(eventId = null))) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -197,7 +185,6 @@ class MessagesPresenterTest {
@@ -197,7 +185,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
val mediaMessage = aMessageEvent( |
|
|
|
|
content = TimelineItemImageContent( |
|
|
|
@ -214,7 +201,6 @@ class MessagesPresenterTest {
@@ -214,7 +201,6 @@ class MessagesPresenterTest {
|
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) |
|
|
|
|
|
|
|
|
|
val finalState = awaitItem() |
|
|
|
|
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Reply::class.java) |
|
|
|
|
val replyMode = finalState.composerState.mode as MessageComposerMode.Reply |
|
|
|
@ -229,7 +215,6 @@ class MessagesPresenterTest {
@@ -229,7 +215,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
val mediaMessage = aMessageEvent( |
|
|
|
|
content = TimelineItemVideoContent( |
|
|
|
@ -247,7 +232,6 @@ class MessagesPresenterTest {
@@ -247,7 +232,6 @@ class MessagesPresenterTest {
|
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) |
|
|
|
|
|
|
|
|
|
val finalState = awaitItem() |
|
|
|
|
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Reply::class.java) |
|
|
|
|
val replyMode = finalState.composerState.mode as MessageComposerMode.Reply |
|
|
|
@ -262,7 +246,6 @@ class MessagesPresenterTest {
@@ -262,7 +246,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
val mediaMessage = aMessageEvent( |
|
|
|
|
content = TimelineItemFileContent( |
|
|
|
@ -275,7 +258,6 @@ class MessagesPresenterTest {
@@ -275,7 +258,6 @@ class MessagesPresenterTest {
|
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) |
|
|
|
|
|
|
|
|
|
val finalState = awaitItem() |
|
|
|
|
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Reply::class.java) |
|
|
|
|
val replyMode = finalState.composerState.mode as MessageComposerMode.Reply |
|
|
|
@ -290,10 +272,8 @@ class MessagesPresenterTest {
@@ -290,10 +272,8 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent())) |
|
|
|
|
|
|
|
|
|
val finalState = awaitItem() |
|
|
|
|
assertThat(finalState.composerState.mode).isInstanceOf(MessageComposerMode.Edit::class.java) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -308,7 +288,6 @@ class MessagesPresenterTest {
@@ -308,7 +288,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Redact, aMessageEvent())) |
|
|
|
|
assertThat(matrixRoom.redactEventEventIdParam).isEqualTo(AN_EVENT_ID) |
|
|
|
@ -323,7 +302,6 @@ class MessagesPresenterTest {
@@ -323,7 +302,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent())) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -337,7 +315,6 @@ class MessagesPresenterTest {
@@ -337,7 +315,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.Dismiss) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -351,7 +328,6 @@ class MessagesPresenterTest {
@@ -351,7 +328,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Developer, aMessageEvent())) |
|
|
|
|
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) |
|
|
|
@ -366,17 +342,13 @@ class MessagesPresenterTest {
@@ -366,17 +342,13 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
|
|
|
|
|
// Initially the composer doesn't have focus, so we don't show the alert |
|
|
|
|
assertThat(initialState.showReinvitePrompt).isFalse() |
|
|
|
|
|
|
|
|
|
// When the input field is focused we show the alert |
|
|
|
|
initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) |
|
|
|
|
val focusedState = awaitItem() |
|
|
|
|
assertThat(focusedState.showReinvitePrompt).isTrue() |
|
|
|
|
|
|
|
|
|
// If it's dismissed then we stop showing the alert |
|
|
|
|
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Cancel)) |
|
|
|
|
val dismissedState = awaitItem() |
|
|
|
@ -391,10 +363,8 @@ class MessagesPresenterTest {
@@ -391,10 +363,8 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
assertThat(initialState.showReinvitePrompt).isFalse() |
|
|
|
|
|
|
|
|
|
initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) |
|
|
|
|
val focusedState = awaitItem() |
|
|
|
|
assertThat(focusedState.showReinvitePrompt).isFalse() |
|
|
|
@ -408,10 +378,8 @@ class MessagesPresenterTest {
@@ -408,10 +378,8 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
assertThat(initialState.showReinvitePrompt).isFalse() |
|
|
|
|
|
|
|
|
|
initialState.composerState.eventSink(MessageComposerEvents.FocusChanged(true)) |
|
|
|
|
val focusedState = awaitItem() |
|
|
|
|
assertThat(focusedState.showReinvitePrompt).isFalse() |
|
|
|
@ -436,11 +404,9 @@ class MessagesPresenterTest {
@@ -436,11 +404,9 @@ class MessagesPresenterTest {
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
skipItems(1) |
|
|
|
|
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) |
|
|
|
|
|
|
|
|
|
skipItems(1) |
|
|
|
|
val loadingState = awaitItem() |
|
|
|
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue() |
|
|
|
|
|
|
|
|
|
val newState = awaitItem() |
|
|
|
|
assertThat(newState.inviteProgress.isSuccess()).isTrue() |
|
|
|
|
assertThat(room.invitedUserId).isEqualTo(A_SESSION_ID_2) |
|
|
|
@ -466,11 +432,9 @@ class MessagesPresenterTest {
@@ -466,11 +432,9 @@ class MessagesPresenterTest {
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
skipItems(1) |
|
|
|
|
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) |
|
|
|
|
|
|
|
|
|
skipItems(1) |
|
|
|
|
val loadingState = awaitItem() |
|
|
|
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue() |
|
|
|
|
|
|
|
|
|
val newState = awaitItem() |
|
|
|
|
assertThat(newState.inviteProgress.isSuccess()).isTrue() |
|
|
|
|
assertThat(room.invitedUserId).isEqualTo(A_SESSION_ID_2) |
|
|
|
@ -488,11 +452,9 @@ class MessagesPresenterTest {
@@ -488,11 +452,9 @@ class MessagesPresenterTest {
|
|
|
|
|
val initialState = awaitItem() |
|
|
|
|
skipItems(1) |
|
|
|
|
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) |
|
|
|
|
|
|
|
|
|
skipItems(1) |
|
|
|
|
val loadingState = awaitItem() |
|
|
|
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue() |
|
|
|
|
|
|
|
|
|
val newState = awaitItem() |
|
|
|
|
assertThat(newState.inviteProgress.isFailure()).isTrue() |
|
|
|
|
} |
|
|
|
@ -520,7 +482,6 @@ class MessagesPresenterTest {
@@ -520,7 +482,6 @@ class MessagesPresenterTest {
|
|
|
|
|
skipItems(1) |
|
|
|
|
val loadingState = awaitItem() |
|
|
|
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue() |
|
|
|
|
|
|
|
|
|
val newState = awaitItem() |
|
|
|
|
assertThat(newState.inviteProgress.isFailure()).isTrue() |
|
|
|
|
} |
|
|
|
@ -534,7 +495,6 @@ class MessagesPresenterTest {
@@ -534,7 +495,6 @@ class MessagesPresenterTest {
|
|
|
|
|
moleculeFlow(RecompositionMode.Immediate) { |
|
|
|
|
presenter.present() |
|
|
|
|
}.test { |
|
|
|
|
|
|
|
|
|
assertThat(awaitItem().userHasPermissionToSendMessage).isTrue() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|