@@ -16,7 +16,6 @@ import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustTimelineD
1616import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustTimelineItem
1717import io.element.android.tests.testutils.lambda.lambdaError
1818import io.element.android.tests.testutils.lambda.lambdaRecorder
19- import io.element.android.tests.testutils.runCancellableScopeTestWithTestScope
2019import kotlinx.coroutines.CompletableDeferred
2120import kotlinx.coroutines.CoroutineScope
2221import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -25,6 +24,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
2524import kotlinx.coroutines.test.StandardTestDispatcher
2625import kotlinx.coroutines.test.TestScope
2726import kotlinx.coroutines.test.runCurrent
27+ import kotlinx.coroutines.test.runTest
2828import org.junit.Test
2929import org.matrix.rustcomponents.sdk.Timeline
3030import org.matrix.rustcomponents.sdk.TimelineChange
@@ -33,115 +33,107 @@ import uniffi.matrix_sdk_ui.EventItemOrigin
3333@OptIn(ExperimentalCoroutinesApi ::class )
3434class TimelineItemsSubscriberTest {
3535 @Test
36- fun `when timeline emits an empty list of items, the flow must emits an empty list` () {
37- runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
38- val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
39- MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
40- val timeline = FakeRustTimeline ()
41- val timelineItemsSubscriber = testScope.createTimelineItemsSubscriber(
42- coroutineScope = cancellableScope,
43- timeline = timeline,
44- timelineItems = timelineItems,
45- )
46- timelineItems.test {
47- timelineItemsSubscriber.subscribeIfNeeded()
48- // Wait for the listener to be set.
49- testScope.runCurrent()
50- timeline.emitDiff(listOf (FakeRustTimelineDiff (item = null , change = TimelineChange .RESET )))
51- val final = awaitItem()
52- assertThat(final).isEmpty()
53- timelineItemsSubscriber.unsubscribeIfNeeded()
54- }
36+ fun `when timeline emits an empty list of items, the flow must emits an empty list` () = runTest {
37+ val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
38+ MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
39+ val timeline = FakeRustTimeline ()
40+ val timelineItemsSubscriber = createTimelineItemsSubscriber(
41+ coroutineScope = backgroundScope,
42+ timeline = timeline,
43+ timelineItems = timelineItems,
44+ )
45+ timelineItems.test {
46+ timelineItemsSubscriber.subscribeIfNeeded()
47+ // Wait for the listener to be set.
48+ runCurrent()
49+ timeline.emitDiff(listOf (FakeRustTimelineDiff (item = null , change = TimelineChange .RESET )))
50+ val final = awaitItem()
51+ assertThat(final).isEmpty()
52+ timelineItemsSubscriber.unsubscribeIfNeeded()
5553 }
5654 }
5755
5856 @Test
59- fun `when timeline emits a non empty list of items, the flow must emits a non empty list` () {
60- runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
61- val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
62- MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
63- val timeline = FakeRustTimeline ()
64- val timelineItemsSubscriber = testScope.createTimelineItemsSubscriber(
65- coroutineScope = cancellableScope,
66- timeline = timeline,
67- timelineItems = timelineItems,
68- )
69- timelineItems.test {
70- timelineItemsSubscriber.subscribeIfNeeded()
71- // Wait for the listener to be set.
72- testScope.runCurrent()
73- timeline.emitDiff(listOf (FakeRustTimelineDiff (item = FakeRustTimelineItem (), change = TimelineChange .RESET )))
74- val final = awaitItem()
75- assertThat(final).isNotEmpty()
76- timelineItemsSubscriber.unsubscribeIfNeeded()
77- }
57+ fun `when timeline emits a non empty list of items, the flow must emits a non empty list` () = runTest {
58+ val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
59+ MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
60+ val timeline = FakeRustTimeline ()
61+ val timelineItemsSubscriber = createTimelineItemsSubscriber(
62+ coroutineScope = backgroundScope,
63+ timeline = timeline,
64+ timelineItems = timelineItems,
65+ )
66+ timelineItems.test {
67+ timelineItemsSubscriber.subscribeIfNeeded()
68+ // Wait for the listener to be set.
69+ runCurrent()
70+ timeline.emitDiff(listOf (FakeRustTimelineDiff (item = FakeRustTimelineItem (), change = TimelineChange .RESET )))
71+ val final = awaitItem()
72+ assertThat(final).isNotEmpty()
73+ timelineItemsSubscriber.unsubscribeIfNeeded()
7874 }
7975 }
8076
8177 @Test
82- fun `when timeline emits an item with SYNC origin, the callback onNewSyncedEvent is invoked` () {
83- runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
84- val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
85- MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
86- val timeline = FakeRustTimeline ()
87- val onNewSyncedEventRecorder = lambdaRecorder<Unit > { }
88- val timelineItemsSubscriber = testScope.createTimelineItemsSubscriber(
89- coroutineScope = cancellableScope,
90- timeline = timeline,
91- timelineItems = timelineItems,
92- onNewSyncedEvent = onNewSyncedEventRecorder,
93- )
94- timelineItems.test {
95- timelineItemsSubscriber.subscribeIfNeeded()
96- // Wait for the listener to be set.
97- testScope.runCurrent()
98- timeline.emitDiff(
99- listOf (
100- FakeRustTimelineDiff (
101- item = FakeRustTimelineItem (
102- asEventResult = FakeRustEventTimelineItem (origin = EventItemOrigin .SYNC )
103- ),
104- change = TimelineChange .RESET ,
105- )
78+ fun `when timeline emits an item with SYNC origin, the callback onNewSyncedEvent is invoked` () = runTest {
79+ val timelineItems: MutableSharedFlow <List <MatrixTimelineItem >> =
80+ MutableSharedFlow (replay = 1 , extraBufferCapacity = Int .MAX_VALUE )
81+ val timeline = FakeRustTimeline ()
82+ val onNewSyncedEventRecorder = lambdaRecorder<Unit > { }
83+ val timelineItemsSubscriber = createTimelineItemsSubscriber(
84+ coroutineScope = backgroundScope,
85+ timeline = timeline,
86+ timelineItems = timelineItems,
87+ onNewSyncedEvent = onNewSyncedEventRecorder,
88+ )
89+ timelineItems.test {
90+ timelineItemsSubscriber.subscribeIfNeeded()
91+ // Wait for the listener to be set.
92+ runCurrent()
93+ timeline.emitDiff(
94+ listOf (
95+ FakeRustTimelineDiff (
96+ item = FakeRustTimelineItem (
97+ asEventResult = FakeRustEventTimelineItem (origin = EventItemOrigin .SYNC )
98+ ),
99+ change = TimelineChange .RESET ,
106100 )
107101 )
108- val final = awaitItem()
109- assertThat(final).isNotEmpty()
110- timelineItemsSubscriber.unsubscribeIfNeeded()
111- }
112- onNewSyncedEventRecorder.assertions().isCalledOnce()
113- }
114- }
115-
116- @Test
117- fun `multiple subscriptions does not have side effect` () {
118- runCancellableScopeTestWithTestScope { testScope, cancellableScope ->
119- val timelineItemsSubscriber = testScope.createTimelineItemsSubscriber(
120- coroutineScope = cancellableScope,
121102 )
122- timelineItemsSubscriber.subscribeIfNeeded()
123- timelineItemsSubscriber.subscribeIfNeeded()
124- timelineItemsSubscriber.unsubscribeIfNeeded()
103+ val final = awaitItem()
104+ assertThat(final).isNotEmpty()
125105 timelineItemsSubscriber.unsubscribeIfNeeded()
126106 }
107+ onNewSyncedEventRecorder.assertions().isCalledOnce()
127108 }
128109
129- private fun TestScope.createTimelineItemsSubscriber (
130- coroutineScope : CoroutineScope ,
131- timeline : Timeline = FakeRustTimeline (),
132- timelineItems : MutableSharedFlow <List <MatrixTimelineItem >> = MutableSharedFlow (replay = 1, extraBufferCapacity = Int .MAX_VALUE ),
133- initLatch : CompletableDeferred <Unit > = CompletableDeferred (),
134- isTimelineInitialized : MutableStateFlow <Boolean > = MutableStateFlow (false),
135- onNewSyncedEvent : () -> Unit = { lambdaError() },
136- ): TimelineItemsSubscriber {
137- return TimelineItemsSubscriber (
138- timelineCoroutineScope = coroutineScope,
139- dispatcher = StandardTestDispatcher (testScheduler),
140- timeline = timeline,
141- timelineDiffProcessor = createMatrixTimelineDiffProcessor(timelineItems),
142- initLatch = initLatch,
143- isTimelineInitialized = isTimelineInitialized,
144- onNewSyncedEvent = onNewSyncedEvent,
110+ @Test
111+ fun `multiple subscriptions does not have side effect` () = runTest {
112+ val timelineItemsSubscriber = createTimelineItemsSubscriber(
113+ coroutineScope = backgroundScope,
145114 )
115+ timelineItemsSubscriber.subscribeIfNeeded()
116+ timelineItemsSubscriber.subscribeIfNeeded()
117+ timelineItemsSubscriber.unsubscribeIfNeeded()
118+ timelineItemsSubscriber.unsubscribeIfNeeded()
146119 }
147120}
121+
122+ private fun TestScope.createTimelineItemsSubscriber (
123+ coroutineScope : CoroutineScope ,
124+ timeline : Timeline = FakeRustTimeline (),
125+ timelineItems : MutableSharedFlow <List <MatrixTimelineItem >> = MutableSharedFlow (replay = 1, extraBufferCapacity = Int .MAX_VALUE ),
126+ initLatch : CompletableDeferred <Unit > = CompletableDeferred (),
127+ isTimelineInitialized : MutableStateFlow <Boolean > = MutableStateFlow (false),
128+ onNewSyncedEvent : () -> Unit = { lambdaError() },
129+ ): TimelineItemsSubscriber {
130+ return TimelineItemsSubscriber (
131+ timelineCoroutineScope = coroutineScope,
132+ dispatcher = StandardTestDispatcher (testScheduler),
133+ timeline = timeline,
134+ timelineDiffProcessor = createMatrixTimelineDiffProcessor(timelineItems),
135+ initLatch = initLatch,
136+ isTimelineInitialized = isTimelineInitialized,
137+ onNewSyncedEvent = onNewSyncedEvent,
138+ )
139+ }
0 commit comments