Skip to content

Commit 29356b9

Browse files
authored
Merge pull request #3554 from element-hq/feature/bma/testEmptyTimeline
Add unit tests on TimelineItemsSubscriber
2 parents ee7e5b8 + f89463c commit 29356b9

File tree

14 files changed

+347
-128
lines changed

14 files changed

+347
-128
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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.fixtures.factories
9+
10+
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo
11+
12+
fun anEventTimelineItemDebugInfo(
13+
model: String = "model",
14+
originalJson: String? = null,
15+
latestEditJson: String? = null,
16+
) = EventTimelineItemDebugInfo(
17+
model = model,
18+
originalJson = originalJson,
19+
latestEditJson = latestEditJson
20+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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.fixtures.fakes
9+
10+
import io.element.android.libraries.matrix.impl.fixtures.factories.anEventTimelineItemDebugInfo
11+
import io.element.android.libraries.matrix.test.AN_EVENT_ID
12+
import io.element.android.libraries.matrix.test.A_USER_ID
13+
import org.matrix.rustcomponents.sdk.EventSendState
14+
import org.matrix.rustcomponents.sdk.EventTimelineItem
15+
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo
16+
import org.matrix.rustcomponents.sdk.NoPointer
17+
import org.matrix.rustcomponents.sdk.ProfileDetails
18+
import org.matrix.rustcomponents.sdk.Reaction
19+
import org.matrix.rustcomponents.sdk.Receipt
20+
import org.matrix.rustcomponents.sdk.ShieldState
21+
import org.matrix.rustcomponents.sdk.TimelineItemContent
22+
import uniffi.matrix_sdk_ui.EventItemOrigin
23+
24+
class FakeRustEventTimelineItem(
25+
private val origin: EventItemOrigin? = null,
26+
) : EventTimelineItem(NoPointer) {
27+
override fun origin(): EventItemOrigin? = origin
28+
override fun eventId(): String = AN_EVENT_ID.value
29+
override fun transactionId(): String? = null
30+
override fun isEditable(): Boolean = false
31+
override fun canBeRepliedTo(): Boolean = false
32+
override fun isLocal(): Boolean = false
33+
override fun isOwn(): Boolean = false
34+
override fun isRemote(): Boolean = false
35+
override fun localSendState(): EventSendState? = null
36+
override fun reactions(): List<Reaction> = emptyList()
37+
override fun readReceipts(): Map<String, Receipt> = emptyMap()
38+
override fun sender(): String = A_USER_ID.value
39+
override fun senderProfile(): ProfileDetails = ProfileDetails.Unavailable
40+
override fun timestamp(): ULong = 0u
41+
override fun content(): TimelineItemContent = FakeRustTimelineItemContent()
42+
override fun debugInfo(): EventTimelineItemDebugInfo = anEventTimelineItemDebugInfo()
43+
override fun getShield(strict: Boolean): ShieldState? = null
44+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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.fixtures.fakes
9+
10+
import org.matrix.rustcomponents.sdk.NoPointer
11+
import org.matrix.rustcomponents.sdk.TaskHandle
12+
import org.matrix.rustcomponents.sdk.Timeline
13+
import org.matrix.rustcomponents.sdk.TimelineDiff
14+
import org.matrix.rustcomponents.sdk.TimelineListener
15+
16+
class FakeRustTimeline : Timeline(NoPointer) {
17+
private var listener: TimelineListener? = null
18+
override suspend fun addListener(listener: TimelineListener): TaskHandle {
19+
this.listener = listener
20+
return FakeRustTaskHandle()
21+
}
22+
23+
fun emitDiff(diff: List<TimelineDiff>) {
24+
listener!!.onUpdate(diff)
25+
}
26+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import org.matrix.rustcomponents.sdk.NoPointer
1212
import org.matrix.rustcomponents.sdk.TimelineItem
1313
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
1414

15-
class FakeRustTimelineItem : TimelineItem(NoPointer) {
16-
override fun asEvent(): EventTimelineItem? = null
15+
class FakeRustTimelineItem(
16+
private val asEventResult: EventTimelineItem? = null,
17+
) : TimelineItem(NoPointer) {
18+
override fun asEvent(): EventTimelineItem? = asEventResult
1719
override fun asVirtual(): VirtualTimelineItem? = null
1820
override fun fmtDebug(): String = "fmtDebug"
1921
override fun uniqueId(): String = "uniqueId"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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.fixtures.fakes
9+
10+
import org.matrix.rustcomponents.sdk.Message
11+
import org.matrix.rustcomponents.sdk.NoPointer
12+
import org.matrix.rustcomponents.sdk.TimelineItemContent
13+
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
14+
15+
class FakeRustTimelineItemContent : TimelineItemContent(NoPointer) {
16+
override fun asMessage(): Message? = null
17+
override fun kind(): TimelineItemContentKind = TimelineItemContentKind.Message
18+
}

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustRoomDirectoryListTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,28 @@ import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryList
1313
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomDescription
1414
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRoomDirectorySearch
1515
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
16-
import io.element.android.tests.testutils.runCancellableScopeTestWithTestScope
1716
import kotlinx.coroutines.CoroutineScope
1817
import kotlinx.coroutines.ExperimentalCoroutinesApi
1918
import kotlinx.coroutines.test.StandardTestDispatcher
2019
import kotlinx.coroutines.test.TestScope
2120
import kotlinx.coroutines.test.runCurrent
21+
import kotlinx.coroutines.test.runTest
2222
import org.junit.Test
2323
import org.matrix.rustcomponents.sdk.RoomDirectorySearch
2424
import org.matrix.rustcomponents.sdk.RoomDirectorySearchEntryUpdate
2525

2626
@OptIn(ExperimentalCoroutinesApi::class)
2727
class RustRoomDirectoryListTest {
2828
@Test
29-
fun `check that the state emits the expected values`() = runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
29+
fun `check that the state emits the expected values`() = runTest {
3030
val fakeRoomDirectorySearch = FakeRoomDirectorySearch()
3131
val mapper = RoomDescriptionMapper()
32-
val sut = testScope.createRustRoomDirectoryList(
32+
val sut = createRustRoomDirectoryList(
3333
roomDirectorySearch = fakeRoomDirectorySearch,
34-
scope = cancellableScope,
34+
scope = backgroundScope,
3535
)
3636
// Let the mxCallback be ready
37-
testScope.runCurrent()
37+
runCurrent()
3838
sut.state.test {
3939
sut.filter("", 20)
4040
fakeRoomDirectorySearch.emitResult(

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustRoomDirectoryServiceTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
package io.element.android.libraries.matrix.impl.roomdirectory
99

1010
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustClient
11-
import io.element.android.tests.testutils.runCancellableScopeTestWithTestScope
1211
import kotlinx.coroutines.test.StandardTestDispatcher
12+
import kotlinx.coroutines.test.runTest
1313
import org.junit.Test
1414

1515
class RustRoomDirectoryServiceTest {
1616
@Test
17-
fun test() = runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
17+
fun test() = runTest {
1818
val client = FakeRustClient()
1919
val sut = RustRoomDirectoryService(
2020
client = client,
21-
sessionDispatcher = StandardTestDispatcher(testScope.testScheduler),
21+
sessionDispatcher = StandardTestDispatcher(testScheduler),
2222
)
23-
sut.createRoomDirectoryList(cancellableScope)
23+
sut.createRoomDirectoryList(backgroundScope)
2424
}
2525
}

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ package io.element.android.libraries.matrix.impl.roomlist
99

1010
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoomList
1111
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoomListService
12-
import io.element.android.tests.testutils.runCancellableScopeTest
12+
import kotlinx.coroutines.test.runTest
1313
import org.junit.Test
1414
import kotlin.coroutines.EmptyCoroutineContext
1515

1616
class RoomListFactoryTest {
1717
@Test
18-
fun `createRoomList should work`() = runCancellableScopeTest {
18+
fun `createRoomList should work`() = runTest {
1919
val sut = RoomListFactory(
2020
innerRoomListService = FakeRustRoomListService(),
21-
sessionCoroutineScope = it,
21+
sessionCoroutineScope = backgroundScope,
2222
)
2323
sut.createRoomList(
2424
pageSize = 10,

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListServiceTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,28 @@ import com.google.common.truth.Truth.assertThat
1111
import io.element.android.libraries.matrix.api.roomlist.RoomListService
1212
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoomListService
1313
import io.element.android.libraries.matrix.impl.room.RoomSyncSubscriber
14-
import io.element.android.tests.testutils.runCancellableScopeTestWithTestScope
1514
import io.element.android.tests.testutils.testCoroutineDispatchers
1615
import kotlinx.coroutines.CoroutineScope
1716
import kotlinx.coroutines.ExperimentalCoroutinesApi
1817
import kotlinx.coroutines.test.StandardTestDispatcher
1918
import kotlinx.coroutines.test.TestScope
2019
import kotlinx.coroutines.test.runCurrent
20+
import kotlinx.coroutines.test.runTest
2121
import org.junit.Test
2222
import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator
2323
import org.matrix.rustcomponents.sdk.RoomListService as RustRoomListService
2424

2525
@OptIn(ExperimentalCoroutinesApi::class)
2626
class RustRoomListServiceTest {
2727
@Test
28-
fun `syncIndicator should emit the expected values`() = runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
28+
fun `syncIndicator should emit the expected values`() = runTest {
2929
val roomListService = FakeRustRoomListService()
30-
val sut = testScope.createRustRoomListService(
31-
sessionCoroutineScope = cancellableScope,
30+
val sut = createRustRoomListService(
31+
sessionCoroutineScope = backgroundScope,
3232
roomListService = roomListService,
3333
)
3434
// Give time for mxCallback to setup
35-
testScope.runCurrent()
35+
runCurrent()
3636
sut.syncIndicator.test {
3737
assertThat(awaitItem()).isEqualTo(RoomListService.SyncIndicator.Hide)
3838
roomListService.emitRoomListServiceSyncIndicator(RoomListServiceSyncIndicator.SHOW)

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTim
1616
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
1717
import io.element.android.libraries.matrix.test.A_UNIQUE_ID_2
1818
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
19+
import kotlinx.coroutines.flow.MutableSharedFlow
1920
import kotlinx.coroutines.flow.MutableStateFlow
2021
import kotlinx.coroutines.test.TestScope
2122
import kotlinx.coroutines.test.runTest
@@ -31,7 +32,7 @@ class MatrixTimelineDiffProcessorTest {
3132
@Test
3233
fun `Append adds new entries at the end of the list`() = runTest {
3334
timelineItems.value = listOf(anEvent)
34-
val processor = createProcessor()
35+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
3536
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.APPEND)))
3637
assertThat(timelineItems.value.count()).isEqualTo(2)
3738
assertThat(timelineItems.value).containsExactly(
@@ -43,7 +44,7 @@ class MatrixTimelineDiffProcessorTest {
4344
@Test
4445
fun `PushBack adds a new entry at the end of the list`() = runTest {
4546
timelineItems.value = listOf(anEvent)
46-
val processor = createProcessor()
47+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
4748
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.PUSH_BACK)))
4849
assertThat(timelineItems.value.count()).isEqualTo(2)
4950
assertThat(timelineItems.value).containsExactly(
@@ -55,7 +56,7 @@ class MatrixTimelineDiffProcessorTest {
5556
@Test
5657
fun `PushFront inserts a new entry at the start of the list`() = runTest {
5758
timelineItems.value = listOf(anEvent)
58-
val processor = createProcessor()
59+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
5960
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.PUSH_FRONT)))
6061
assertThat(timelineItems.value.count()).isEqualTo(2)
6162
assertThat(timelineItems.value).containsExactly(
@@ -67,7 +68,7 @@ class MatrixTimelineDiffProcessorTest {
6768
@Test
6869
fun `Set replaces an entry at some index`() = runTest {
6970
timelineItems.value = listOf(anEvent, anEvent2)
70-
val processor = createProcessor()
71+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
7172
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.SET)))
7273
assertThat(timelineItems.value.count()).isEqualTo(2)
7374
assertThat(timelineItems.value).containsExactly(
@@ -79,7 +80,7 @@ class MatrixTimelineDiffProcessorTest {
7980
@Test
8081
fun `Insert inserts a new entry at the provided index`() = runTest {
8182
timelineItems.value = listOf(anEvent, anEvent2)
82-
val processor = createProcessor()
83+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
8384
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.INSERT)))
8485
assertThat(timelineItems.value.count()).isEqualTo(3)
8586
assertThat(timelineItems.value).containsExactly(
@@ -92,7 +93,7 @@ class MatrixTimelineDiffProcessorTest {
9293
@Test
9394
fun `Remove removes an entry at some index`() = runTest {
9495
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
95-
val processor = createProcessor()
96+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
9697
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.REMOVE)))
9798
assertThat(timelineItems.value.count()).isEqualTo(2)
9899
assertThat(timelineItems.value).containsExactly(
@@ -104,7 +105,7 @@ class MatrixTimelineDiffProcessorTest {
104105
@Test
105106
fun `PopBack removes an entry at the end of the list`() = runTest {
106107
timelineItems.value = listOf(anEvent, anEvent2)
107-
val processor = createProcessor()
108+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
108109
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.POP_BACK)))
109110
assertThat(timelineItems.value.count()).isEqualTo(1)
110111
assertThat(timelineItems.value).containsExactly(
@@ -115,7 +116,7 @@ class MatrixTimelineDiffProcessorTest {
115116
@Test
116117
fun `PopFront removes an entry at the start of the list`() = runTest {
117118
timelineItems.value = listOf(anEvent, anEvent2)
118-
val processor = createProcessor()
119+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
119120
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.POP_FRONT)))
120121
assertThat(timelineItems.value.count()).isEqualTo(1)
121122
assertThat(timelineItems.value).containsExactly(
@@ -126,15 +127,15 @@ class MatrixTimelineDiffProcessorTest {
126127
@Test
127128
fun `Clear removes all the entries`() = runTest {
128129
timelineItems.value = listOf(anEvent, anEvent2)
129-
val processor = createProcessor()
130+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
130131
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.CLEAR)))
131132
assertThat(timelineItems.value).isEmpty()
132133
}
133134

134135
@Test
135136
fun `Truncate removes all entries after the provided length`() = runTest {
136137
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
137-
val processor = createProcessor()
138+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
138139
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.TRUNCATE)))
139140
assertThat(timelineItems.value.count()).isEqualTo(1)
140141
assertThat(timelineItems.value).containsExactly(
@@ -145,27 +146,29 @@ class MatrixTimelineDiffProcessorTest {
145146
@Test
146147
fun `Reset removes all entries and add the provided ones`() = runTest {
147148
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
148-
val processor = createProcessor()
149+
val processor = createMatrixTimelineDiffProcessor(timelineItems)
149150
processor.postDiffs(listOf(FakeRustTimelineDiff(change = TimelineChange.RESET)))
150151
assertThat(timelineItems.value.count()).isEqualTo(1)
151152
assertThat(timelineItems.value).containsExactly(
152153
MatrixTimelineItem.Other,
153154
)
154155
}
156+
}
155157

156-
private fun TestScope.createProcessor(): MatrixTimelineDiffProcessor {
157-
val timelineEventContentMapper = TimelineEventContentMapper()
158-
val timelineItemMapper = MatrixTimelineItemMapper(
159-
fetchDetailsForEvent = { _ -> Result.success(Unit) },
160-
coroutineScope = this,
161-
virtualTimelineItemMapper = VirtualTimelineItemMapper(),
162-
eventTimelineItemMapper = EventTimelineItemMapper(
163-
contentMapper = timelineEventContentMapper
164-
)
165-
)
166-
return MatrixTimelineDiffProcessor(
167-
timelineItems,
168-
timelineItemFactory = timelineItemMapper,
158+
internal fun TestScope.createMatrixTimelineDiffProcessor(
159+
timelineItems: MutableSharedFlow<List<MatrixTimelineItem>>,
160+
): MatrixTimelineDiffProcessor {
161+
val timelineEventContentMapper = TimelineEventContentMapper()
162+
val timelineItemMapper = MatrixTimelineItemMapper(
163+
fetchDetailsForEvent = { _ -> Result.success(Unit) },
164+
coroutineScope = this,
165+
virtualTimelineItemMapper = VirtualTimelineItemMapper(),
166+
eventTimelineItemMapper = EventTimelineItemMapper(
167+
contentMapper = timelineEventContentMapper
169168
)
170-
}
169+
)
170+
return MatrixTimelineDiffProcessor(
171+
timelineItems = timelineItems,
172+
timelineItemFactory = timelineItemMapper,
173+
)
171174
}

0 commit comments

Comments
 (0)