From cb466911a5e903edf6a097f9fcf35b23f9ce44ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jc=20Mi=C3=B1arro?= Date: Tue, 6 Feb 2024 17:50:37 +0100 Subject: [PATCH] Ensure deleted messages are rendered with the deleteView --- .../io/getstream/chat/android/Mother.kt | 13 + .../internal/MessageListItemViewTypeMapper.kt | 14 +- .../io/getstream/chat/android/ui/Mother.kt | 43 ++++ .../MessageListItemViewTypeMapperTest.kt | 223 ++++++++++++++++++ 4 files changed, 287 insertions(+), 6 deletions(-) create mode 100644 stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/Mother.kt create mode 100644 stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapperTest.kt diff --git a/stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt b/stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt index 93f37d625ef..7e088e803aa 100644 --- a/stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt +++ b/stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt @@ -17,6 +17,7 @@ package io.getstream.chat.android import io.getstream.chat.android.models.Attachment +import io.getstream.chat.android.models.AttachmentType import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.ChannelConfig import io.getstream.chat.android.models.ChannelInfo @@ -392,6 +393,18 @@ public fun randomAttachment( ) } +public fun randomMediaAttachment(): Attachment = randomAttachment( + type = listOf( + AttachmentType.IMAGE, + AttachmentType.VIDEO, + AttachmentType.AUDIO_RECORDING, + ).random(), + titleLink = null, + ogUrl = null, + uploadState = Attachment.UploadState.Success, + extraData = mapOf("uploadId" to randomString()), +) + public fun randomMember( user: User = randomUser(), createdAt: Date? = randomDate(), diff --git a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapper.kt b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapper.kt index 3a6f52ba9a6..9189d35649d 100644 --- a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapper.kt +++ b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapper.kt @@ -85,15 +85,17 @@ internal object MessageListItemViewTypeMapper { val containsOnlyLinks = message.containsOnlyLinkAttachments() return when { - attachmentFactoryManager.canHandle(message) -> CUSTOM_ATTACHMENTS + message.isDeleted() -> MESSAGE_DELETED message.isError() && !message.isModerationBounce() -> ERROR_MESSAGE message.isSystem() -> SYSTEM_MESSAGE - message.isDeleted() -> MESSAGE_DELETED message.isGiphyEphemeral() -> GIPHY - containsGiphy -> GIPHY_ATTACHMENT - containsOnlyLinks -> LINK_ATTACHMENTS - message.isMediaAttachment() -> MEDIA_ATTACHMENT - hasAttachments -> FILE_ATTACHMENTS + hasAttachments -> when { + attachmentFactoryManager.canHandle(message) -> CUSTOM_ATTACHMENTS + containsGiphy -> GIPHY_ATTACHMENT + containsOnlyLinks -> LINK_ATTACHMENTS + message.isMediaAttachment() -> MEDIA_ATTACHMENT + else -> FILE_ATTACHMENTS + } else -> PLAIN_TEXT } } diff --git a/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/Mother.kt b/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/Mother.kt new file mode 100644 index 00000000000..1d993f0add5 --- /dev/null +++ b/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/Mother.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014-2024 Stream.io Inc. All rights reserved. + * + * Licensed under the Stream License; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://github.com/GetStream/stream-chat-android/blob/main/LICENSE + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.getstream.chat.android.ui + +import io.getstream.chat.android.models.ChannelUserRead +import io.getstream.chat.android.models.Message +import io.getstream.chat.android.randomBoolean +import io.getstream.chat.android.randomMessage +import io.getstream.chat.android.ui.common.state.messages.list.MessagePosition +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItem + +public fun randomMessageItem( + message: Message = randomMessage(), + positions: List = listOf(), + isMine: Boolean = randomBoolean(), + messageReadBy: List = listOf(), + isThreadMode: Boolean = randomBoolean(), + isMessageRead: Boolean = randomBoolean(), + showMessageFooter: Boolean = randomBoolean(), +): MessageListItem.MessageItem = + MessageListItem.MessageItem( + message = message, + positions = positions, + isMine = isMine, + messageReadBy = messageReadBy, + isThreadMode = isThreadMode, + isMessageRead = isMessageRead, + showMessageFooter = showMessageFooter, + ) diff --git a/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapperTest.kt b/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapperTest.kt new file mode 100644 index 00000000000..c1976c031ad --- /dev/null +++ b/stream-chat-android-ui-components/src/test/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/internal/MessageListItemViewTypeMapperTest.kt @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2014-2024 Stream.io Inc. All rights reserved. + * + * Licensed under the Stream License; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://github.com/GetStream/stream-chat-android/blob/main/LICENSE + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.getstream.chat.android.ui.feature.messages.list.adapter.internal + +import io.getstream.chat.android.models.Attachment +import io.getstream.chat.android.models.AttachmentType +import io.getstream.chat.android.models.MessageType +import io.getstream.chat.android.randomChannel +import io.getstream.chat.android.randomDate +import io.getstream.chat.android.randomInt +import io.getstream.chat.android.randomMediaAttachment +import io.getstream.chat.android.randomMessage +import io.getstream.chat.android.randomString +import io.getstream.chat.android.randomUser +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItem +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.DATE_DIVIDER +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.LOADING_INDICATOR +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.START_OF_THE_CHANNEL +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.THREAD_PLACEHOLDER +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.THREAD_SEPARATOR +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.TYPING_INDICATOR +import io.getstream.chat.android.ui.feature.messages.list.adapter.MessageListItemViewType.UNREAD_SEPARATOR +import io.getstream.chat.android.ui.feature.messages.list.adapter.viewholder.attachment.AttachmentFactoryManager +import io.getstream.chat.android.ui.randomMessageItem +import org.amshove.kluent.`should be equal to` +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource + +internal class MessageListItemViewTypeMapperTest { + + /** + * This method use [generateGetViewTypeValueInput] to generate input. + */ + @ParameterizedTest + @MethodSource("generateGetViewTypeValueInput") + fun `Should generate proper View Type Value`( + attachmentFactoryManager: AttachmentFactoryManager, + messageListItem: MessageListItem, + expected: Int, + ) { + val result = MessageListItemViewTypeMapper.getViewTypeValue( + messageListItem = messageListItem, + attachmentFactoryManager = attachmentFactoryManager, + ) + + result `should be equal to` expected + } + + companion object { + private val attachmentFactoryManager = AttachmentFactoryManager() + + @JvmStatic + @Suppress("LongMethod") + fun generateGetViewTypeValueInput() = listOf( + Arguments.of( + attachmentFactoryManager, + MessageListItem.DateSeparatorItem(randomDate()), + DATE_DIVIDER, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.LoadingMoreIndicatorItem, + LOADING_INDICATOR, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.ThreadSeparatorItem( + date = randomDate(), + messageCount = randomInt(), + ), + THREAD_SEPARATOR, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = randomDate(), + attachments = listOf( + Attachment( + type = randomString(), + ), + ), + ), + ), + MessageListItemViewType.MESSAGE_DELETED, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + type = MessageType.ERROR, + ), + ), + MessageListItemViewType.ERROR_MESSAGE, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + type = MessageType.SYSTEM, + ), + ), + MessageListItemViewType.SYSTEM_MESSAGE, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + type = MessageType.EPHEMERAL, + command = AttachmentType.GIPHY, + ), + ), + MessageListItemViewType.GIPHY, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = listOf(Attachment(type = randomString())), + ), + ), + MessageListItemViewType.CUSTOM_ATTACHMENTS, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = listOf( + Attachment( + type = AttachmentType.GIPHY, + titleLink = randomString(), + ), + ), + ), + ), + MessageListItemViewType.GIPHY_ATTACHMENT, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = listOf(Attachment(titleLink = randomString())), + ), + ), + MessageListItemViewType.LINK_ATTACHMENTS, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = listOf(randomMediaAttachment()), + ), + ), + MessageListItemViewType.MEDIA_ATTACHMENT, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = listOf(Attachment(type = AttachmentType.FILE)), + ), + ), + MessageListItemViewType.FILE_ATTACHMENTS, + ), + Arguments.of( + attachmentFactoryManager, + randomMessageItem( + message = randomMessage( + deletedAt = null, + attachments = emptyList(), + ), + ), + MessageListItemViewType.PLAIN_TEXT, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.TypingItem( + users = listOf(randomUser()), + ), + TYPING_INDICATOR, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.ThreadPlaceholderItem, + THREAD_PLACEHOLDER, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.UnreadSeparatorItem(randomInt()), + UNREAD_SEPARATOR, + ), + Arguments.of( + attachmentFactoryManager, + MessageListItem.StartOfTheChannelItem(randomChannel()), + START_OF_THE_CHANNEL, + ), + ) + } +}