From 15079e959f73e7410297dd8a4c7c4621bd871613 Mon Sep 17 00:00:00 2001 From: kanat Date: Fri, 23 Jun 2023 14:26:33 -0700 Subject: [PATCH] Add attachment verifier --- .../chat/android/client/ChatClient.kt | 8 +-- .../client/attachment/AttachmentsSender.kt | 4 +- .../client/attachment/AttachmentsVerifier.kt | 29 +++++++++ .../attachment/AttachmentsVerifierTests.kt | 62 +++++++++++++++++++ 4 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsVerifier.kt create mode 100644 stream-chat-android-client/src/test/java/io/getstream/chat/android/client/attachment/AttachmentsVerifierTests.kt diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt index a5520f70814..d4bba034349 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt @@ -3070,10 +3070,10 @@ internal constructor( mutableClientState = MutableClientState(module.networkStateProvider), ).apply { attachmentsSender = AttachmentsSender( - appContext, - uploadAttachmentsNetworkType, - clientState, - clientScope + context = appContext, + networkType = uploadAttachmentsNetworkType, + clientState = clientState, + scope = clientScope ) } } diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsSender.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsSender.kt index 96c36a68601..027c022c8ea 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsSender.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsSender.kt @@ -46,6 +46,7 @@ internal class AttachmentsSender( private val networkType: UploadAttachmentsNetworkType, private val clientState: ClientState, private val scope: CoroutineScope, + private val verifier: AttachmentsVerifier = AttachmentsVerifier() ) { private var jobsMap: Map = emptyMap() @@ -59,7 +60,7 @@ internal class AttachmentsSender( isRetrying: Boolean, repositoryFacade: RepositoryFacade, ): Result { - return if (!isRetrying) { + val result = if (!isRetrying) { if (message.hasPendingAttachments()) { logger.d { "[sendAttachments] Message ${message.id}" + @@ -74,6 +75,7 @@ internal class AttachmentsSender( logger.d { "[sendAttachments] Retrying Message ${message.id}" } retryMessage(message, channelType, channelId, repositoryFacade) } + return verifier.verifyAttachments(result) } /** diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsVerifier.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsVerifier.kt new file mode 100644 index 00000000000..39ac1e92a11 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/attachment/AttachmentsVerifier.kt @@ -0,0 +1,29 @@ +package io.getstream.chat.android.client.attachment + +import io.getstream.chat.android.models.Message +import io.getstream.log.taggedLogger +import io.getstream.result.Error +import io.getstream.result.Result + +internal class AttachmentsVerifier { + + private val logger by taggedLogger("Chat:AttachmentVerifier") + + internal fun verifyAttachments(result: Result): Result { + val message = result.getOrNull() ?: return result + logger.d { "[verifyAttachments] #uploader; uploadedAttachments: ${message.attachments}" } + val corruptedAttachment = message.attachments.find { + it.upload != null && it.imageUrl == null && it.assetUrl == null + } + if (corruptedAttachment != null) { + logger.e { + "[verifyAttachments] #uploader; message(${message.id}) has corrupted attachment: $corruptedAttachment" + } + return Result.Failure( + Error.GenericError("Message(${message.id}) contains corrupted attachment: $corruptedAttachment") + ) + } + return result + } + +} \ No newline at end of file diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/attachment/AttachmentsVerifierTests.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/attachment/AttachmentsVerifierTests.kt new file mode 100644 index 00000000000..79c1b463f89 --- /dev/null +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/attachment/AttachmentsVerifierTests.kt @@ -0,0 +1,62 @@ +package io.getstream.chat.android.client.attachment + +import io.getstream.chat.android.client.test.randomMessage +import io.getstream.chat.android.models.Attachment +import io.getstream.chat.android.test.TestLoggingHelper +import io.getstream.result.Result +import org.amshove.kluent.`should be equal to` +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.io.File + +internal class AttachmentsVerifierTests { + + private lateinit var verifier: AttachmentsVerifier + + @BeforeEach + fun setUp() { + verifier = AttachmentsVerifier() + + TestLoggingHelper.initialize() + } + + @Test + fun `when verify message with non-File attachment, result must be Successful`() { + /* Given */ + val locationAttachment = Attachment( + type = "location", + extraData = mutableMapOf("latitude" to 1.0, "longitude" to 2.0), + uploadState = Attachment.UploadState.Success, + ) + val message = randomMessage(attachments = arrayListOf(locationAttachment)) + val result = Result.Success(message) + + /* When */ + val verified = verifier.verifyAttachments(result) + + /* Then */ + verified.isSuccess `should be equal to` true + } + + @Test + fun `when verify message with File attachment, result must be Failure if no CDN urls`() { + /* Given */ + val fileAttachment = Attachment( + type = "audio", + mimeType = "audio/mp3", + upload = File("./some.mp3"), + assetUrl = null, + imageUrl = null, + uploadState = Attachment.UploadState.Success, + ) + val message = randomMessage(attachments = arrayListOf(fileAttachment)) + val result = Result.Success(message) + + /* When */ + val verified = verifier.verifyAttachments(result) + + /* Then */ + verified.isFailure `should be equal to` true + } + +} \ No newline at end of file