From 4d997a88dbe554312972a54aeb8c280be13f6a67 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 10 Dec 2024 16:07:27 +0100 Subject: [PATCH] Add unit test on MediaItemsPostProcessor --- .../impl/gallery/MediaGalleryStateProvider.kt | 10 +- .../impl/gallery/MediaItemsPostProcessor.kt | 12 +- .../ui/MediaItemDateSeparatorProvider.kt | 6 +- .../gallery/MediaItemsPostProcessorTest.kt | 210 ++++++++++++++++++ 4 files changed, 228 insertions(+), 10 deletions(-) create mode 100644 libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaItemsPostProcessorTest.kt diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryStateProvider.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryStateProvider.kt index 481e200f04..58d566dddd 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryStateProvider.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryStateProvider.kt @@ -12,7 +12,7 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.details.aMediaDetailsBottomSheetState -import io.element.android.libraries.mediaviewer.impl.gallery.ui.aDate +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemDateSeparator import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemFile import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemLoadingIndicator @@ -29,9 +29,9 @@ open class MediaGalleryStateProvider : PreviewParameterProvider { - imageAndVideoItemsSubList.add(item) + imageAndVideoItemsSubList.add(0, item) } is MediaItem.File -> { - fileItemsSublist.add(item) + fileItemsSublist.add(0, item) } } } @@ -67,6 +67,14 @@ class MediaItemsPostProcessor @Inject constructor() { } } } + if (imageAndVideoItemsSubList.isNotEmpty()) { + // Should not happen, since the SDK is always adding a date separator + imageAndVideoItems.addAll(imageAndVideoItemsSubList) + } + if (fileItemsSublist.isNotEmpty()) { + // Should not happen, since the SDK is always adding a date separator + fileItems.addAll(fileItemsSublist) + } return GroupedMediaItems( imageAndVideoItems = imageAndVideoItems.toImmutableList(), fileItems = fileItems.toImmutableList(), diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/MediaItemDateSeparatorProvider.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/MediaItemDateSeparatorProvider.kt index 2d7c3d50ab..32169751f0 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/MediaItemDateSeparatorProvider.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/MediaItemDateSeparatorProvider.kt @@ -14,12 +14,12 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem class MediaItemDateSeparatorProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( - aDate(), - aDate(formattedDate = "A long date that should be truncated"), + aMediaItemDateSeparator(), + aMediaItemDateSeparator(formattedDate = "A long date that should be truncated"), ) } -fun aDate( +fun aMediaItemDateSeparator( id: UniqueId = UniqueId("dateId"), formattedDate: String = "October 2024", ): MediaItem.DateSeparator { diff --git a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaItemsPostProcessorTest.kt b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaItemsPostProcessorTest.kt new file mode 100644 index 0000000000..75a911f1dc --- /dev/null +++ b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaItemsPostProcessorTest.kt @@ -0,0 +1,210 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.mediaviewer.impl.gallery + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.matrix.api.core.UniqueId +import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemDateSeparator +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemFile +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemImage +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemLoadingIndicator +import io.element.android.libraries.mediaviewer.impl.gallery.ui.aMediaItemVideo +import kotlinx.collections.immutable.toImmutableList +import org.junit.Test + +class MediaItemsPostProcessorTest { + private val file1 = aMediaItemFile(id = UniqueId("1")) + private val file2 = aMediaItemFile(id = UniqueId("2")) + private val file3 = aMediaItemFile(id = UniqueId("3")) + private val image1 = aMediaItemImage(id = UniqueId("1")) + private val image2 = aMediaItemImage(id = UniqueId("2")) + private val image3 = aMediaItemImage(id = UniqueId("3")) + private val video1 = aMediaItemVideo(id = UniqueId("1")) + private val video2 = aMediaItemVideo(id = UniqueId("2")) + private val video3 = aMediaItemVideo(id = UniqueId("3")) + private val date1 = aMediaItemDateSeparator(id = UniqueId("1")) + private val date2 = aMediaItemDateSeparator(id = UniqueId("2")) + private val date3 = aMediaItemDateSeparator(id = UniqueId("3")) + private val loading1 = aMediaItemLoadingIndicator(id = UniqueId("1")) + + @Test + fun `process Uninitialized`() { + val sut = MediaItemsPostProcessor() + val result = sut.process(AsyncData.Uninitialized) + assertThat(result).isEqualTo(AsyncData.Uninitialized) + } + + @Test + fun `process Loading`() { + val sut = MediaItemsPostProcessor() + val result = sut.process(AsyncData.Loading()) + assertThat(result).isEqualTo(AsyncData.Loading()) + } + + @Test + fun `process Failure`() { + val sut = MediaItemsPostProcessor() + val result = sut.process(AsyncData.Failure(AN_EXCEPTION)) + assertThat(result).isEqualTo(AsyncData.Failure(AN_EXCEPTION)) + } + + @Test + fun `process Empty`() { + test( + mediaItems = listOf(), + expectedImageAndVideoItems = emptyList(), + expectedFileItems = emptyList(), + ) + } + + @Test + fun `process will reorder files`() { + test( + mediaItems = listOf( + file3, + file2, + file1, + date1, + ), + expectedImageAndVideoItems = emptyList(), + expectedFileItems = listOf( + date1, + file1, + file2, + file3, + ), + ) + } + + @Test + fun `process will reorder images`() { + test( + mediaItems = listOf( + image3, + image2, + image1, + date1, + ), + expectedImageAndVideoItems = listOf( + date1, + image1, + image2, + image3, + ), + expectedFileItems = emptyList(), + ) + } + + @Test + fun `process will split images, videos and files`() { + test( + mediaItems = listOf( + file1, + image1, + video1, + date1, + ), + expectedImageAndVideoItems = listOf( + date1, + video1, + image1, + ), + expectedFileItems = listOf( + date1, + file1, + ), + ) + } + + @Test + fun `process will skip date if there is no items`() { + test( + mediaItems = listOf( + date1, + date2, + date3, + ), + expectedImageAndVideoItems = emptyList(), + expectedFileItems = emptyList(), + ) + } + + @Test + fun `process will add the loading indicator to both list`() { + test( + mediaItems = listOf( + loading1, + ), + expectedImageAndVideoItems = listOf( + loading1, + ), + expectedFileItems = listOf( + loading1, + ), + ) + } + + @Test + fun `process will handle complex case`() { + test( + mediaItems = listOf( + file1, + image1, + video1, + date1, + file3, + date3, + video3, + video2, + date2, + loading1, + ), + expectedImageAndVideoItems = listOf( + date1, + video1, + image1, + date2, + video2, + video3, + loading1, + ), + expectedFileItems = listOf( + date1, + file1, + date3, + file3, + loading1, + ), + ) + } + + private fun test( + mediaItems: List, + expectedImageAndVideoItems: List, + expectedFileItems: List, + ) { + val sut = MediaItemsPostProcessor() + val result = sut.process(AsyncData.Success(mediaItems.toImmutableList())) + val data = result.dataOrNull()!! + + // Compare the lists to have better failure info + assertThat(data.imageAndVideoItems.toList()).isEqualTo(expectedImageAndVideoItems) + assertThat(data.fileItems.toList()).isEqualTo(expectedFileItems) + + assertThat(result).isEqualTo( + AsyncData.Success( + GroupedMediaItems( + imageAndVideoItems = expectedImageAndVideoItems.toImmutableList(), + fileItems = expectedFileItems.toImmutableList(), + ) + ) + ) + } +}