Use presenter test extension.

This commit is contained in:
Benoit Marty
2026-01-27 10:08:25 +01:00
parent c74169d893
commit 847e62a5ac
8 changed files with 78 additions and 237 deletions

View File

@@ -11,9 +11,6 @@
package io.element.android.features.messages.impl.attachments
import android.net.Uri
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewEvent
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewPresenter
@@ -111,9 +108,7 @@ class AttachmentsPreviewPresenterTest {
mediaPreProcessor = mediaPreProcessor,
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
@@ -147,9 +142,7 @@ class AttachmentsPreviewPresenterTest {
mediaPreProcessor = mediaPreProcessor,
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
// Pre-processing finishes
@@ -185,9 +178,7 @@ class AttachmentsPreviewPresenterTest {
mediaPreProcessor = mediaPreProcessor,
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
@@ -216,9 +207,7 @@ class AttachmentsPreviewPresenterTest {
},
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.eventSink(AttachmentsPreviewEvent.SendAttachment)
@@ -241,9 +230,7 @@ class AttachmentsPreviewPresenterTest {
},
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
// Pre-processing finishes
@@ -265,9 +252,7 @@ class AttachmentsPreviewPresenterTest {
temporaryUriDeleter = FakeTemporaryUriDeleter(deleteCallback),
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.eventSink(AttachmentsPreviewEvent.CancelAndDismiss)
@@ -298,9 +283,7 @@ class AttachmentsPreviewPresenterTest {
mediaPreProcessor = mediaPreProcessor,
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.textEditorState.setMarkdown(A_CAPTION)
@@ -341,9 +324,7 @@ class AttachmentsPreviewPresenterTest {
mediaPreProcessor = mediaPreProcessor,
onDoneListener = { onDoneListener() },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.textEditorState.setMarkdown(A_CAPTION)
@@ -418,9 +399,7 @@ class AttachmentsPreviewPresenterTest {
},
)
val presenter = createAttachmentsPreviewPresenter(room = room, onDoneListener = onDoneListenerResult)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.eventSink(AttachmentsPreviewEvent.SendAttachment)
@@ -453,9 +432,7 @@ class AttachmentsPreviewPresenterTest {
),
onDoneListener = onDoneListenerResult,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle)
initialState.eventSink(AttachmentsPreviewEvent.SendAttachment)
@@ -503,9 +480,7 @@ class AttachmentsPreviewPresenterTest {
}
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
assertThat(localMedia.info.fileSize).isGreaterThan(maxUploadSize)
consumeItemsUntilPredicate { it.mediaOptimizationSelectorState.maxUploadSize.isSuccess() }
@@ -563,9 +538,7 @@ class AttachmentsPreviewPresenterTest {
}
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
consumeItemsUntilPredicate {
it.mediaOptimizationSelectorState.maxUploadSize.isSuccess() &&
it.mediaOptimizationSelectorState.videoSizeEstimations.dataOrNull()?.isNotEmpty() == true

View File

@@ -11,9 +11,6 @@ package io.element.android.features.messages.impl.attachments.video
import android.net.Uri
import android.util.Size
import androidx.test.ext.junit.runners.AndroidJUnit4
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.test.attachments.video.FakeVideoMetadataExtractor
import io.element.android.features.messages.test.attachments.video.FakeVideoMetadataExtractorFactory
@@ -29,6 +26,7 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia
import io.element.android.libraries.mediaviewer.test.viewer.aLocalMedia
import io.element.android.libraries.preferences.api.store.VideoCompressionPreset
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.Rule
@@ -46,9 +44,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
@Test
fun `present - initial state`() = runTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
awaitItem().run {
// Loading
assertThat(videoSizeEstimations).isInstanceOf(AsyncData.Loading::class.java)
@@ -77,9 +73,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
localMedia = aLocalMedia(mockMediaUrl, anImageMediaInfo())
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading state
skipItems(1)
@@ -94,9 +88,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
@Test
fun `present - OpenVideoPresetSelectorDialog displays it, DismissVideoPresetSelectorDialog hides it`() = runTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading state
val eventSink = awaitItem().eventSink
@@ -115,9 +107,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
@Test
fun `present - SelectVideoPreset sets it and dismisses the dialog`() = runTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading state
val eventSink = awaitItem().eventSink
@@ -139,9 +129,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
mediaExtractorFactory = FakeVideoMetadataExtractorFactory(FakeVideoMetadataExtractor(sizeResult = Result.failure(AN_EXCEPTION))),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading state
val eventSink = awaitItem().eventSink
@@ -163,9 +151,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
)
),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading and loaded states
val eventSink = awaitItem().eventSink
skipItems(1)
@@ -188,9 +174,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
localMedia = aLocalMedia(mockMediaUrl, anImageMediaInfo()),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading state
val eventSink = awaitItem().eventSink
@@ -207,9 +191,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
maxUploadSizeProvider = MaxUploadSizeProvider { Result.failure(AN_EXCEPTION) }
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading and loaded state
skipItems(1)
assertThat(awaitItem().maxUploadSize.dataOrNull()).isEqualTo(1024 * 1024 * 100)
@@ -221,9 +203,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
val presenter = createDefaultMediaOptimizationSelectorPresenter(
featureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.SelectableMediaQuality.key to false)),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
// Skip loading and loaded state
skipItems(1)
assertThat(awaitItem().displayMediaSelectorViews).isFalse()

View File

@@ -137,9 +137,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - initial state`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
assertThat(initialState.isFullScreen).isFalse()
assertThat(initialState.textEditorState.messageHtml()).isEqualTo("")
@@ -152,9 +150,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - toggle fullscreen`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink.invoke(MessageComposerEvent.ToggleFullScreenState)
val fullscreenState = awaitItem()
@@ -168,9 +164,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - change message`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.textEditorState.setHtml(A_MESSAGE)
assertThat(initialState.textEditorState.messageHtml()).isEqualTo(A_MESSAGE)
@@ -347,9 +341,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - change mode to reply`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
var state = awaitFirstItem()
val mode = aReplyMode()
state.eventSink.invoke(MessageComposerEvent.SetMode(mode))
@@ -363,9 +355,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - cancel reply`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
var state = awaitFirstItem()
val mode = aReplyMode()
state.eventSink.invoke(MessageComposerEvent.SetMode(mode))
@@ -625,9 +615,7 @@ class MessageComposerPresenterTest {
val presenter = createPresenter(
joinedRoom,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
assertThat(initialState.textEditorState.messageHtml()).isEqualTo("")
val mode = aReplyMode()
@@ -661,9 +649,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Open attachments menu`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
assertThat(initialState.showAttachmentSourcePicker).isFalse()
initialState.eventSink(MessageComposerEvent.AddAttachment)
@@ -674,9 +660,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Dismiss attachments menu`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.AddAttachment)
skipItems(1)
@@ -717,9 +701,7 @@ class MessageComposerPresenterTest {
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.FromGallery)
onPreviewAttachmentLambda.assertions().isCalledOnce()
@@ -758,9 +740,7 @@ class MessageComposerPresenterTest {
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.FromGallery)
onPreviewAttachmentLambda.assertions().isCalledOnce()
@@ -774,9 +754,7 @@ class MessageComposerPresenterTest {
givenResult(null) // Simulate a user canceling the flow
givenMimeType(MimeTypes.Images)
}
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.FromGallery)
// No crashes here, otherwise it fails
@@ -796,9 +774,7 @@ class MessageComposerPresenterTest {
room = room,
navigator = navigator,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.FromFiles)
onPreviewAttachmentLambda.assertions().isCalledOnce()
@@ -811,9 +787,7 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.AddAttachment)
val attachmentOpenState = awaitItem()
@@ -830,9 +804,7 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.AddAttachment)
val attachmentOpenState = awaitItem()
@@ -858,9 +830,7 @@ class MessageComposerPresenterTest {
permissionPresenter = permissionPresenter,
navigator = navigator,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.PhotoFromCamera)
onPreviewAttachmentLambda.assertions().isCalledOnce()
@@ -882,9 +852,7 @@ class MessageComposerPresenterTest {
permissionPresenter = permissionPresenter,
navigator = navigator,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.PhotoFromCamera)
permissionPresenter.setPermissionGranted()
@@ -908,9 +876,7 @@ class MessageComposerPresenterTest {
permissionPresenter = permissionPresenter,
navigator = navigator,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.VideoFromCamera)
onPreviewAttachmentLambda.assertions().isCalledOnce()
@@ -932,9 +898,7 @@ class MessageComposerPresenterTest {
permissionPresenter = permissionPresenter,
navigator = navigator,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.PickAttachmentSource.VideoFromCamera)
val permissionState = awaitItem()
@@ -949,9 +913,7 @@ class MessageComposerPresenterTest {
fun `present - errors are tracked`() = runTest {
val testException = Exception("Test error")
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvent.Error(testException))
assertThat(analyticsService.trackedErrors).containsExactly(testException)
@@ -961,9 +923,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - ToggleTextFormatting toggles text formatting`() = runTest {
val presenter = createPresenter(isRichTextEditorEnabled = false)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
assertThat(initialState.showTextFormatting).isFalse()
initialState.eventSink(MessageComposerEvent.AddAttachment)
@@ -1008,9 +968,7 @@ class MessageComposerPresenterTest {
givenRoomInfo(aRoomInfo(isDirect = false))
}
val presenter = createPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
// A null suggestion (no suggestion was received) returns nothing
@@ -1062,9 +1020,7 @@ class MessageComposerPresenterTest {
givenRoomInfo(aRoomInfo(isDirect = false))
}
val presenter = createPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
// An empty suggestion returns the joined members that are not the current user, but not the room
initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "")))
@@ -1099,9 +1055,7 @@ class MessageComposerPresenterTest {
)
}
val presenter = createPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
// An empty suggestion returns the joined members that are not the current user, but not the room
initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "")))
@@ -1119,9 +1073,7 @@ class MessageComposerPresenterTest {
}
)
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.textEditorState.setHtml("Hey @bo")
initialState.eventSink(MessageComposerEvent.InsertSuggestion(ResolvedSuggestion.Member(aRoomMember(userId = A_USER_ID_2))))
@@ -1153,9 +1105,7 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
// Check intentional mentions on message sent
@@ -1242,9 +1192,7 @@ class MessageComposerPresenterTest {
typingNoticeResult = typingNoticeResult,
)
val presenter = createPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
typingNoticeResult.assertions().isNeverCalled()
initialState.eventSink.invoke(MessageComposerEvent.TypingNotice(true))
@@ -1268,9 +1216,7 @@ class MessageComposerPresenterTest {
isSendTypingNotificationsEnabled = false
)
val presenter = createPresenter(room = room, sessionPreferencesStore = store)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
typingNoticeResult.assertions().isNeverCalled()
initialState.eventSink.invoke(MessageComposerEvent.TypingNotice(true))
@@ -1286,9 +1232,7 @@ class MessageComposerPresenterTest {
this.loadDraftLambda = loadDraftLambda
}
val presenter = createPresenter(draftService = composerDraftService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
awaitFirstItem()
assert(loadDraftLambda)
.isCalledOnce()
@@ -1311,9 +1255,7 @@ class MessageComposerPresenterTest {
draftService = composerDraftService,
permalinkBuilder = permalinkBuilder,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
skipItems(2)
awaitItem().also { state ->
assertThat(state.textEditorState.messageMarkdown(permalinkBuilder)).isEqualTo(A_MESSAGE)
@@ -1344,9 +1286,7 @@ class MessageComposerPresenterTest {
draftService = composerDraftService,
permalinkBuilder = permalinkBuilder,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
skipItems(1)
awaitItem().also { state ->
assertThat(state.showTextFormatting).isTrue()
@@ -1377,9 +1317,7 @@ class MessageComposerPresenterTest {
draftService = composerDraftService,
permalinkBuilder = permalinkBuilder,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
skipItems(2)
awaitItem().also { state ->
assertThat(state.showTextFormatting).isFalse()
@@ -1423,9 +1361,7 @@ class MessageComposerPresenterTest {
draftService = composerDraftService,
permalinkBuilder = permalinkBuilder,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
skipItems(2)
awaitItem().also { state ->
assertThat(state.showTextFormatting).isFalse()
@@ -1452,9 +1388,7 @@ class MessageComposerPresenterTest {
this.saveDraftLambda = saveDraftLambda
}
val presenter = createPresenter(draftService = composerDraftService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitFirstItem()
initialState.eventSink.invoke(MessageComposerEvent.SaveDraft)
advanceUntilIdle()

View File

@@ -8,9 +8,6 @@
package io.element.android.features.messages.impl.report
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
@@ -22,6 +19,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.test
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@@ -33,9 +31,7 @@ class ReportMessagePresenterTest {
@Test
fun `presenter - initial state`() = runTest {
val presenter = createReportMessagePresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.reason).isEmpty()
assertThat(initialState.blockUser).isFalse()
@@ -46,9 +42,7 @@ class ReportMessagePresenterTest {
@Test
fun `presenter - update reason`() = runTest {
val presenter = createReportMessagePresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
val reason = "This user is making the chat very toxic."
initialState.eventSink(ReportMessageEvent.UpdateReason(reason))
@@ -60,9 +54,7 @@ class ReportMessagePresenterTest {
@Test
fun `presenter - toggle block user`() = runTest {
val presenter = createReportMessagePresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
initialState.eventSink(ReportMessageEvent.ToggleBlockUser)
@@ -83,9 +75,7 @@ class ReportMessagePresenterTest {
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
initialState.eventSink(ReportMessageEvent.ToggleBlockUser)
skipItems(1)
@@ -105,9 +95,7 @@ class ReportMessagePresenterTest {
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
initialState.eventSink(ReportMessageEvent.Report)
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
@@ -125,9 +113,7 @@ class ReportMessagePresenterTest {
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
initialState.eventSink(ReportMessageEvent.Report)
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)

View File

@@ -8,15 +8,13 @@
package io.element.android.features.messages.impl.timeline.components.customreaction
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.aTimelineItemReactions
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.recentemojis.test.FakeEmojibaseProvider
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.test.runTest
import org.junit.Rule
@@ -33,9 +31,7 @@ class CustomReactionPresenterTest {
@Test
fun `present - handle selecting and de-selecting an event`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val event = aTimelineItemEvent(eventId = AN_EVENT_ID)
val initialState = awaitItem()
assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None)
@@ -54,9 +50,7 @@ class CustomReactionPresenterTest {
@Test
fun `present - handle selected emojis`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val reactions = aTimelineItemReactions(count = 1, isHighlighted = true)
val event = aTimelineItemEvent(eventId = AN_EVENT_ID, timelineItemReactions = reactions)
val initialState = awaitItem()

View File

@@ -8,9 +8,6 @@
package io.element.android.features.messages.impl.timeline.components.reactionsummary
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.timeline.model.anAggregatedReaction
import io.element.android.libraries.matrix.api.room.RoomMembersState
@@ -21,6 +18,7 @@ import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.test.runTest
import org.junit.Rule
@@ -40,9 +38,7 @@ class ReactionSummaryPresenterTest {
@Test
fun `present - handle showing and hiding the reaction summary`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.target).isNull()
@@ -56,9 +52,7 @@ class ReactionSummaryPresenterTest {
@Test
fun `present - handle reaction summary content and avatars populated`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.target).isNull()

View File

@@ -8,12 +8,10 @@
package io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@@ -25,9 +23,7 @@ class ReadReceiptBottomSheetPresenterTest {
@Test
fun `present - handle event selected`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
val selectedEvent = aTimelineItemEvent()
initialState.eventSink(ReadReceiptBottomSheetEvent.EventSelected(selectedEvent))
@@ -38,9 +34,7 @@ class ReadReceiptBottomSheetPresenterTest {
@Test
fun `present - handle dismiss`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
val selectedEvent = aTimelineItemEvent()
initialState.eventSink(ReadReceiptBottomSheetEvent.EventSelected(selectedEvent))

View File

@@ -8,10 +8,7 @@
package io.element.android.features.messages.impl.typing
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.Event
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.JoinedRoom
@@ -26,6 +23,7 @@ import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
@@ -40,9 +38,7 @@ class TypingNotificationPresenterTest {
@Test
fun `present - initial state`() = runTest {
val presenter = createPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.renderTypingNotifications).isTrue()
assertThat(initialState.typingMembers).isEmpty()
@@ -61,9 +57,7 @@ class TypingNotificationPresenterTest {
joinedRoom = room,
sessionPreferencesStore = sessionPreferencesStore,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.renderTypingNotifications).isFalse()
@@ -95,9 +89,7 @@ class TypingNotificationPresenterTest {
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
typingMembersFlow.emit(listOf(A_USER_ID_2))
@@ -133,9 +125,7 @@ class TypingNotificationPresenterTest {
)
}
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
typingMembersFlow.emit(listOf(A_USER_ID_2))
@@ -160,9 +150,7 @@ class TypingNotificationPresenterTest {
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
typingMembersFlow.emit(listOf(A_USER_ID_2))
@@ -194,9 +182,7 @@ class TypingNotificationPresenterTest {
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
typingMembersFlow.emit(listOf(A_USER_ID_2))