adding tests around marking room as read
- fixes wrong message instance being used for filtering
This commit is contained in:
parent
aab6170caa
commit
6dc98ef8d3
|
@ -5,9 +5,7 @@ import app.dapk.st.matrix.common.EventId
|
|||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.common.UserId
|
||||
import app.dapk.st.matrix.room.RoomService
|
||||
import app.dapk.st.matrix.sync.RoomEvent
|
||||
import app.dapk.st.matrix.sync.RoomStore
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
@ -24,7 +22,7 @@ class ReadMarkingTimeline(
|
|||
val credentials = credentialsStore.credentials()!!
|
||||
roomStore.markRead(roomId)
|
||||
emit(credentials)
|
||||
}.flatMapMerge { credentials ->
|
||||
}.flatMapConcat { credentials ->
|
||||
var lastKnownReadEvent: EventId? = null
|
||||
observeTimelineUseCase.invoke(roomId, credentials.userId).distinctUntilChanged().onEach { state ->
|
||||
state.latestMessageEventFromOthers(self = credentials.userId)?.let {
|
||||
|
@ -37,8 +35,9 @@ class ReadMarkingTimeline(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun updateRoomReadStateAsync(latestReadEvent: EventId, state: MessengerPageState, isReadReceiptsDisabled: Boolean): Deferred<*> {
|
||||
return coroutineScope {
|
||||
@Suppress("DeferredResultUnused")
|
||||
private suspend fun updateRoomReadStateAsync(latestReadEvent: EventId, state: MessengerPageState, isReadReceiptsDisabled: Boolean) {
|
||||
coroutineScope {
|
||||
async {
|
||||
runCatching {
|
||||
roomService.markFullyRead(state.roomState.roomOverview.roomId, latestReadEvent, isPrivate = isReadReceiptsDisabled)
|
||||
|
@ -48,10 +47,9 @@ class ReadMarkingTimeline(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MessengerPageState.latestMessageEventFromOthers(self: UserId) = this.roomState.events
|
||||
.filterIsInstance<RoomEvent.Message>()
|
||||
.filterNot { it.author.id == self }
|
||||
.firstOrNull()
|
||||
?.eventId
|
||||
}
|
||||
|
||||
private fun MessengerPageState.latestMessageEventFromOthers(self: UserId) = this.roomState.events
|
||||
.filterIsInstance<RoomEvent.Message>()
|
||||
.filterNot { it.author.id == self }
|
||||
.firstOrNull()
|
||||
?.eventId
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.common.UserId
|
||||
import fake.FakeCredentialsStore
|
||||
import fake.FakeRoomStore
|
||||
import fixture.*
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
import org.junit.Test
|
||||
import test.delegateReturn
|
||||
import test.runExpectTest
|
||||
|
||||
private val A_ROOM_ID = aRoomId()
|
||||
private val A_USER_CREDENTIALS = aUserCredentials()
|
||||
private val A_ROOM_MESSAGE_FROM_OTHER_USER = aRoomMessageEvent(author = aRoomMember(id = aUserId("another-user")))
|
||||
private val A_ROOM_MESSAGE_FROM_SELF = aRoomMessageEvent(author = aRoomMember(id = A_USER_CREDENTIALS.userId))
|
||||
private val READ_RECEIPTS_ARE_DISABLED = true
|
||||
|
||||
class ReadMarkingTimelineTest {
|
||||
|
||||
private val fakeRoomStore = FakeRoomStore()
|
||||
private val fakeCredentialsStore = FakeCredentialsStore().apply { givenCredentials().returns(A_USER_CREDENTIALS) }
|
||||
private val fakeObserveTimelineUseCase = FakeObserveTimelineUseCase()
|
||||
private val fakeRoomService = FakeRoomService()
|
||||
|
||||
private val readMarkingTimeline = ReadMarkingTimeline(
|
||||
fakeRoomStore,
|
||||
fakeCredentialsStore,
|
||||
fakeObserveTimelineUseCase,
|
||||
fakeRoomService,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `given a message from self, when fetching, then only marks room as read on initial launch`() = runExpectTest {
|
||||
fakeRoomStore.expectUnit(times = 1) { it.markRead(A_ROOM_ID) }
|
||||
val messengerState = aMessengerState(roomState = aRoomState(events = listOf(A_ROOM_MESSAGE_FROM_SELF)))
|
||||
fakeObserveTimelineUseCase.given(A_ROOM_ID, A_USER_CREDENTIALS.userId).returns(flowOf(messengerState))
|
||||
|
||||
val result = readMarkingTimeline.fetch(A_ROOM_ID, isReadReceiptsDisabled = READ_RECEIPTS_ARE_DISABLED).first()
|
||||
|
||||
result shouldBeEqualTo messengerState
|
||||
verifyExpects()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a message from other user, when fetching, then marks room as read`() = runExpectTest {
|
||||
fakeRoomStore.expectUnit(times = 2) { it.markRead(A_ROOM_ID) }
|
||||
fakeRoomService.expectUnit { it.markFullyRead(A_ROOM_ID, A_ROOM_MESSAGE_FROM_OTHER_USER.eventId, isPrivate = READ_RECEIPTS_ARE_DISABLED) }
|
||||
val messengerState = aMessengerState(roomState = aRoomState(events = listOf(A_ROOM_MESSAGE_FROM_OTHER_USER)))
|
||||
fakeObserveTimelineUseCase.given(A_ROOM_ID, A_USER_CREDENTIALS.userId).returns(flowOf(messengerState))
|
||||
|
||||
val result = readMarkingTimeline.fetch(A_ROOM_ID, isReadReceiptsDisabled = READ_RECEIPTS_ARE_DISABLED).first()
|
||||
|
||||
result shouldBeEqualTo messengerState
|
||||
verifyExpects()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FakeObserveTimelineUseCase : ObserveTimelineUseCase by mockk() {
|
||||
fun given(roomId: RoomId, userId: UserId) = every { this@FakeObserveTimelineUseCase.invoke(roomId, userId) }.delegateReturn()
|
||||
}
|
|
@ -136,7 +136,7 @@ class FakeRoomService : RoomService by mockk() {
|
|||
|
||||
fun aMessengerState(
|
||||
self: UserId = aUserId(),
|
||||
roomState: app.dapk.st.engine.RoomState,
|
||||
roomState: app.dapk.st.engine.RoomState = aRoomState(),
|
||||
typing: Typing? = null,
|
||||
isMuted: Boolean = IS_ROOM_MUTED,
|
||||
) = MessengerPageState(self, roomState, typing, isMuted)
|
Loading…
Reference in New Issue