Timeline : makes sure all tests are passing
This commit is contained in:
@@ -31,6 +31,7 @@ import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@@ -22,17 +22,22 @@ import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.LiveTimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.getAndUpdate
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import java.io.Closeable
|
||||
import java.util.Optional
|
||||
import javax.inject.Inject
|
||||
@@ -49,12 +54,14 @@ class TimelineController @Inject constructor(
|
||||
private val room: MatrixRoom,
|
||||
) : Closeable, TimelineProvider {
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
private val liveTimeline = MutableStateFlow(room.liveTimeline)
|
||||
private val detachedTimeline = MutableStateFlow<Optional<Timeline>>(Optional.empty())
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun timelineItems(): Flow<List<MatrixTimelineItem>> {
|
||||
return currentTimelineFlow().flatMapLatest { it.timelineItems }
|
||||
return currentTimelineFlow.flatMapLatest { it.timelineItems }
|
||||
}
|
||||
|
||||
fun isLive(): Flow<Boolean> {
|
||||
@@ -62,7 +69,7 @@ class TimelineController @Inject constructor(
|
||||
}
|
||||
|
||||
suspend fun invokeOnCurrentTimeline(block: suspend (Timeline.() -> Any)) {
|
||||
currentTimelineFlow().first().run {
|
||||
currentTimelineFlow.value.run {
|
||||
block(this)
|
||||
}
|
||||
}
|
||||
@@ -89,6 +96,10 @@ class TimelineController @Inject constructor(
|
||||
* This does close the detached timeline if any.
|
||||
*/
|
||||
fun focusOnLive() {
|
||||
closeDetachedTimeline()
|
||||
}
|
||||
|
||||
private fun closeDetachedTimeline() {
|
||||
detachedTimeline.getAndUpdate {
|
||||
when {
|
||||
it.isPresent -> {
|
||||
@@ -101,11 +112,12 @@ class TimelineController @Inject constructor(
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
focusOnLive()
|
||||
coroutineScope.cancel()
|
||||
closeDetachedTimeline()
|
||||
}
|
||||
|
||||
suspend fun paginate(direction: Timeline.PaginationDirection): Result<Boolean> {
|
||||
return currentTimelineFlow().first().paginate(direction)
|
||||
return currentTimelineFlow.value.paginate(direction)
|
||||
.onSuccess { hasReachedEnd ->
|
||||
if (direction == Timeline.PaginationDirection.FORWARDS && hasReachedEnd) {
|
||||
focusOnLive()
|
||||
@@ -113,14 +125,14 @@ class TimelineController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun currentTimelineFlow() = combine(liveTimeline, detachedTimeline) { live, detached ->
|
||||
private val currentTimelineFlow = combine(liveTimeline, detachedTimeline) { live, detached ->
|
||||
when {
|
||||
detached.isPresent -> detached.get()
|
||||
else -> live
|
||||
}
|
||||
}
|
||||
}.stateIn(coroutineScope, SharingStarted.Eagerly, room.liveTimeline)
|
||||
|
||||
override suspend fun getActiveTimeline(): Timeline {
|
||||
return currentTimelineFlow().first()
|
||||
override fun activeTimelineFlow(): StateFlow<Timeline> {
|
||||
return currentTimelineFlow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@ data class TimelineState(
|
||||
val focusedEventId : EventId?,
|
||||
val focusRequestState: FocusRequestState,
|
||||
val eventSink: (TimelineEvents) -> Unit,
|
||||
)
|
||||
){
|
||||
val isTimelineEmpty = timelineItems.none { it is TimelineItem.Event }
|
||||
}
|
||||
|
||||
sealed interface FocusRequestState {
|
||||
data object None : FocusRequestState
|
||||
|
||||
@@ -63,6 +63,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentProvider
|
||||
import io.element.android.features.messages.impl.typing.TypingNotificationState
|
||||
import io.element.android.features.messages.impl.typing.TypingNotificationView
|
||||
import io.element.android.features.messages.impl.typing.aTypingNotificationState
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
@@ -125,12 +126,12 @@ fun TimelineView(
|
||||
reverseLayout = useReverseLayout,
|
||||
contentPadding = PaddingValues(vertical = 8.dp),
|
||||
) {
|
||||
/*
|
||||
item(key = UUID.randomUUID()) {
|
||||
TypingNotificationView(state = typingNotificationState)
|
||||
}
|
||||
|
||||
*/
|
||||
if(state.isLive) {
|
||||
item {
|
||||
TypingNotificationView(state = typingNotificationState)
|
||||
}
|
||||
}
|
||||
items(
|
||||
items = state.timelineItems,
|
||||
contentType = { timelineItem -> timelineItem.contentType() },
|
||||
@@ -165,7 +166,7 @@ fun TimelineView(
|
||||
)
|
||||
|
||||
TimelineScrollHelper(
|
||||
isTimelineEmpty = state.timelineItems.isEmpty(),
|
||||
isTimelineEmpty = state.isTimelineEmpty,
|
||||
lazyListState = lazyListState,
|
||||
forceJumpToBottomVisibility = forceJumpToBottomVisibility,
|
||||
newEventState = state.newEventState,
|
||||
@@ -185,10 +186,6 @@ private fun FocusRequestStateView(
|
||||
onClearFocusRequestState: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
BackHandler(enabled = focusRequestState is FocusRequestState.Fetching) {
|
||||
onClearFocusRequestState()
|
||||
}
|
||||
|
||||
when (focusRequestState) {
|
||||
is FocusRequestState.Failure -> {
|
||||
ErrorDialog(
|
||||
@@ -198,7 +195,7 @@ private fun FocusRequestStateView(
|
||||
)
|
||||
}
|
||||
FocusRequestState.Fetching -> {
|
||||
ProgressDialog(modifier = modifier)
|
||||
ProgressDialog(modifier = modifier, onDismissRequest = onClearFocusRequestState)
|
||||
}
|
||||
is FocusRequestState.Cached, FocusRequestState.None -> Unit
|
||||
}
|
||||
@@ -254,7 +251,6 @@ private fun BoxScope.TimelineScrollHelper(
|
||||
}
|
||||
|
||||
LaunchedEffect(canAutoScroll, newEventState) {
|
||||
Timber.d("TimelineScrollHelper - canAutoScroll: $canAutoScroll, newEventState: $newEventState")
|
||||
val shouldScrollToBottom = isScrollFinished && (canAutoScroll || newEventState == NewEventState.FromMe)
|
||||
if (shouldScrollToBottom) {
|
||||
scrollToBottom()
|
||||
|
||||
@@ -21,15 +21,20 @@ import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.timeline.LiveTimelineProvider
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails
|
||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class ForwardMessagesPresenterTests {
|
||||
@get:Rule
|
||||
@@ -37,7 +42,7 @@ class ForwardMessagesPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = aPresenter()
|
||||
val presenter = aForwardMessagesPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
@@ -50,7 +55,14 @@ class ForwardMessagesPresenterTests {
|
||||
|
||||
@Test
|
||||
fun `present - forward successful`() = runTest {
|
||||
val presenter = aPresenter()
|
||||
val forwardEventLambda = lambdaRecorder { _: EventId, _: List<RoomId> ->
|
||||
Result.success(Unit)
|
||||
}
|
||||
val timeline = FakeTimeline().apply {
|
||||
this.forwardEventLambda = forwardEventLambda
|
||||
}
|
||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
||||
val presenter = aForwardMessagesPresenter(fakeMatrixRoom = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
@@ -62,18 +74,23 @@ class ForwardMessagesPresenterTests {
|
||||
val successfulForwardState = awaitItem()
|
||||
assertThat(successfulForwardState.isForwarding).isFalse()
|
||||
assertThat(successfulForwardState.forwardingSucceeded).isNotNull()
|
||||
assert(forwardEventLambda).isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - select a room and forward failed, then clear`() = runTest {
|
||||
val room = FakeMatrixRoom()
|
||||
val presenter = aPresenter(fakeMatrixRoom = room)
|
||||
val forwardEventLambda = lambdaRecorder { _: EventId, _: List<RoomId> ->
|
||||
Result.failure<Unit>(IllegalStateException("error"))
|
||||
}
|
||||
val timeline = FakeTimeline().apply {
|
||||
this.forwardEventLambda = forwardEventLambda
|
||||
}
|
||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
||||
val presenter = aForwardMessagesPresenter(fakeMatrixRoom = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
// Test failed forwarding
|
||||
room.givenForwardEventResult(Result.failure(Throwable("error")))
|
||||
skipItems(1)
|
||||
val summary = aRoomSummaryDetails()
|
||||
presenter.onRoomSelected(listOf(summary.roomId))
|
||||
@@ -83,10 +100,11 @@ class ForwardMessagesPresenterTests {
|
||||
// Then clear error
|
||||
failedForwardState.eventSink(ForwardMessagesEvents.ClearError)
|
||||
assertThat(awaitItem().error).isNull()
|
||||
assert(forwardEventLambda).isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.aPresenter(
|
||||
private fun CoroutineScope.aForwardMessagesPresenter(
|
||||
eventId: EventId = AN_EVENT_ID,
|
||||
fakeMatrixRoom: FakeMatrixRoom = FakeMatrixRoom(),
|
||||
coroutineScope: CoroutineScope = this,
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.poll.PollKind
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
import kotlinx.coroutines.flow.first
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -34,22 +34,23 @@ import io.element.android.features.poll.impl.history.model.PollHistoryItemsFacto
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class PollHistoryPresenter @Inject constructor(
|
||||
private val room: MatrixRoom,
|
||||
private val appCoroutineScope: CoroutineScope,
|
||||
private val sendPollResponseAction: SendPollResponseAction,
|
||||
private val endPollAction: EndPollAction,
|
||||
private val pollHistoryItemFactory: PollHistoryItemsFactory,
|
||||
private val timelineProvider: TimelineProvider,
|
||||
) : Presenter<PollHistoryState> {
|
||||
@Composable
|
||||
override fun present(): PollHistoryState {
|
||||
// TODO use room.rememberPollHistory() when working properly?
|
||||
val timeline = room.liveTimeline
|
||||
val timeline by timelineProvider.activeTimelineFlow().collectAsState()
|
||||
val paginationState by timeline.paginationStatus(Timeline.PaginationDirection.BACKWARDS).collectAsState()
|
||||
val pollHistoryItemsFlow = remember {
|
||||
timeline.timelineItems.map { items ->
|
||||
|
||||
@@ -32,6 +32,7 @@ import io.element.android.features.poll.test.actions.FakeEndPollAction
|
||||
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
|
||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.LiveTimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
|
||||
@@ -174,11 +175,11 @@ class PollHistoryPresenterTest {
|
||||
),
|
||||
): PollHistoryPresenter {
|
||||
return PollHistoryPresenter(
|
||||
room = room,
|
||||
appCoroutineScope = appCoroutineScope,
|
||||
sendPollResponseAction = sendPollResponseAction,
|
||||
endPollAction = endPollAction,
|
||||
pollHistoryItemFactory = pollHistoryItemFactory,
|
||||
timelineProvider = LiveTimelineProvider(room),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ package io.element.android.libraries.matrix.api.timeline
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -26,9 +31,11 @@ import javax.inject.Inject
|
||||
* It could be the current room timeline, or a timeline for a specific event.
|
||||
*/
|
||||
interface TimelineProvider {
|
||||
suspend fun getActiveTimeline(): Timeline
|
||||
fun activeTimelineFlow(): StateFlow<Timeline>
|
||||
}
|
||||
|
||||
suspend fun TimelineProvider.getActiveTimeline(): Timeline = activeTimelineFlow().first()
|
||||
|
||||
/**
|
||||
* Default implementation of [TimelineProvider] that provides the live timeline of a room.
|
||||
*/
|
||||
@@ -36,6 +43,6 @@ interface TimelineProvider {
|
||||
class LiveTimelineProvider @Inject constructor(
|
||||
private val room: MatrixRoom,
|
||||
) : TimelineProvider {
|
||||
override suspend fun getActiveTimeline(): Timeline = room.liveTimeline
|
||||
override fun activeTimelineFlow(): StateFlow<Timeline> = MutableStateFlow(room.liveTimeline)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package io.element.android.libraries.matrix.impl.timeline.postprocessor
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||
|
||||
fun List<MatrixTimelineItem>.hasEncryptionHistoryBanner(): Boolean {
|
||||
internal fun List<MatrixTimelineItem>.hasEncryptionHistoryBanner(): Boolean {
|
||||
val firstItem = firstOrNull()
|
||||
return firstItem is MatrixTimelineItem.Virtual &&
|
||||
firstItem.virtual is VirtualTimelineItem.EncryptedHistoryBanner
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.element.android.libraries.matrix.impl.timeline.postprocessor
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
|
||||
@@ -43,10 +44,7 @@ class RoomBeginningPostProcessor {
|
||||
|
||||
private fun processForRoom(items: List<MatrixTimelineItem>): List<MatrixTimelineItem> {
|
||||
if (items.hasEncryptionHistoryBanner()) return items
|
||||
val roomBeginningItem = MatrixTimelineItem.Virtual(
|
||||
uniqueId = VirtualTimelineItem.RoomBeginning.toString(),
|
||||
virtual = VirtualTimelineItem.RoomBeginning
|
||||
)
|
||||
val roomBeginningItem = createRoomBeginningItem()
|
||||
return listOf(roomBeginningItem) + items
|
||||
}
|
||||
|
||||
@@ -77,4 +75,13 @@ class RoomBeginningPostProcessor {
|
||||
}
|
||||
return newItems
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun createRoomBeginningItem(): MatrixTimelineItem.Virtual {
|
||||
return MatrixTimelineItem.Virtual(
|
||||
uniqueId = VirtualTimelineItem.RoomBeginning.toString(),
|
||||
virtual = VirtualTimelineItem.RoomBeginning
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,14 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MembershipCha
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||
import org.junit.Test
|
||||
|
||||
class DmBeginningTimelineProcessorTest {
|
||||
class RoomBeginningPostProcessorTest {
|
||||
@Test
|
||||
fun `processor removes room creation event and self-join event from DM timeline`() {
|
||||
val timelineItems = listOf(
|
||||
@@ -36,7 +37,7 @@ class DmBeginningTimelineProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
|
||||
@@ -53,18 +54,30 @@ class DmBeginningTimelineProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor won't remove items if it's not a DM`() {
|
||||
fun `processor will add beginning of room item if it's not a DM`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = true)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(
|
||||
listOf(processor.createRoomBeginningItem()) + timelineItems
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor will not add beginning of room item if it's not a DM and EncryptedHistoryBanner item is found`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Virtual("EncryptedHistoryBanner", VirtualTimelineItem.EncryptedHistoryBanner),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
@@ -75,7 +88,7 @@ class DmBeginningTimelineProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
@@ -85,7 +98,7 @@ class DmBeginningTimelineProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
@@ -96,7 +109,7 @@ class DmBeginningTimelineProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user