Merge pull request #692 from vector-im/feature/fga/room_list_api
Feature/fga/room list api
This commit is contained in:
@@ -54,8 +54,8 @@ class InviteListPresenter @Inject constructor(
|
||||
@Composable
|
||||
override fun present(): InviteListState {
|
||||
val invites by client
|
||||
.invitesDataSource
|
||||
.roomSummaries()
|
||||
.roomSummaryDataSource
|
||||
.inviteRooms()
|
||||
.collectAsState()
|
||||
|
||||
var seenInvites by remember { mutableStateOf<Set<RoomId>>(emptySet()) }
|
||||
|
||||
@@ -46,10 +46,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - starts empty, adds invites when received`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -60,7 +60,7 @@ class InviteListPresenterTests {
|
||||
val initialState = awaitItem()
|
||||
Truth.assertThat(initialState.inviteList).isEmpty()
|
||||
|
||||
invitesDataSource.postRoomSummary(listOf(aRoomSummary()))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummary()))
|
||||
|
||||
val withInviteState = awaitItem()
|
||||
Truth.assertThat(withInviteState.inviteList.size).isEqualTo(1)
|
||||
@@ -71,10 +71,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - uses user ID and avatar for direct invites`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withDirectChatInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withDirectChatInvitation()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -101,10 +101,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - includes sender details for room invites`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -129,10 +129,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - shows confirm dialog for declining direct chat invites`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withDirectChatInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withDirectChatInvitation()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -154,10 +154,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - shows confirm dialog for declining room invites`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -179,10 +179,10 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - hides confirm dialog when cancelling`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
FakeSeenInvitesStore(),
|
||||
FakeAnalyticsService(),
|
||||
@@ -204,9 +204,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - declines invite after confirming`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -230,9 +230,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - declines invite after confirming and sets state on error`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -261,9 +261,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - dismisses declining error state`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -293,9 +293,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - accepts invites and sets state on success`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -316,9 +316,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - accepts invites and sets state on error`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -341,9 +341,9 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - dismisses accepting error state`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
|
||||
val client = FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
)
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
|
||||
@@ -368,11 +368,11 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - stores seen invites when received`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val store = FakeSeenInvitesStore()
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
store,
|
||||
FakeAnalyticsService(),
|
||||
@@ -383,19 +383,19 @@ class InviteListPresenterTests {
|
||||
awaitItem()
|
||||
|
||||
// When one invite is received, that ID is saved
|
||||
invitesDataSource.postRoomSummary(listOf(aRoomSummary()))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummary()))
|
||||
|
||||
awaitItem()
|
||||
Truth.assertThat(store.getProvidedRoomIds()).isEqualTo(setOf(A_ROOM_ID))
|
||||
|
||||
// When a second is added, both are saved
|
||||
invitesDataSource.postRoomSummary(listOf(aRoomSummary(), aRoomSummary(A_ROOM_ID_2)))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummary(), aRoomSummary(A_ROOM_ID_2)))
|
||||
|
||||
awaitItem()
|
||||
Truth.assertThat(store.getProvidedRoomIds()).isEqualTo(setOf(A_ROOM_ID, A_ROOM_ID_2))
|
||||
|
||||
// When they're both dismissed, an empty set is saved
|
||||
invitesDataSource.postRoomSummary(listOf())
|
||||
roomSummaryDataSource.postInviteRooms(listOf())
|
||||
|
||||
awaitItem()
|
||||
Truth.assertThat(store.getProvidedRoomIds()).isEmpty()
|
||||
@@ -404,12 +404,12 @@ class InviteListPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - marks invite as new if they're unseen`() = runTest {
|
||||
val invitesDataSource = FakeRoomSummaryDataSource()
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val store = FakeSeenInvitesStore()
|
||||
store.publishRoomIds(setOf(A_ROOM_ID))
|
||||
val presenter = InviteListPresenter(
|
||||
FakeMatrixClient(
|
||||
invitesDataSource = invitesDataSource,
|
||||
roomSummaryDataSource = roomSummaryDataSource,
|
||||
),
|
||||
store,
|
||||
FakeAnalyticsService(),
|
||||
@@ -419,7 +419,7 @@ class InviteListPresenterTests {
|
||||
}.test {
|
||||
awaitItem()
|
||||
|
||||
invitesDataSource.postRoomSummary(listOf(aRoomSummary(), aRoomSummary(A_ROOM_ID_2)))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummary(), aRoomSummary(A_ROOM_ID_2)))
|
||||
skipItems(1)
|
||||
|
||||
val withInviteState = awaitItem()
|
||||
@@ -432,7 +432,7 @@ class InviteListPresenterTests {
|
||||
}
|
||||
|
||||
private suspend fun FakeRoomSummaryDataSource.withRoomInvitation(): FakeRoomSummaryDataSource {
|
||||
postRoomSummary(
|
||||
postInviteRooms(
|
||||
listOf(
|
||||
RoomSummary.Filled(
|
||||
RoomSummaryDetails(
|
||||
@@ -461,7 +461,7 @@ class InviteListPresenterTests {
|
||||
}
|
||||
|
||||
private suspend fun FakeRoomSummaryDataSource.withDirectChatInvitation(): FakeRoomSummaryDataSource {
|
||||
postRoomSummary(
|
||||
postInviteRooms(
|
||||
listOf(
|
||||
RoomSummary.Filled(
|
||||
RoomSummaryDetails(
|
||||
|
||||
@@ -108,7 +108,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus)
|
||||
val networkConnectionStatus by networkMonitor.connectivity.collectAsState()
|
||||
|
||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class ForwardMessagesPresenter @AssistedInject constructor(
|
||||
var results: SearchBarResultState<ImmutableList<RoomSummaryDetails>> by remember { mutableStateOf(SearchBarResultState.NotSearching()) }
|
||||
val forwardingActionState: MutableState<Async<ImmutableList<RoomId>>> = remember { mutableStateOf(Async.Uninitialized) }
|
||||
|
||||
val summaries by client.roomSummaryDataSource.roomSummaries().collectAsState()
|
||||
val summaries by client.roomSummaryDataSource.allRooms().collectAsState()
|
||||
|
||||
LaunchedEffect(query, summaries) {
|
||||
val filteredSummaries = summaries.filterIsInstance<RoomSummary.Filled>()
|
||||
|
||||
@@ -78,7 +78,7 @@ class ForwardMessagesPresenterTests {
|
||||
@Test
|
||||
fun `present - update query`() = runTest {
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource().apply {
|
||||
postRoomSummary(listOf(RoomSummary.Filled(aRoomSummaryDetail())))
|
||||
postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetail())))
|
||||
}
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val presenter = aPresenter(client = client)
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package io.element.android.features.networkmonitor.api
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface NetworkMonitor {
|
||||
val connectivity: Flow<NetworkStatus>
|
||||
val currentConnectivityStatus: NetworkStatus
|
||||
val connectivity: StateFlow<NetworkStatus>
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:OptIn(FlowPreview::class)
|
||||
|
||||
package io.element.android.features.networkmonitor.impl
|
||||
|
||||
import android.content.Context
|
||||
@@ -27,63 +29,80 @@ import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import javax.inject.Inject
|
||||
|
||||
@ContributesBinding(scope = AppScope::class)
|
||||
@SingleIn(AppScope::class)
|
||||
class NetworkMonitorImpl @Inject constructor(
|
||||
@ApplicationContext context: Context
|
||||
@ApplicationContext context: Context,
|
||||
appCoroutineScope: CoroutineScope,
|
||||
) : NetworkMonitor {
|
||||
|
||||
private val connectivityManager: ConnectivityManager = context.getSystemService(ConnectivityManager::class.java)
|
||||
|
||||
private val callback = object : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
_connectivity.value = connectivityManager.currentConnectionStatus()
|
||||
Timber.v("Connectivity status (available): ${connectivityManager.currentConnectionStatus()}")
|
||||
override val connectivity: StateFlow<NetworkStatus> = callbackFlow {
|
||||
|
||||
/**
|
||||
* Calling connectivityManager methods synchronously from the callbacks is not safe.
|
||||
* So instead we just keep the count of active networks, ie. those checking the capability request.
|
||||
* Debounce the result to avoid quick offline<->online changes.
|
||||
*/
|
||||
val callback = object : ConnectivityManager.NetworkCallback() {
|
||||
|
||||
private val activeNetworksCount = AtomicInteger(0)
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
if (activeNetworksCount.decrementAndGet() == 0) {
|
||||
trySendBlocking(NetworkStatus.Offline)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAvailable(network: Network) {
|
||||
if (activeNetworksCount.incrementAndGet() > 0) {
|
||||
trySendBlocking(NetworkStatus.Online)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
_connectivity.value = connectivityManager.currentConnectionStatus()
|
||||
Timber.v("Connectivity status (lost): ${connectivityManager.currentConnectionStatus()}")
|
||||
}
|
||||
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
_connectivity.value = connectivityManager.currentConnectionStatus()
|
||||
Timber.v("Connectivity status (changed): ${connectivityManager.currentConnectionStatus()}")
|
||||
}
|
||||
}
|
||||
|
||||
private val _connectivity = MutableStateFlow(NetworkStatus.Online)
|
||||
override val connectivity: Flow<NetworkStatus> = _connectivity
|
||||
|
||||
override val currentConnectivityStatus: NetworkStatus get() = _connectivity.value
|
||||
|
||||
init {
|
||||
listenToConnectionChanges()
|
||||
}
|
||||
|
||||
private fun listenToConnectionChanges() {
|
||||
trySendBlocking(connectivityManager.activeNetworkStatus())
|
||||
val request = NetworkRequest.Builder()
|
||||
// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
// .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
.build()
|
||||
connectivityManager.registerNetworkCallback(request, callback)
|
||||
|
||||
_connectivity.tryEmit(connectivityManager.currentConnectionStatus())
|
||||
connectivityManager.registerNetworkCallback(request, callback)
|
||||
Timber.d("Subscribe")
|
||||
awaitClose {
|
||||
Timber.d("Unsubscribe")
|
||||
connectivityManager.unregisterNetworkCallback(callback)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.debounce(300)
|
||||
.onEach {
|
||||
Timber.d("NetworkStatus changed=$it")
|
||||
}
|
||||
.stateIn(appCoroutineScope, SharingStarted.WhileSubscribed(), connectivityManager.activeNetworkStatus())
|
||||
|
||||
private fun ConnectivityManager.activeNetworkStatus(): NetworkStatus {
|
||||
return activeNetwork?.let {
|
||||
getNetworkCapabilities(it)?.getNetworkStatus()
|
||||
} ?: NetworkStatus.Offline
|
||||
}
|
||||
|
||||
private fun ConnectivityManager.currentConnectionStatus(): NetworkStatus {
|
||||
val hasInternet = activeNetwork?.let(::getNetworkCapabilities)
|
||||
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
?: false
|
||||
private fun NetworkCapabilities.getNetworkStatus(): NetworkStatus {
|
||||
val hasInternet = hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
return if (hasInternet) {
|
||||
NetworkStatus.Online
|
||||
} else {
|
||||
|
||||
@@ -18,13 +18,8 @@ package io.element.android.features.networkmonitor.test
|
||||
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class FakeNetworkMonitor(initialStatus: NetworkStatus = NetworkStatus.Online) : NetworkMonitor {
|
||||
override val currentConnectivityStatus: NetworkStatus
|
||||
get() = _connectivityStatus.value
|
||||
|
||||
private val _connectivityStatus: MutableStateFlow<NetworkStatus> = MutableStateFlow(initialStatus)
|
||||
override val connectivity: Flow<NetworkStatus> = _connectivityStatus
|
||||
override val connectivity = MutableStateFlow(initialStatus)
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ class DefaultInviteStateDataSource @Inject constructor(
|
||||
@Composable
|
||||
override fun inviteState(): InvitesState {
|
||||
val invites by client
|
||||
.invitesDataSource
|
||||
.roomSummaries()
|
||||
.roomSummaryDataSource
|
||||
.inviteRooms()
|
||||
.collectAsState()
|
||||
|
||||
val seenInvites by seenInvitesStore
|
||||
|
||||
@@ -78,10 +78,10 @@ class RoomListPresenter @Inject constructor(
|
||||
var filter by rememberSaveable { mutableStateOf("") }
|
||||
val roomSummaries by client
|
||||
.roomSummaryDataSource
|
||||
.roomSummaries()
|
||||
.allRooms()
|
||||
.collectAsState()
|
||||
|
||||
val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus)
|
||||
val networkConnectionStatus by networkMonitor.connectivity.collectAsState()
|
||||
|
||||
Timber.v("RoomSummaries size = ${roomSummaries.size}")
|
||||
|
||||
@@ -178,7 +178,7 @@ class RoomListPresenter @Inject constructor(
|
||||
// Safe to give bigger size than room list
|
||||
val extendedRangeEnd = range.last + midExtendedRangeSize
|
||||
val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd)
|
||||
client.roomSummaryDataSource.setSlidingSyncRange(extendedRange)
|
||||
client.roomSummaryDataSource.updateRoomListVisibleRange(extendedRange)
|
||||
}
|
||||
|
||||
private suspend fun mapRoomSummaries(
|
||||
|
||||
@@ -34,8 +34,8 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `emits NoInvites state if invites list is empty`() = runTest {
|
||||
val matrixDataSource = FakeRoomSummaryDataSource()
|
||||
val client = FakeMatrixClient(invitesDataSource = matrixDataSource)
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val seenStore = FakeSeenInvitesStore()
|
||||
val dataSource = DefaultInviteStateDataSource(client, seenStore, testCoroutineDispatchers())
|
||||
|
||||
@@ -48,9 +48,9 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `emits NewInvites state if unseen invite exists`() = runTest {
|
||||
val matrixDataSource = FakeRoomSummaryDataSource()
|
||||
matrixDataSource.postRoomSummary(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
val client = FakeMatrixClient(invitesDataSource = matrixDataSource)
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val seenStore = FakeSeenInvitesStore()
|
||||
val dataSource = DefaultInviteStateDataSource(client, seenStore, testCoroutineDispatchers())
|
||||
|
||||
@@ -64,9 +64,9 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `emits NewInvites state if multiple invites exist and at least one is unseen`() = runTest {
|
||||
val matrixDataSource = FakeRoomSummaryDataSource()
|
||||
matrixDataSource.postRoomSummary(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID), aRoomSummaryFilled(roomId = A_ROOM_ID_2)))
|
||||
val client = FakeMatrixClient(invitesDataSource = matrixDataSource)
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID), aRoomSummaryFilled(roomId = A_ROOM_ID_2)))
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val seenStore = FakeSeenInvitesStore()
|
||||
seenStore.publishRoomIds(setOf(A_ROOM_ID))
|
||||
val dataSource = DefaultInviteStateDataSource(client, seenStore, testCoroutineDispatchers(useUnconfinedTestDispatcher = true))
|
||||
@@ -81,9 +81,9 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `emits SeenInvites state if invite exists in seen store`() = runTest {
|
||||
val matrixDataSource = FakeRoomSummaryDataSource()
|
||||
matrixDataSource.postRoomSummary(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
val client = FakeMatrixClient(invitesDataSource = matrixDataSource)
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val seenStore = FakeSeenInvitesStore()
|
||||
seenStore.publishRoomIds(setOf(A_ROOM_ID))
|
||||
val dataSource = DefaultInviteStateDataSource(client, seenStore, testCoroutineDispatchers(useUnconfinedTestDispatcher = true))
|
||||
@@ -99,8 +99,8 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
|
||||
@Test
|
||||
fun `emits new state in response to upstream events`() = runTest {
|
||||
val matrixDataSource = FakeRoomSummaryDataSource()
|
||||
val client = FakeMatrixClient(invitesDataSource = matrixDataSource)
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val client = FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
|
||||
val seenStore = FakeSeenInvitesStore()
|
||||
val dataSource = DefaultInviteStateDataSource(client, seenStore, testCoroutineDispatchers())
|
||||
|
||||
@@ -111,7 +111,7 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NoInvites)
|
||||
|
||||
// When a single invite is received, state should be NewInvites
|
||||
matrixDataSource.postRoomSummary(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID)))
|
||||
skipItems(1)
|
||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NewInvites)
|
||||
|
||||
@@ -121,12 +121,12 @@ internal class DefaultInviteStateDataSourceTest {
|
||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.SeenInvites)
|
||||
|
||||
// Another new invite resets it to NewInvites
|
||||
matrixDataSource.postRoomSummary(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID), aRoomSummaryFilled(roomId = A_ROOM_ID_2)))
|
||||
roomSummaryDataSource.postInviteRooms(listOf(aRoomSummaryFilled(roomId = A_ROOM_ID), aRoomSummaryFilled(roomId = A_ROOM_ID_2)))
|
||||
skipItems(1)
|
||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NewInvites)
|
||||
|
||||
// All of the invites going away reverts to NoInvites
|
||||
matrixDataSource.postRoomSummary(emptyList())
|
||||
roomSummaryDataSource.postInviteRooms(emptyList())
|
||||
skipItems(1)
|
||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NoInvites)
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ class RoomListPresenterTests {
|
||||
// Room list is loaded with 16 placeholders
|
||||
Truth.assertThat(withUserState.roomList.size).isEqualTo(16)
|
||||
Truth.assertThat(withUserState.roomList.all { it.isPlaceholder }).isTrue()
|
||||
roomSummaryDataSource.postRoomSummary(listOf(aRoomSummaryFilled()))
|
||||
roomSummaryDataSource.postAllRooms(listOf(aRoomSummaryFilled()))
|
||||
skipItems(1)
|
||||
val withRoomState = awaitItem()
|
||||
Truth.assertThat(withRoomState.roomList.size).isEqualTo(1)
|
||||
@@ -174,7 +174,7 @@ class RoomListPresenterTests {
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
roomSummaryDataSource.postRoomSummary(listOf(aRoomSummaryFilled()))
|
||||
roomSummaryDataSource.postAllRooms(listOf(aRoomSummaryFilled()))
|
||||
skipItems(3)
|
||||
val loadedState = awaitItem()
|
||||
// Test filtering with result
|
||||
@@ -212,7 +212,7 @@ class RoomListPresenterTests {
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
roomSummaryDataSource.postRoomSummary(listOf(aRoomSummaryFilled()))
|
||||
roomSummaryDataSource.postAllRooms(listOf(aRoomSummaryFilled()))
|
||||
skipItems(3)
|
||||
val loadedState = awaitItem()
|
||||
// check initial value
|
||||
|
||||
Reference in New Issue
Block a user