diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 7bd4668ed4..2ae72c86c6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -32,6 +32,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.model.event.canBeCopied import io.element.android.features.messages.impl.timeline.model.event.canBeForwarded import io.element.android.features.messages.impl.timeline.model.event.canReact @@ -157,7 +158,9 @@ class DefaultActionListPresenter @AssistedInject constructor( add(TimelineItemAction.Edit) } else { // Caption - if (timelineItem.isMine && timelineItem.content is TimelineItemEventContentWithAttachment) { + if (timelineItem.isMine && + timelineItem.content is TimelineItemEventContentWithAttachment && + timelineItem.content !is TimelineItemVoiceContent) { if (timelineItem.content.caption == null) { add(TimelineItemAction.AddCaption) } else { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 078fb9e676..98d6ad0ec7 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.features.poll.api.pollcontent.aPollAnswerItemList import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_CAPTION import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeMatrixRoom @@ -444,8 +445,6 @@ class ActionListPresenterTest { ), ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -455,6 +454,56 @@ class ActionListPresenterTest { actions = persistentListOf( TimelineItemAction.Reply, TimelineItemAction.Forward, + TimelineItemAction.AddCaption, + TimelineItemAction.Pin, + TimelineItemAction.CopyLink, + TimelineItemAction.ViewSource, + TimelineItemAction.Redact, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + + @Test + fun `present - compute for a media with caption item`() = runTest { + val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = true, + isEditable = false, + content = aTimelineItemImageContent( + caption = A_CAPTION, + ), + ) + initialState.eventSink.invoke( + ActionListEvents.ComputeForMessage( + event = messageEvent, + userEventPermissions = aUserEventPermissions( + canRedactOwn = true, + canRedactOther = false, + canSendMessage = true, + canSendReaction = true, + canPinUnpin = true, + ), + ) + ) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + event = messageEvent, + displayEmojiReactions = true, + verifiedUserSendFailure = VerifiedUserSendFailure.None, + actions = persistentListOf( + TimelineItemAction.Reply, + TimelineItemAction.Forward, + TimelineItemAction.EditCaption, + TimelineItemAction.RemoveCaption, TimelineItemAction.Pin, TimelineItemAction.CopyLink, TimelineItemAction.ViewSource, 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 ac753f6cdb..bc61728cb1 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 @@ -60,7 +60,7 @@ class AttachmentsPreviewPresenterTest { @Test fun `present - send media success scenario`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val room = FakeMatrixRoom( @@ -192,7 +192,7 @@ class AttachmentsPreviewPresenterTest { @Test fun `present - send media failure scenario`() = runTest { val failure = MediaPreProcessor.Failure(null) - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.failure(failure) } val room = FakeMatrixRoom( 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 2e68c9b199..c1d1fd8c11 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 @@ -30,9 +30,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.core.ProgressCallback import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder @@ -58,7 +56,6 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.A_USER_ID_4 import io.element.android.libraries.matrix.test.core.aBuildMeta -import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.room.FakeMatrixRoom @@ -684,17 +681,8 @@ class MessageComposerPresenterTest { } @Test - fun `present - Pick file from storage`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> - Result.success(FakeMediaUploadHandler()) - } + fun `present - Pick file from storage will open the preview`() = runTest { val room = FakeMatrixRoom( - progressCallbackValues = listOf( - Pair(0, 10), - Pair(5, 10), - Pair(10, 10) - ), - sendFileResult = sendFileResult, typingNoticeResult = { Result.success(Unit) } ) val presenter = createPresenter(this, room = room) @@ -705,13 +693,7 @@ class MessageComposerPresenterTest { initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) val sendingState = awaitItem() assertThat(sendingState.showAttachmentSourcePicker).isFalse() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending.Processing::class.java) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(0f)) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(0.5f)) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(1f)) - val sentState = awaitItem() - assertThat(sentState.attachmentsState).isEqualTo(AttachmentsState.None) - sendFileResult.assertions().isCalledOnce() + assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) } } @@ -851,48 +833,6 @@ class MessageComposerPresenterTest { } } - @Test - fun `present - Uploading media failure can be recovered from`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> - Result.failure(Exception()) - } - val room = FakeMatrixRoom( - sendFileResult = sendFileResult, - typingNoticeResult = { Result.success(Unit) } - ) - val presenter = createPresenter(this, room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitFirstItem() - initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - val sendingState = awaitItem() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending::class.java) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.None::class.java) - snackbarDispatcher.snackbarMessage.test { - // Assert error message received - assertThat(awaitItem()).isNotNull() - } - } - } - - @Test - fun `present - CancelSendAttachment stops media upload`() = runTest { - val presenter = createPresenter(this) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitFirstItem() - initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - val sendingState = awaitItem() - assertThat(sendingState.showAttachmentSourcePicker).isFalse() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending.Processing::class.java) - sendingState.eventSink(MessageComposerEvents.CancelSendAttachment) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.None) - } - } - @Test fun `present - errors are tracked`() = runTest { val testException = Exception("Test error") diff --git a/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt b/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt index 10d42716a9..e59e2d74c8 100644 --- a/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt +++ b/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt @@ -116,7 +116,7 @@ class SharePresenterTest { @Test fun `present - send media ok`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val matrixRoom = FakeMatrixRoom( diff --git a/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt b/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt index 1cfb46c20e..39f139afec 100644 --- a/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt +++ b/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt @@ -91,7 +91,7 @@ class MediaSenderTest { @OptIn(ExperimentalCoroutinesApi::class) @Test fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val room = FakeMatrixRoom( diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index 83541624a1..8d26082157 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -101,8 +101,10 @@ class KonsistPreviewTest { "SasEmojisPreview", "SecureBackupSetupViewChangePreview", "SelectedUserCannotRemovePreview", + "TextComposerAddCaptionPreview", "TextComposerCaptionPreview", "TextComposerEditPreview", + "TextComposerEditCaptionPreview", "TextComposerFormattingPreview", "TextComposerLinkDialogCreateLinkPreview", "TextComposerLinkDialogCreateLinkWithoutTextPreview",