diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt index ce30f587c3..9110ab6818 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt @@ -677,7 +677,7 @@ class RoomListPresenterTest { } class FakeDateTimeObserver : DateTimeObserver { - override val changes = MutableSharedFlow() + override val changes = MutableSharedFlow(extraBufferCapacity = 1) fun given(event: DateTimeObserver.Event) { changes.tryEmit(event) diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSourceTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSourceTest.kt new file mode 100644 index 0000000000..ce6321b278 --- /dev/null +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSourceTest.kt @@ -0,0 +1,104 @@ +/* + * 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.features.roomlist.impl.datasource + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.features.roomlist.impl.FakeDateTimeObserver +import io.element.android.libraries.androidutils.system.DateTimeObserver +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter +import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter +import io.element.android.libraries.matrix.api.roomlist.RoomListService +import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService +import io.element.android.libraries.matrix.test.room.aRoomSummary +import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService +import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Test +import java.time.Instant + +class RoomListDataSourceTest { + @Test + fun `when DateTimeObserver gets a date change, the room summaries are refreshed`() = runTest { + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Running) + postAllRooms(listOf(aRoomSummary())) + } + val dateTimeObserver = FakeDateTimeObserver() + val roomListDataSource = createRoomListDataSource(roomListService = roomListService, dateTimeObserver = dateTimeObserver) + + roomListDataSource.allRooms.test { + // Observe room list items changes + roomListDataSource.launchIn(backgroundScope) + + // Get the initial room list + val initialRoomList = awaitItem() + assertThat(initialRoomList).isNotEmpty() + + // Trigger a date change + dateTimeObserver.given(DateTimeObserver.Event.DateChanged(Instant.MIN, Instant.now())) + + // Check there is a new list and it's not the same as the previous one (although it has the same content) + val newRoomList = awaitItem() + assertThat(newRoomList).isNotSameInstanceAs(initialRoomList) + + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `when DateTimeObserver gets a time zone change, the room summaries are refreshed`() = runTest { + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Running) + postAllRooms(listOf(aRoomSummary())) + } + val dateTimeObserver = FakeDateTimeObserver() + val roomListDataSource = createRoomListDataSource(roomListService = roomListService, dateTimeObserver = dateTimeObserver) + + roomListDataSource.allRooms.test { + // Observe room list items changes + roomListDataSource.launchIn(backgroundScope) + + // Get the initial room list + val initialRoomList = awaitItem() + assertThat(initialRoomList).isNotEmpty() + + // Trigger a timezone change + dateTimeObserver.given(DateTimeObserver.Event.TimeZoneChanged) + + // Check there is a new list and it's not the same as the previous one (although it has the same content) + val newRoomList = awaitItem() + assertThat(newRoomList).isNotSameInstanceAs(initialRoomList) + + cancelAndIgnoreRemainingEvents() + } + } + + private fun TestScope.createRoomListDataSource( + roomListService: FakeRoomListService = FakeRoomListService(), + roomListRoomSummaryFactory: RoomListRoomSummaryFactory = + RoomListRoomSummaryFactory( + lastMessageTimestampFormatter = LastMessageTimestampFormatter { _ -> "Yesterday" }, + roomLastMessageFormatter = RoomLastMessageFormatter { _, _ -> "Hey" } + ), + dispatchers: CoroutineDispatchers = testCoroutineDispatchers(), + notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), + appScope: CoroutineScope = backgroundScope, + dateTimeObserver: FakeDateTimeObserver = FakeDateTimeObserver(), + ) = RoomListDataSource( + roomListService = roomListService, + roomListRoomSummaryFactory = roomListRoomSummaryFactory, + coroutineDispatchers = dispatchers, + notificationSettingsService = notificationSettingsService, + appScope = appScope, + dateTimeObserver = dateTimeObserver, + ) +} diff --git a/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/LastMessageTimestampFormatter.kt b/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/LastMessageTimestampFormatter.kt index b3f82b1efe..c5b9778669 100644 --- a/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/LastMessageTimestampFormatter.kt +++ b/libraries/dateformatter/api/src/main/kotlin/io/element/android/libraries/dateformatter/api/LastMessageTimestampFormatter.kt @@ -7,6 +7,6 @@ package io.element.android.libraries.dateformatter.api -interface LastMessageTimestampFormatter { +fun interface LastMessageTimestampFormatter { fun format(timestamp: Long?): String } diff --git a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt index e5eabdb9d4..e6815e5bcf 100644 --- a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt +++ b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt @@ -9,6 +9,6 @@ package io.element.android.libraries.eventformatter.api import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem -interface RoomLastMessageFormatter { +fun interface RoomLastMessageFormatter { fun format(event: EventTimelineItem, isDmRoom: Boolean): CharSequence? }