From 847e62a5ac9d90f8915ea9d0a64065e2843e2d9e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 27 Jan 2026 10:08:25 +0100 Subject: [PATCH] Use presenter test extension. --- .../AttachmentsPreviewPresenterTest.kt | 51 ++----- ...tMediaOptimizationSelectorPresenterTest.kt | 40 ++---- .../MessageComposerPresenterTest.kt | 132 +++++------------- .../impl/report/ReportMessagePresenterTest.kt | 28 +--- .../CustomReactionPresenterTest.kt | 12 +- .../ReactionSummaryPresenterTest.kt | 12 +- .../ReadReceiptBottomSheetPresenterTest.kt | 12 +- .../typing/TypingNotificationPresenterTest.kt | 28 +--- 8 files changed, 78 insertions(+), 237 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt index 1e4bea0b4a..384b78471d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt @@ -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 diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt index 96cc93ea3d..106fff7375 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt @@ -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() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 2feafbc9e5..e16236f109 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -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() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTest.kt index 0bc9cd6585..69cf3b04cd 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTest.kt @@ -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) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenterTest.kt index f5d854b463..e3317b3d42 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/CustomReactionPresenterTest.kt @@ -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() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenterTest.kt index 4621a87e75..f42f47adc3 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryPresenterTest.kt @@ -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() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheetPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheetPresenterTest.kt index 0a10188f48..91c89ec89e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheetPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheetPresenterTest.kt @@ -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)) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/typing/TypingNotificationPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/typing/TypingNotificationPresenterTest.kt index 896c529ed1..62e596bc21 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/typing/TypingNotificationPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/typing/TypingNotificationPresenterTest.kt @@ -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>(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>(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>(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))