Skip to content

Commit

Permalink
adding tests around marking room as read
Browse files Browse the repository at this point in the history
- fixes wrong message instance being used for filtering
  • Loading branch information
ouchadam committed Nov 6, 2022
1 parent aab6170 commit 6dc98ef
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -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
}
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 6dc98ef

Please sign in to comment.