Browse Source

Tests: fix tests for media

feature/fga/small_timeline_improvements
ganfra 1 year ago
parent
commit
efee010b8c
  1. 9
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt
  2. 13
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/helper/fileExtensionAndSize.kt
  3. 8
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/AndroidLocalMediaFactory.kt
  4. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt
  5. 9
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/MediaInfo.kt
  6. 13
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt
  7. 3
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt
  8. 5
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt
  9. 1
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt
  10. 3
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt
  11. 1
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt
  12. 5
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt
  13. 45
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/util/FileExtensionExtractor.kt
  14. 10
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt
  15. 3
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/fixtures/timelineItemsFactory.kt
  16. 13
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/FakeLocalMediaFactory.kt
  17. 3
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt

9
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt

@ -120,7 +120,8 @@ class MessagesFlowNode @AssistedInject constructor( @@ -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( @@ -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( @@ -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,

13
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/helper/fileExtensionAndSize.kt

@ -16,18 +16,9 @@ @@ -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)")

8
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/AndroidLocalMediaFactory.kt

@ -20,6 +20,7 @@ import android.content.Context @@ -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 @@ -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( @@ -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( @@ -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
)
)
}

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt

@ -246,7 +246,7 @@ fun MediaFileView( @@ -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,

9
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/MediaInfo.kt

@ -25,20 +25,21 @@ data class MediaInfo( @@ -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"
)

13
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt

@ -24,6 +24,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt @@ -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 @@ -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( @@ -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( @@ -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( @@ -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,

3
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt

@ -24,9 +24,10 @@ data class TimelineItemFileContent( @@ -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)
}

5
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt

@ -33,6 +33,7 @@ fun aTimelineItemFileContent(fileName: String) = TimelineItemFileContent( @@ -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"
)

1
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt

@ -22,6 +22,7 @@ data class TimelineItemImageContent( @@ -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?,

3
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt

@ -37,5 +37,6 @@ fun aTimelineItemImageContent() = TimelineItemImageContent( @@ -37,5 +37,6 @@ fun aTimelineItemImageContent() = TimelineItemImageContent(
width = null,
height = 300,
aspectRatio = 0.5f,
formattedFileSize = "4MB"
formattedFileSize = "4MB",
fileExtension = "jpg"
)

1
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt

@ -29,6 +29,7 @@ data class TimelineItemVideoContent( @@ -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"
}

5
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt

@ -30,7 +30,7 @@ open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineI @@ -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( @@ -39,5 +39,6 @@ fun aTimelineItemVideoContent() = TimelineItemVideoContent(
height = 300,
width = 150,
mimeType = MimeTypes.Mp4,
formattedFileSize = "14MB"
formattedFileSize = "14MB",
fileExtension = "mp4"
)

45
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/util/FileExtensionExtractor.kt

@ -0,0 +1,45 @@ @@ -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('.', "")
}
}

10
features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt

@ -32,7 +32,6 @@ import io.element.android.features.messages.impl.timeline.TimelinePresenter @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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(

3
features/messages/impl/src/test/kotlin/io/element/android/features/messages/fixtures/timelineItemsFactory.kt

@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.factories.event.Timeli @@ -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 { @@ -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(),

13
features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/FakeLocalMediaFactory.kt

@ -21,10 +21,15 @@ import io.element.android.features.messages.fixtures.aLocalMedia @@ -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 @@ -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)
}

3
features/messages/impl/src/test/kotlin/io/element/android/features/messages/media/viewer/MediaViewerPresenterTest.kt

@ -42,7 +42,8 @@ import org.junit.Test @@ -42,7 +42,8 @@ import org.junit.Test
private val TESTED_MEDIA_INFO = MediaInfo(
name = "",
mimeType = "",
formattedFileSize = ""
formattedFileSize = "",
fileExtension = ""
)
class MediaViewerPresenterTest {

Loading…
Cancel
Save