adding directory use case test

This commit is contained in:
Adam Brown 2022-11-05 11:42:31 +00:00
parent a21f3a1663
commit 623639d2ec
6 changed files with 131 additions and 13 deletions

View File

@ -70,3 +70,8 @@ fun aRoomInvite(
roomId: RoomId = aRoomId(), roomId: RoomId = aRoomId(),
inviteMeta: RoomInvite.InviteMeta = RoomInvite.InviteMeta.DirectMessage, inviteMeta: RoomInvite.InviteMeta = RoomInvite.InviteMeta.DirectMessage,
) = RoomInvite(from, roomId, inviteMeta) ) = RoomInvite(from, roomId, inviteMeta)
fun aTypingEvent(
roomId: RoomId = aRoomId(),
members: List<RoomMember> = listOf(aRoomMember())
) = Typing(roomId, members)

View File

@ -3,7 +3,6 @@ package app.dapk.st.engine
import app.dapk.st.core.extensions.combine import app.dapk.st.core.extensions.combine
import app.dapk.st.matrix.common.CredentialsStore import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.message.MessageService import app.dapk.st.matrix.message.MessageService
import app.dapk.st.matrix.room.RoomService
import app.dapk.st.matrix.sync.RoomStore import app.dapk.st.matrix.sync.RoomStore
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing
@ -17,7 +16,7 @@ internal class DirectoryUseCase(
private val messageService: MessageService, private val messageService: MessageService,
private val credentialsStore: CredentialsStore, private val credentialsStore: CredentialsStore,
private val roomStore: RoomStore, private val roomStore: RoomStore,
private val mergeLocalEchosUseCase: DirectoryMergeWithLocalEchosUseCaseImpl private val mergeLocalEchosUseCase: DirectoryMergeWithLocalEchosUseCase,
) { ) {
fun state(): Flow<DirectoryState> { fun state(): Flow<DirectoryState> {

View File

@ -0,0 +1,115 @@
package app.dapk.st.engine
import app.dapk.st.matrix.common.RoomId
import app.dapk.st.matrix.common.RoomMember
import app.dapk.st.matrix.common.UserId
import app.dapk.st.matrix.message.MessageService
import app.dapk.st.matrix.sync.RoomOverview
import fake.FakeCredentialsStore
import fake.FakeRoomStore
import fake.FakeSyncService
import fixture.aMatrixRoomOverview
import fixture.aRoomMember
import fixture.aTypingEvent
import fixture.aUserCredentials
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
import test.delegateReturn
private val A_ROOM_OVERVIEW = aMatrixRoomOverview()
private const val AN_UNREAD_COUNT = 10
private const val MUTED_ROOM = true
private val TYPING_MEMBERS = listOf(aRoomMember())
class DirectoryUseCaseTest {
private val fakeSyncService = FakeSyncService()
private val fakeMessageService = FakeMessageService()
private val fakeCredentialsStore = FakeCredentialsStore()
private val fakeRoomStore = FakeRoomStore()
private val fakeMergeLocalEchosUseCase = FakeDirectoryMergeWithLocalEchosUseCase()
private val useCase = DirectoryUseCase(
fakeSyncService,
fakeMessageService,
fakeCredentialsStore,
fakeRoomStore,
fakeMergeLocalEchosUseCase,
)
@Test
fun `given empty values, then reads default directory state and maps to engine`() = runTest {
givenEmitsDirectoryState(
A_ROOM_OVERVIEW,
unreadCount = null,
isMuted = false,
)
val result = useCase.state().first()
result shouldBeEqualTo listOf(
DirectoryItem(
A_ROOM_OVERVIEW.engine(),
unreadCount = UnreadCount(0),
typing = null,
isMuted = false
)
)
}
@Test
fun `given extra state, then reads directory state and maps to engine`() = runTest {
givenEmitsDirectoryState(
A_ROOM_OVERVIEW,
unreadCount = AN_UNREAD_COUNT,
isMuted = MUTED_ROOM,
typing = TYPING_MEMBERS
)
val result = useCase.state().first()
result shouldBeEqualTo listOf(
DirectoryItem(
A_ROOM_OVERVIEW.engine(),
unreadCount = UnreadCount(AN_UNREAD_COUNT),
typing = aTypingEvent(A_ROOM_OVERVIEW.roomId, TYPING_MEMBERS),
isMuted = MUTED_ROOM
)
)
}
private fun givenEmitsDirectoryState(
roomOverview: RoomOverview,
unreadCount: Int? = null,
isMuted: Boolean = false,
typing: List<RoomMember> = emptyList(),
) {
val userCredentials = aUserCredentials()
fakeCredentialsStore.givenCredentials().returns(userCredentials)
val matrixOverviewState = listOf(roomOverview)
fakeSyncService.givenStartsSyncing()
fakeSyncService.givenOverview().returns(flowOf(matrixOverviewState))
fakeSyncService.givenEvents().returns(flowOf(if (typing.isEmpty()) emptyList() else listOf(aTypingSyncEvent(roomOverview.roomId, typing))))
fakeMessageService.givenEchos().returns(flowOf(emptyMap()))
fakeRoomStore.givenUnreadByCount().returns(flowOf(unreadCount?.let { mapOf(roomOverview.roomId to it) } ?: emptyMap()))
fakeRoomStore.givenMuted().returns(flowOf(if (isMuted) setOf(roomOverview.roomId) else emptySet()))
val mappedOverview = roomOverview.engine()
val expectedOverviewState = listOf(mappedOverview)
fakeMergeLocalEchosUseCase.givenMergedEchos(expectedOverviewState, userCredentials.userId, emptyMap()).returns(expectedOverviewState)
}
}
class FakeDirectoryMergeWithLocalEchosUseCase : DirectoryMergeWithLocalEchosUseCase by mockk() {
fun givenMergedEchos(overviewState: OverviewState, selfId: UserId, echos: Map<RoomId, List<MessageService.LocalEcho>>) = coEvery {
this@FakeDirectoryMergeWithLocalEchosUseCase.invoke(overviewState, selfId, echos)
}.delegateReturn()
}

View File

@ -125,9 +125,8 @@ fun aTypingSyncEvent(
) = SyncService.SyncEvent.Typing(roomId, members) ) = SyncService.SyncEvent.Typing(roomId, members)
class FakeMessageService : MessageService by mockk() { class FakeMessageService : MessageService by mockk() {
fun givenEchos(roomId: RoomId) = every { localEchos(roomId) }.delegateReturn() fun givenEchos(roomId: RoomId) = every { localEchos(roomId) }.delegateReturn()
fun givenEchos() = every { localEchos() }.delegateReturn()
} }
class FakeRoomService : RoomService by mockk() { class FakeRoomService : RoomService by mockk() {

View File

@ -10,6 +10,7 @@ import io.mockk.coVerify
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import test.delegateReturn
class FakeRoomStore : RoomStore by mockk() { class FakeRoomStore : RoomStore by mockk() {
@ -34,8 +35,13 @@ class FakeRoomStore : RoomStore by mockk() {
every { observeUnread() } returns unreadEvents every { observeUnread() } returns unreadEvents
} }
fun givenUnreadEvents() = every { observeUnread() }.delegateReturn()
fun givenUnreadByCount() = every { observeUnreadCountById() }.delegateReturn()
fun givenNotMutedUnreadEvents(unreadEvents: Flow<Map<RoomOverview, List<RoomEvent>>>) { fun givenNotMutedUnreadEvents(unreadEvents: Flow<Map<RoomOverview, List<RoomEvent>>>) {
every { observeNotMutedUnread() } returns unreadEvents every { observeNotMutedUnread() } returns unreadEvents
} }
fun givenMuted() = every { observeMuted() }.delegateReturn()
} }

View File

@ -4,19 +4,13 @@ import app.dapk.st.matrix.common.RoomId
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import test.delegateReturn import test.delegateReturn
class FakeSyncService : SyncService by mockk() { class FakeSyncService : SyncService by mockk() {
fun givenStartsSyncing() { fun givenStartsSyncing() = every { startSyncing() }.returns(flowOf(Unit))
every { startSyncing() }.returns(flowOf(Unit))
}
fun givenRoom(roomId: RoomId) = every { room(roomId) }.delegateReturn() fun givenRoom(roomId: RoomId) = every { room(roomId) }.delegateReturn()
fun givenEvents(roomId: RoomId? = null) = every { events(roomId) }.delegateReturn()
fun givenEvents(roomId: RoomId) = every { events(roomId) }.delegateReturn()
fun givenInvites() = every { invites() }.delegateReturn() fun givenInvites() = every { invites() }.delegateReturn()
fun givenOverview() = every { overview() }.delegateReturn()
} }