Tests: fix tests for media
This commit is contained in:
@@ -120,7 +120,8 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
mimeType = event.content.mimeType,
|
||||
formattedFileSize = event.content.formattedFileSize
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = event.content.mediaSource,
|
||||
thumbnailSource = event.content.mediaSource,
|
||||
@@ -133,7 +134,8 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
mimeType = event.content.mimeType,
|
||||
formattedFileSize = event.content.formattedFileSize
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = mediaSource,
|
||||
thumbnailSource = event.content.thumbnailSource,
|
||||
@@ -146,7 +148,8 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
mimeType = event.content.mimeType,
|
||||
formattedFileSize = event.content.formattedFileSize
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = mediaSource,
|
||||
thumbnailSource = event.content.thumbnailSource,
|
||||
|
||||
@@ -16,18 +16,9 @@
|
||||
|
||||
package io.element.android.features.messages.impl.media.helper
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
|
||||
fun formatFileExtensionAndSize(name: String, size: String?): String {
|
||||
val fileExtension = name.substringAfterLast('.', "")
|
||||
// Makes sure the extension is known by the system, otherwise default to binary extension.
|
||||
val safeExtension = if (MimeTypeMap.getSingleton().hasExtension(fileExtension)) {
|
||||
fileExtension.uppercase()
|
||||
} else {
|
||||
"BIN"
|
||||
}
|
||||
fun formatFileExtensionAndSize(extension: String, size: String?): String {
|
||||
return buildString {
|
||||
append(safeExtension)
|
||||
append(extension.uppercase())
|
||||
if (size != null) {
|
||||
append(' ')
|
||||
append("($size)")
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.features.messages.impl.timeline.util.FileExtensionExtractor
|
||||
import io.element.android.features.messages.impl.timeline.util.FileSizeFormatter
|
||||
import io.element.android.libraries.androidutils.file.getFileName
|
||||
import io.element.android.libraries.androidutils.file.getFileSize
|
||||
@@ -35,6 +36,7 @@ import javax.inject.Inject
|
||||
class AndroidLocalMediaFactory @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val fileSizeFormatter: FileSizeFormatter,
|
||||
private val fileExtensionExtractor: FileExtensionExtractor,
|
||||
) : LocalMediaFactory {
|
||||
|
||||
override fun createFromMediaFile(mediaFile: MediaFile, mediaInfo: MediaInfo): LocalMedia {
|
||||
@@ -43,7 +45,7 @@ class AndroidLocalMediaFactory @Inject constructor(
|
||||
uri = uri,
|
||||
mimeType = mediaInfo.mimeType,
|
||||
name = mediaInfo.name,
|
||||
formattedFileSize = mediaInfo.formattedFileSize
|
||||
formattedFileSize = mediaInfo.formattedFileSize,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,12 +58,14 @@ class AndroidLocalMediaFactory @Inject constructor(
|
||||
val resolvedMimeType = mimeType ?: context.getMimeType(uri) ?: MimeTypes.OctetStream
|
||||
val fileName = name ?: context.getFileName(uri) ?: ""
|
||||
val fileSize = formattedFileSize ?: fileSizeFormatter.format(context.getFileSize(uri))
|
||||
val fileExtension = fileExtensionExtractor.extractFromName(fileName)
|
||||
return LocalMedia(
|
||||
uri = uri,
|
||||
info = MediaInfo(
|
||||
mimeType = resolvedMimeType,
|
||||
name = fileName,
|
||||
formattedFileSize = fileSize
|
||||
formattedFileSize = fileSize,
|
||||
fileExtension = fileExtension
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ fun MediaFileView(
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = formatFileExtensionAndSize(info.name, info.formattedFileSize),
|
||||
text = formatFileExtensionAndSize(info.fileExtension, info.formattedFileSize),
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
||||
@@ -25,20 +25,21 @@ data class MediaInfo(
|
||||
val name: String,
|
||||
val mimeType: String,
|
||||
val formattedFileSize: String,
|
||||
val fileExtension: String,
|
||||
) : Parcelable
|
||||
|
||||
fun anImageInfo(): MediaInfo = MediaInfo(
|
||||
"an image file.jpg", MimeTypes.Jpeg, "4MB"
|
||||
"an image file.jpg", MimeTypes.Jpeg, "4MB","jpg"
|
||||
)
|
||||
|
||||
fun aVideoInfo(): MediaInfo = MediaInfo(
|
||||
"a video file.mp4", MimeTypes.Mp4, "14MB"
|
||||
"a video file.mp4", MimeTypes.Mp4, "14MB", "mp4"
|
||||
)
|
||||
|
||||
fun aPdfInfo(): MediaInfo = MediaInfo(
|
||||
"a pdf file.pdf", MimeTypes.Pdf, "23MB"
|
||||
"a pdf file.pdf", MimeTypes.Pdf, "23MB", "pdf"
|
||||
)
|
||||
|
||||
fun aFileInfo(): MediaInfo = MediaInfo(
|
||||
"an apk file.apk", MimeTypes.Apk, "50MB"
|
||||
"an apk file.apk", MimeTypes.Apk, "50MB", "apk"
|
||||
)
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
|
||||
import io.element.android.features.messages.impl.timeline.util.FileExtensionExtractor
|
||||
import io.element.android.features.messages.impl.timeline.util.FileSizeFormatter
|
||||
import io.element.android.features.messages.impl.timeline.util.toHtmlDocument
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
@@ -37,7 +38,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageT
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemContentMessageFactory @Inject constructor(
|
||||
private val fileSizeFormatter: FileSizeFormatter
|
||||
private val fileSizeFormatter: FileSizeFormatter,
|
||||
private val fileExtensionExtractor: FileExtensionExtractor,
|
||||
) {
|
||||
|
||||
fun create(content: MessageContent): TimelineItemEventContent {
|
||||
@@ -57,7 +59,8 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
width = messageType.info?.width?.toInt(),
|
||||
height = messageType.info?.height?.toInt(),
|
||||
aspectRatio = aspectRatio,
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0)
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0),
|
||||
fileExtension = fileExtensionExtractor.extractFromName(messageType.body)
|
||||
)
|
||||
}
|
||||
is VideoMessageType -> {
|
||||
@@ -72,7 +75,8 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
duration = messageType.info?.duration ?: 0L,
|
||||
blurHash = messageType.info?.blurhash,
|
||||
aspectRatio = aspectRatio,
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0)
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0),
|
||||
fileExtension = fileExtensionExtractor.extractFromName(messageType.body)
|
||||
)
|
||||
}
|
||||
is FileMessageType -> TimelineItemFileContent(
|
||||
@@ -80,7 +84,8 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
fileSource = messageType.source,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0)
|
||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0),
|
||||
fileExtension = fileExtensionExtractor.extractFromName(messageType.body)
|
||||
)
|
||||
is NoticeMessageType -> TimelineItemNoticeContent(
|
||||
body = messageType.body,
|
||||
|
||||
@@ -24,9 +24,10 @@ data class TimelineItemFileContent(
|
||||
val fileSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val formattedFileSize: String,
|
||||
val fileExtension: String,
|
||||
val mimeType: String,
|
||||
) : TimelineItemEventContent {
|
||||
override val type: String = "TimelineItemFileContent"
|
||||
|
||||
val fileExtensionAndSize = formatFileExtensionAndSize(body, formattedFileSize)
|
||||
val fileExtensionAndSize = formatFileExtensionAndSize(fileExtension, formattedFileSize)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ fun aTimelineItemFileContent(fileName: String) = TimelineItemFileContent(
|
||||
body = fileName,
|
||||
thumbnailSource = MediaSource(url = ""),
|
||||
fileSource = MediaSource(url = ""),
|
||||
mimeType = MimeTypes.OctetStream,
|
||||
formattedFileSize = "100kB"
|
||||
mimeType = MimeTypes.Apk,
|
||||
formattedFileSize = "100kB",
|
||||
fileExtension = "apk"
|
||||
)
|
||||
|
||||
@@ -22,6 +22,7 @@ data class TimelineItemImageContent(
|
||||
val body: String,
|
||||
val mediaSource: MediaSource,
|
||||
val formattedFileSize: String,
|
||||
val fileExtension: String,
|
||||
val mimeType: String,
|
||||
val blurhash: String?,
|
||||
val width: Int?,
|
||||
|
||||
@@ -37,5 +37,6 @@ fun aTimelineItemImageContent() = TimelineItemImageContent(
|
||||
width = null,
|
||||
height = 300,
|
||||
aspectRatio = 0.5f,
|
||||
formattedFileSize = "4MB"
|
||||
formattedFileSize = "4MB",
|
||||
fileExtension = "jpg"
|
||||
)
|
||||
|
||||
@@ -29,6 +29,7 @@ data class TimelineItemVideoContent(
|
||||
val width: Int?,
|
||||
val mimeType: String,
|
||||
val formattedFileSize: String,
|
||||
val fileExtension: String,
|
||||
) : TimelineItemEventContent {
|
||||
override val type: String = "TimelineItemImageContent"
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineI
|
||||
}
|
||||
|
||||
fun aTimelineItemVideoContent() = TimelineItemVideoContent(
|
||||
body = "a video",
|
||||
body = "Video.mp4",
|
||||
thumbnailSource = MediaSource(url = ""),
|
||||
blurHash = "TQF5:I_NtRE4kXt7Z#MwkCIARPjr",
|
||||
aspectRatio = 0.5f,
|
||||
@@ -39,5 +39,6 @@ fun aTimelineItemVideoContent() = TimelineItemVideoContent(
|
||||
height = 300,
|
||||
width = 150,
|
||||
mimeType = MimeTypes.Mp4,
|
||||
formattedFileSize = "14MB"
|
||||
formattedFileSize = "14MB",
|
||||
fileExtension = "mp4"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.element.android.features.messages.impl.timeline.util
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import javax.inject.Inject
|
||||
|
||||
interface FileExtensionExtractor {
|
||||
fun extractFromName(name: String): String
|
||||
}
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class FileExtensionExtractorWithValidation @Inject constructor() : FileExtensionExtractor {
|
||||
override fun extractFromName(name: String): String {
|
||||
val fileExtension = name.substringAfterLast('.', "")
|
||||
// Makes sure the extension is known by the system, otherwise default to binary extension.
|
||||
return if (MimeTypeMap.getSingleton().hasExtension(fileExtension)) {
|
||||
fileExtension
|
||||
} else {
|
||||
"bin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FileExtensionExtractorWithoutValidation : FileExtensionExtractor {
|
||||
override fun extractFromName(name: String): String {
|
||||
return name.substringAfterLast('.', "")
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import io.element.android.features.messages.impl.timeline.TimelinePresenter
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
|
||||
import io.element.android.features.messages.impl.utils.messagesummary.MessageSummaryFormatterImpl
|
||||
import io.element.android.features.messages.media.FakeLocalMediaFactory
|
||||
import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter
|
||||
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
|
||||
@@ -145,6 +144,8 @@ class MessagesPresenterTest {
|
||||
width = 20,
|
||||
height = 20,
|
||||
aspectRatio = 1.0f,
|
||||
fileExtension = "jpg",
|
||||
formattedFileSize = "4MB"
|
||||
)
|
||||
)
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage))
|
||||
@@ -175,6 +176,8 @@ class MessagesPresenterTest {
|
||||
width = 20,
|
||||
height = 20,
|
||||
aspectRatio = 1.0f,
|
||||
fileExtension = "mp4",
|
||||
formattedFileSize = "50MB"
|
||||
)
|
||||
)
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage))
|
||||
@@ -196,11 +199,12 @@ class MessagesPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
val mediaMessage = aMessageEvent(
|
||||
content = TimelineItemFileContent(
|
||||
body = "video.mp4",
|
||||
body = "video.pdf",
|
||||
fileSource = MediaSource(AN_AVATAR_URL),
|
||||
thumbnailSource = MediaSource(AN_AVATAR_URL),
|
||||
formattedFileSize = "10 MB",
|
||||
mimeType = MimeTypes.Pdf,
|
||||
fileExtension = "pdf",
|
||||
)
|
||||
)
|
||||
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage))
|
||||
@@ -276,7 +280,7 @@ class MessagesPresenterTest {
|
||||
mediaPickerProvider = FakePickerProvider(),
|
||||
featureFlagService = FakeFeatureFlagService(),
|
||||
localMediaFactory = FakeLocalMediaFactory(mockMediaUrl),
|
||||
mediaSender = MediaSender(FakeMediaPreProcessor(),matrixRoom),
|
||||
mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom),
|
||||
snackbarDispatcher = SnackbarDispatcher(),
|
||||
)
|
||||
val timelinePresenter = TimelinePresenter(
|
||||
|
||||
@@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.factories.event.Timeli
|
||||
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemDaySeparatorFactory
|
||||
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemVirtualFactory
|
||||
import io.element.android.features.messages.impl.timeline.groups.TimelineItemGrouper
|
||||
import io.element.android.features.messages.impl.timeline.util.FileExtensionExtractorWithoutValidation
|
||||
import io.element.android.features.messages.timeline.FakeFileSizeFormatter
|
||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||
import io.element.android.libraries.eventformatter.api.TimelineEventFormatter
|
||||
@@ -43,7 +44,7 @@ internal fun aTimelineItemsFactory(): TimelineItemsFactory {
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
eventItemFactory = TimelineItemEventFactory(
|
||||
TimelineItemContentFactory(
|
||||
messageFactory = TimelineItemContentMessageFactory(FakeFileSizeFormatter()),
|
||||
messageFactory = TimelineItemContentMessageFactory(FakeFileSizeFormatter(), FileExtensionExtractorWithoutValidation()),
|
||||
redactedMessageFactory = TimelineItemContentRedactedFactory(),
|
||||
stickerFactory = TimelineItemContentStickerFactory(),
|
||||
utdFactory = TimelineItemContentUTDFactory(),
|
||||
|
||||
@@ -21,10 +21,15 @@ import io.element.android.features.messages.fixtures.aLocalMedia
|
||||
import io.element.android.features.messages.impl.media.local.LocalMedia
|
||||
import io.element.android.features.messages.impl.media.local.LocalMediaFactory
|
||||
import io.element.android.features.messages.impl.media.local.MediaInfo
|
||||
import io.element.android.features.messages.impl.timeline.util.FileExtensionExtractor
|
||||
import io.element.android.features.messages.impl.timeline.util.FileExtensionExtractorWithoutValidation
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
import io.element.android.libraries.matrix.api.media.MediaFile
|
||||
|
||||
class FakeLocalMediaFactory(private val localMediaUri: Uri) : LocalMediaFactory {
|
||||
class FakeLocalMediaFactory(
|
||||
private val localMediaUri: Uri,
|
||||
private val fileExtensionExtractor: FileExtensionExtractor = FileExtensionExtractorWithoutValidation()
|
||||
) : LocalMediaFactory {
|
||||
|
||||
var fallbackMimeType: String = MimeTypes.OctetStream
|
||||
var fallbackName: String = "File name"
|
||||
@@ -35,10 +40,12 @@ class FakeLocalMediaFactory(private val localMediaUri: Uri) : LocalMediaFactory
|
||||
}
|
||||
|
||||
override fun createFromUri(uri: Uri, mimeType: String?, name: String?, formattedFileSize: String?): LocalMedia {
|
||||
val safeName = name ?: fallbackName
|
||||
val mediaInfo = MediaInfo(
|
||||
name = name ?: fallbackName,
|
||||
name = safeName,
|
||||
mimeType = mimeType ?: fallbackMimeType,
|
||||
formattedFileSize = formattedFileSize ?: fallbackFileSize
|
||||
formattedFileSize = formattedFileSize ?: fallbackFileSize,
|
||||
fileExtension = fileExtensionExtractor.extractFromName(safeName)
|
||||
)
|
||||
return aLocalMedia(uri, mediaInfo)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ import org.junit.Test
|
||||
private val TESTED_MEDIA_INFO = MediaInfo(
|
||||
name = "",
|
||||
mimeType = "",
|
||||
formattedFileSize = ""
|
||||
formattedFileSize = "",
|
||||
fileExtension = ""
|
||||
)
|
||||
|
||||
class MediaViewerPresenterTest {
|
||||
|
||||
Reference in New Issue
Block a user