diff --git a/chat-engine/src/testFixtures/kotlin/fixture/Fixtures.kt b/chat-engine/src/testFixtures/kotlin/fixture/Fixtures.kt index 14e038b..5bf9444 100644 --- a/chat-engine/src/testFixtures/kotlin/fixture/Fixtures.kt +++ b/chat-engine/src/testFixtures/kotlin/fixture/Fixtures.kt @@ -70,3 +70,8 @@ fun aRoomInvite( roomId: RoomId = aRoomId(), inviteMeta: RoomInvite.InviteMeta = RoomInvite.InviteMeta.DirectMessage, ) = RoomInvite(from, roomId, inviteMeta) + +fun aTypingEvent( + roomId: RoomId = aRoomId(), + members: List = listOf(aRoomMember()) +) = Typing(roomId, members) \ No newline at end of file diff --git a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/DirectoryUseCase.kt b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/DirectoryUseCase.kt index f6282d3..27b8799 100644 --- a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/DirectoryUseCase.kt +++ b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/DirectoryUseCase.kt @@ -3,7 +3,6 @@ package app.dapk.st.engine import app.dapk.st.core.extensions.combine import app.dapk.st.matrix.common.CredentialsStore 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.SyncService import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing @@ -17,7 +16,7 @@ internal class DirectoryUseCase( private val messageService: MessageService, private val credentialsStore: CredentialsStore, private val roomStore: RoomStore, - private val mergeLocalEchosUseCase: DirectoryMergeWithLocalEchosUseCaseImpl + private val mergeLocalEchosUseCase: DirectoryMergeWithLocalEchosUseCase, ) { fun state(): Flow { diff --git a/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/DirectoryUseCaseTest.kt b/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/DirectoryUseCaseTest.kt new file mode 100644 index 0000000..081000e --- /dev/null +++ b/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/DirectoryUseCaseTest.kt @@ -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 = 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>) = coEvery { + this@FakeDirectoryMergeWithLocalEchosUseCase.invoke(overviewState, selfId, echos) + }.delegateReturn() +} diff --git a/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/TimelineUseCaseTest.kt b/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/TimelineUseCaseTest.kt index 1936e9a..73d980e 100644 --- a/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/TimelineUseCaseTest.kt +++ b/matrix-chat-engine/src/test/kotlin/app/dapk/st/engine/TimelineUseCaseTest.kt @@ -125,9 +125,8 @@ fun aTypingSyncEvent( ) = SyncService.SyncEvent.Typing(roomId, members) class FakeMessageService : MessageService by mockk() { - fun givenEchos(roomId: RoomId) = every { localEchos(roomId) }.delegateReturn() - + fun givenEchos() = every { localEchos() }.delegateReturn() } class FakeRoomService : RoomService by mockk() { diff --git a/matrix/services/sync/src/testFixtures/kotlin/fake/FakeRoomStore.kt b/matrix/services/sync/src/testFixtures/kotlin/fake/FakeRoomStore.kt index 3b1cbb2..9a6bb1e 100644 --- a/matrix/services/sync/src/testFixtures/kotlin/fake/FakeRoomStore.kt +++ b/matrix/services/sync/src/testFixtures/kotlin/fake/FakeRoomStore.kt @@ -10,6 +10,7 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.flow.Flow +import test.delegateReturn class FakeRoomStore : RoomStore by mockk() { @@ -34,8 +35,13 @@ class FakeRoomStore : RoomStore by mockk() { every { observeUnread() } returns unreadEvents } + fun givenUnreadEvents() = every { observeUnread() }.delegateReturn() + fun givenUnreadByCount() = every { observeUnreadCountById() }.delegateReturn() + fun givenNotMutedUnreadEvents(unreadEvents: Flow>>) { every { observeNotMutedUnread() } returns unreadEvents } + fun givenMuted() = every { observeMuted() }.delegateReturn() + } \ No newline at end of file diff --git a/matrix/services/sync/src/testFixtures/kotlin/fake/FakeSyncService.kt b/matrix/services/sync/src/testFixtures/kotlin/fake/FakeSyncService.kt index 1721c48..d0acc50 100644 --- a/matrix/services/sync/src/testFixtures/kotlin/fake/FakeSyncService.kt +++ b/matrix/services/sync/src/testFixtures/kotlin/fake/FakeSyncService.kt @@ -4,19 +4,13 @@ import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.sync.SyncService import io.mockk.every import io.mockk.mockk -import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import test.delegateReturn class FakeSyncService : SyncService by mockk() { - fun givenStartsSyncing() { - every { startSyncing() }.returns(flowOf(Unit)) - } - + fun givenStartsSyncing() = every { startSyncing() }.returns(flowOf(Unit)) fun givenRoom(roomId: RoomId) = every { room(roomId) }.delegateReturn() - - fun givenEvents(roomId: RoomId) = every { events(roomId) }.delegateReturn() - + fun givenEvents(roomId: RoomId? = null) = every { events(roomId) }.delegateReturn() fun givenInvites() = every { invites() }.delegateReturn() - + fun givenOverview() = every { overview() }.delegateReturn() }