Skip to content

Commit d1be434

Browse files
committed
Add test on RustRoomDirectoryList
1 parent a7d4bab commit d1be434

File tree

4 files changed

+143
-10
lines changed

4 files changed

+143
-10
lines changed

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomDescription.kt

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,24 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
1212
import org.matrix.rustcomponents.sdk.PublicRoomJoinRule
1313
import org.matrix.rustcomponents.sdk.RoomDescription
1414

15-
internal fun aRustRoomDescription(): RoomDescription {
15+
internal fun aRustRoomDescription(
16+
roomId: String = A_ROOM_ID.value,
17+
name: String? = "name",
18+
topic: String? = "topic",
19+
alias: String? = A_ROOM_ALIAS.value,
20+
avatarUrl: String? = "avatarUrl",
21+
joinRule: PublicRoomJoinRule = PublicRoomJoinRule.PUBLIC,
22+
isWorldReadable: Boolean = true,
23+
joinedMembers: ULong = 2u,
24+
): RoomDescription {
1625
return RoomDescription(
17-
roomId = A_ROOM_ID.value,
18-
name = "name",
19-
topic = "topic",
20-
alias = A_ROOM_ALIAS.value,
21-
avatarUrl = "avatarUrl",
22-
joinRule = PublicRoomJoinRule.PUBLIC,
23-
isWorldReadable = true,
24-
joinedMembers = 2u
26+
roomId = roomId,
27+
name = name,
28+
topic = topic,
29+
alias = alias,
30+
avatarUrl = avatarUrl,
31+
joinRule = joinRule,
32+
isWorldReadable = isWorldReadable,
33+
joinedMembers = joinedMembers,
2534
)
2635
}

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRoomDirectorySearch.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,31 @@
77

88
package io.element.android.libraries.matrix.impl.fixtures.fakes
99

10+
import io.element.android.tests.testutils.simulateLongTask
1011
import org.matrix.rustcomponents.sdk.NoPointer
1112
import org.matrix.rustcomponents.sdk.RoomDirectorySearch
13+
import org.matrix.rustcomponents.sdk.RoomDirectorySearchEntriesListener
14+
import org.matrix.rustcomponents.sdk.RoomDirectorySearchEntryUpdate
15+
import org.matrix.rustcomponents.sdk.TaskHandle
1216

13-
class FakeRoomDirectorySearch : RoomDirectorySearch(NoPointer)
17+
class FakeRoomDirectorySearch(
18+
var isAtLastPage: Boolean = false,
19+
) : RoomDirectorySearch(NoPointer) {
20+
override suspend fun isAtLastPage(): Boolean {
21+
return isAtLastPage
22+
}
23+
24+
override suspend fun search(filter: String?, batchSize: UInt) = simulateLongTask { }
25+
override suspend fun nextPage() = simulateLongTask { }
26+
27+
private var listener: RoomDirectorySearchEntriesListener? = null
28+
29+
override suspend fun results(listener: RoomDirectorySearchEntriesListener): TaskHandle {
30+
this.listener = listener
31+
return FakeRustTaskHandle()
32+
}
33+
34+
fun emitResult(roomEntriesUpdate: List<RoomDirectorySearchEntryUpdate>) {
35+
listener?.onUpdate(roomEntriesUpdate)
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2024 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only
5+
* Please see LICENSE in the repository root for full details.
6+
*/
7+
8+
package io.element.android.libraries.matrix.impl.roomdirectory
9+
10+
import app.cash.turbine.test
11+
import com.google.common.truth.Truth.assertThat
12+
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryList
13+
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomDescription
14+
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRoomDirectorySearch
15+
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
16+
import io.element.android.tests.testutils.runCancellableScopeTestWithTestScope
17+
import kotlinx.coroutines.CoroutineScope
18+
import kotlinx.coroutines.ExperimentalCoroutinesApi
19+
import kotlinx.coroutines.test.StandardTestDispatcher
20+
import kotlinx.coroutines.test.TestScope
21+
import kotlinx.coroutines.test.runCurrent
22+
import org.junit.Test
23+
import org.matrix.rustcomponents.sdk.RoomDirectorySearch
24+
import org.matrix.rustcomponents.sdk.RoomDirectorySearchEntryUpdate
25+
26+
@OptIn(ExperimentalCoroutinesApi::class)
27+
class RustRoomDirectoryListTest {
28+
@Test
29+
fun `check that the state emits the expected values`() = runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
30+
val fakeRoomDirectorySearch = FakeRoomDirectorySearch()
31+
val mapper = RoomDescriptionMapper()
32+
val sut = testScope.createRustRoomDirectoryList(
33+
roomDirectorySearch = fakeRoomDirectorySearch,
34+
scope = cancellableScope,
35+
)
36+
// Let the mxCallback be ready
37+
testScope.runCurrent()
38+
sut.state.test {
39+
sut.filter("", 20)
40+
fakeRoomDirectorySearch.emitResult(
41+
listOf(
42+
RoomDirectorySearchEntryUpdate.Append(listOf(aRustRoomDescription()))
43+
)
44+
)
45+
val initialItem = awaitItem()
46+
assertThat(initialItem).isEqualTo(
47+
RoomDirectoryList.State(
48+
hasMoreToLoad = true,
49+
items = listOf(mapper.map(aRustRoomDescription()))
50+
)
51+
)
52+
assertThat(initialItem.hasMoreToLoad).isTrue()
53+
fakeRoomDirectorySearch.isAtLastPage = true
54+
sut.loadMore()
55+
fakeRoomDirectorySearch.emitResult(
56+
listOf(
57+
RoomDirectorySearchEntryUpdate.Append(listOf(aRustRoomDescription(A_ROOM_ID_2.value)))
58+
)
59+
)
60+
val nextItem = awaitItem()
61+
assertThat(nextItem).isEqualTo(
62+
RoomDirectoryList.State(
63+
hasMoreToLoad = false,
64+
items = listOf(
65+
mapper.map(aRustRoomDescription()),
66+
)
67+
)
68+
)
69+
val finalItem = awaitItem()
70+
assertThat(finalItem).isEqualTo(
71+
RoomDirectoryList.State(
72+
hasMoreToLoad = false,
73+
items = listOf(
74+
mapper.map(aRustRoomDescription()),
75+
mapper.map(aRustRoomDescription(A_ROOM_ID_2.value)),
76+
)
77+
)
78+
)
79+
}
80+
}
81+
82+
private fun TestScope.createRustRoomDirectoryList(
83+
roomDirectorySearch: RoomDirectorySearch = FakeRoomDirectorySearch(),
84+
scope: CoroutineScope,
85+
) = RustRoomDirectoryList(
86+
inner = roomDirectorySearch,
87+
coroutineScope = scope,
88+
coroutineContext = StandardTestDispatcher(testScheduler),
89+
)
90+
}

tests/testutils/src/main/kotlin/io/element/android/tests/testutils/RunCancellableTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package io.element.android.tests.testutils
1010
import kotlinx.coroutines.CoroutineScope
1111
import kotlinx.coroutines.SupervisorJob
1212
import kotlinx.coroutines.cancel
13+
import kotlinx.coroutines.test.TestScope
1314
import kotlinx.coroutines.test.runTest
1415

1516
/**
@@ -20,3 +21,12 @@ fun runCancellableScopeTest(block: suspend (CoroutineScope) -> Unit) = runTest {
2021
block(scope)
2122
scope.cancel()
2223
}
24+
25+
/**
26+
* Run a test with a [CoroutineScope] that will be cancelled automatically and avoiding failing the test.
27+
*/
28+
fun runCancellableScopeTestWithTestScope(block: suspend (testScope: TestScope, cancellableScope: CoroutineScope) -> Unit) = runTest {
29+
val scope = CoroutineScope(coroutineContext + SupervisorJob())
30+
block(this, scope)
31+
scope.cancel()
32+
}

0 commit comments

Comments
 (0)