Add test on SpaceRoomCache and fix implementation

This commit is contained in:
Benoit Marty 2025-09-10 18:18:16 +02:00
parent c982279d5c
commit 959cb4f0b3
3 changed files with 60 additions and 12 deletions

View file

@ -47,6 +47,7 @@ dependencies {
testImplementation(projects.libraries.featureflag.test)
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.libraries.preferences.test)
testImplementation(projects.libraries.previewutils)
testImplementation(projects.libraries.sessionStorage.test)
testImplementation(projects.services.analytics.test)
testImplementation(projects.services.toolbox.test)

View file

@ -11,31 +11,32 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.util.concurrent.ConcurrentHashMap
/**
* An in memory cache of space rooms.
* Only caches Rooms with roomType [io.element.android.libraries.matrix.api.room.RoomType.Space].
*/
class SpaceRoomCache {
private val inMemoryCache = MutableStateFlow<MutableMap<RoomId, SpaceRoom>>(LinkedHashMap())
private val inMemoryCache = ConcurrentHashMap<RoomId, MutableStateFlow<SpaceRoom?>>()
private val mutex = Mutex()
fun getSpaceRoomFlow(roomId: RoomId): Flow<SpaceRoom?> {
return inMemoryCache.map { it[roomId] }
return getMutableFlow(roomId).asStateFlow()
}
suspend fun update(spaceRooms: List<SpaceRoom>) = mutex.withLock {
inMemoryCache.update { cache ->
spaceRooms
.filter { it.isSpace }
.forEach { spaceRoom ->
cache.put(spaceRoom.roomId, spaceRoom)
}
cache
}
spaceRooms
.filter { it.isSpace }
.forEach { spaceRoom ->
getMutableFlow(spaceRoom.roomId).value = spaceRoom
}
}
private fun getMutableFlow(roomId: RoomId): MutableStateFlow<SpaceRoom?> {
return inMemoryCache.getOrPut(roomId, { MutableStateFlow(null) })
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.spaces
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
import io.element.android.libraries.previewutils.room.aSpaceRoom
import kotlinx.coroutines.test.runTest
import org.junit.Test
class SpaceRoomCacheTest {
@Test
fun `getSpaceRoomFlow emits items`() = runTest {
val sut = SpaceRoomCache()
sut.getSpaceRoomFlow(A_ROOM_ID).test {
assertThat(awaitItem()).isNull()
val room = aSpaceRoom(
roomId = A_ROOM_ID,
roomType = RoomType.Room,
)
sut.update(listOf(room))
// Not a space, should not be cached
expectNoEvents()
val space = aSpaceRoom(
roomId = A_ROOM_ID,
roomType = RoomType.Space,
)
sut.update(listOf(space))
assertThat(awaitItem()).isEqualTo(space)
val spaceOther = aSpaceRoom(
roomId = A_ROOM_ID_2,
roomType = RoomType.Space,
)
sut.update(listOf(spaceOther))
expectNoEvents()
}
}
}