update tests to reflect muting

This commit is contained in:
Adam Brown 2022-11-02 14:42:35 +00:00
parent 20e4470511
commit 68674aeaab
11 changed files with 44 additions and 36 deletions

View File

@ -6,8 +6,9 @@ import app.dapk.st.matrix.common.*
fun aMessengerState( fun aMessengerState(
self: UserId = aUserId(), self: UserId = aUserId(),
roomState: RoomState, roomState: RoomState,
typing: Typing? = null typing: Typing? = null,
) = MessengerPageState(self, roomState, typing) isMuted: Boolean = false,
) = MessengerPageState(self, roomState, typing, isMuted)
fun aRoomOverview( fun aRoomOverview(
roomId: RoomId = aRoomId(), roomId: RoomId = aRoomId(),

View File

@ -2,7 +2,6 @@ package app.dapk.st.directory
import app.dapk.st.core.JobBag import app.dapk.st.core.JobBag
import app.dapk.st.directory.state.* import app.dapk.st.directory.state.*
import app.dapk.st.engine.DirectoryItem
import app.dapk.st.engine.UnreadCount import app.dapk.st.engine.UnreadCount
import fake.FakeChatEngine import fake.FakeChatEngine
import fixture.aRoomOverview import fixture.aRoomOverview
@ -13,7 +12,7 @@ import test.expect
import test.testReducer import test.testReducer
private val AN_OVERVIEW = aRoomOverview() private val AN_OVERVIEW = aRoomOverview()
private val AN_OVERVIEW_STATE = DirectoryItem(AN_OVERVIEW, UnreadCount(1), null) private val AN_OVERVIEW_STATE = app.dapk.st.engine.DirectoryItem(AN_OVERVIEW, UnreadCount(1), null, isMuted = false)
class DirectoryReducerTest { class DirectoryReducerTest {

View File

@ -3,12 +3,10 @@ package app.dapk.st.messenger
import android.os.Build import android.os.Build
import app.dapk.st.core.* import app.dapk.st.core.*
import app.dapk.st.design.components.BubbleModel import app.dapk.st.design.components.BubbleModel
import app.dapk.st.domain.room.MutedRoomsStore
import app.dapk.st.engine.RoomEvent import app.dapk.st.engine.RoomEvent
import app.dapk.st.engine.RoomState import app.dapk.st.engine.RoomState
import app.dapk.st.engine.SendMessage import app.dapk.st.engine.SendMessage
import app.dapk.st.matrix.common.EventId 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.common.UserId
import app.dapk.st.matrix.common.asString import app.dapk.st.matrix.common.asString
import app.dapk.st.messenger.state.* import app.dapk.st.messenger.state.*
@ -16,7 +14,6 @@ import app.dapk.st.navigator.MessageAttachment
import fake.FakeChatEngine import fake.FakeChatEngine
import fake.FakeMessageOptionsStore import fake.FakeMessageOptionsStore
import fixture.* import fixture.*
import io.mockk.coEvery
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
@ -52,7 +49,6 @@ class MessengerReducerTest {
private val fakeChatEngine = FakeChatEngine() private val fakeChatEngine = FakeChatEngine()
private val fakeCopyToClipboard = FakeCopyToClipboard() private val fakeCopyToClipboard = FakeCopyToClipboard()
private val fakeDeviceMeta = FakeDeviceMeta() private val fakeDeviceMeta = FakeDeviceMeta()
private val fakeMutedRoomsStore = FakeMutedRoomsStore()
private val fakeJobBag = FakeJobBag() private val fakeJobBag = FakeJobBag()
private val runReducerTest = testReducer { fakeEventSource -> private val runReducerTest = testReducer { fakeEventSource ->
@ -62,7 +58,6 @@ class MessengerReducerTest {
fakeCopyToClipboard.instance, fakeCopyToClipboard.instance,
fakeDeviceMeta.instance, fakeDeviceMeta.instance,
fakeMessageOptionsStore.instance, fakeMessageOptionsStore.instance,
fakeMutedRoomsStore,
A_ROOM_ID, A_ROOM_ID,
emptyList(), emptyList(),
fakeEventSource, fakeEventSource,
@ -77,7 +72,6 @@ class MessengerReducerTest {
roomState = Lce.Loading(), roomState = Lce.Loading(),
composerState = ComposerState.Text(value = "", reply = null), composerState = ComposerState.Text(value = "", reply = null),
viewerState = null, viewerState = null,
isMuted = false,
) )
) )
} }
@ -90,7 +84,6 @@ class MessengerReducerTest {
roomState = Lce.Loading(), roomState = Lce.Loading(),
composerState = ComposerState.Text(value = "", reply = null), composerState = ComposerState.Text(value = "", reply = null),
viewerState = null, viewerState = null,
isMuted = false,
) )
) )
} }
@ -103,14 +96,12 @@ class MessengerReducerTest {
roomState = Lce.Loading(), roomState = Lce.Loading(),
composerState = ComposerState.Attachments(listOf(A_MESSAGE_ATTACHMENT), reply = null), composerState = ComposerState.Attachments(listOf(A_MESSAGE_ATTACHMENT), reply = null),
viewerState = null, viewerState = null,
isMuted = false,
) )
) )
} }
@Test @Test
fun `given room is muted and messages emits state, when Visible, then dispatches content and mute changes`() = runReducerTest { fun `given messages emits state, when Visible, then dispatches content`() = runReducerTest {
fakeMutedRoomsStore.givenIsMuted(A_ROOM_ID).returns(ROOM_IS_MUTED)
fakeJobBag.instance.expect { it.replace("messages", any()) } fakeJobBag.instance.expect { it.replace("messages", any()) }
fakeMessageOptionsStore.givenReadReceiptsDisabled().returns(READ_RECEIPTS_ARE_DISABLED) fakeMessageOptionsStore.givenReadReceiptsDisabled().returns(READ_RECEIPTS_ARE_DISABLED)
val state = aMessengerStateWithEvent(AN_EVENT_ID, A_SELF_ID) val state = aMessengerStateWithEvent(AN_EVENT_ID, A_SELF_ID)
@ -118,7 +109,7 @@ class MessengerReducerTest {
reduce(ComponentLifecycle.Visible) reduce(ComponentLifecycle.Visible)
assertOnlyDispatches(listOf(MessagesStateChange.MuteContent(isMuted = ROOM_IS_MUTED), MessagesStateChange.Content(state))) assertOnlyDispatches(listOf(MessagesStateChange.Content(state)))
} }
@Test @Test
@ -340,7 +331,6 @@ class MessengerReducerTest {
fakeCopyToClipboard.instance, fakeCopyToClipboard.instance,
fakeDeviceMeta.instance, fakeDeviceMeta.instance,
fakeMessageOptionsStore.instance, fakeMessageOptionsStore.instance,
FakeMutedRoomsStore(),
A_ROOM_ID, A_ROOM_ID,
initialAttachments = initialAttachments, initialAttachments = initialAttachments,
fakeEventSource, fakeEventSource,
@ -371,7 +361,3 @@ class FakeDeviceMeta {
fun givenApiVersion() = every { instance.apiVersion }.delegateReturn() fun givenApiVersion() = every { instance.apiVersion }.delegateReturn()
} }
class FakeMutedRoomsStore : MutedRoomsStore by mockk() {
fun givenIsMuted(roomId: RoomId) = coEvery { isMuted(roomId) }.delegateReturn()
}

View File

@ -146,11 +146,7 @@ internal object MatrixFactory {
roomInviteRemover = { roomInviteRemover = {
overviewStore.removeInvites(listOf(it)) overviewStore.removeInvites(listOf(it))
}, },
singleRoomStore = object : SingleRoomStore { singleRoomStore = singleRoomStoreAdapter(roomStore)
override suspend fun mute(roomId: RoomId) = roomStore.mute(roomId)
override suspend fun unmute(roomId: RoomId) = roomStore.unmute(roomId)
override fun isMuted(roomId: RoomId): Flow<Boolean> = roomStore.observeMuted().map { it.contains(roomId) }.distinctUntilChanged()
}
) )
installProfileService(profileStore, singletonFlows, credentialsStore) installProfileService(profileStore, singletonFlows, credentialsStore)
@ -253,4 +249,10 @@ internal object MatrixFactory {
} }
} }
private fun singleRoomStoreAdapter(roomStore: RoomStore) = object : SingleRoomStore {
override suspend fun mute(roomId: RoomId) = roomStore.mute(roomId)
override suspend fun unmute(roomId: RoomId) = roomStore.unmute(roomId)
override fun isMuted(roomId: RoomId): Flow<Boolean> = roomStore.observeMuted().map { it.contains(roomId) }.distinctUntilChanged()
}
} }

View File

@ -24,7 +24,7 @@ internal class TimelineUseCaseImpl(
roomDatasource(roomId), roomDatasource(roomId),
messageService.localEchos(roomId), messageService.localEchos(roomId),
syncService.events(roomId), syncService.events(roomId),
roomService.observeIssMuted(roomId), roomService.observeIsMuted(roomId),
) { roomState, localEchos, events, isMuted -> ) { roomState, localEchos, events, isMuted ->
MessengerPageState( MessengerPageState(
roomState = when { roomState = when {

View File

@ -61,7 +61,7 @@ class ObserveUnreadRenderNotificationsUseCaseTest {
@Test @Test
fun `given initial unreads, when receiving new message, then emits all messages`() = runTest { fun `given initial unreads, when receiving new message, then emits all messages`() = runTest {
fakeRoomStore.givenUnreadEvents( fakeRoomStore.givenNotMutedUnreadEvents(
flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE, A_MESSAGE_2)) flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE, A_MESSAGE_2))
) )
@ -74,7 +74,7 @@ class ObserveUnreadRenderNotificationsUseCaseTest {
@Test @Test
fun `given initial unreads, when reading a message, then emits nothing`() = runTest { fun `given initial unreads, when reading a message, then emits nothing`() = runTest {
fakeRoomStore.givenUnreadEvents( fakeRoomStore.givenNotMutedUnreadEvents(
flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE) + A_ROOM_OVERVIEW_2.withUnreads(A_MESSAGE_2), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE)) flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE) + A_ROOM_OVERVIEW_2.withUnreads(A_MESSAGE_2), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE))
) )
@ -85,7 +85,7 @@ class ObserveUnreadRenderNotificationsUseCaseTest {
@Test @Test
fun `given new and then historical message, when reading a message, then only emits the latest`() = runTest { fun `given new and then historical message, when reading a message, then only emits the latest`() = runTest {
fakeRoomStore.givenUnreadEvents( fakeRoomStore.givenNotMutedUnreadEvents(
flowOf( flowOf(
NO_UNREADS, NO_UNREADS,
A_ROOM_OVERVIEW.withUnreads(A_MESSAGE), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE),
@ -105,7 +105,7 @@ class ObserveUnreadRenderNotificationsUseCaseTest {
@Test @Test
fun `given initial unreads, when reading a duplicate unread, then emits nothing`() = runTest { fun `given initial unreads, when reading a duplicate unread, then emits nothing`() = runTest {
fakeRoomStore.givenUnreadEvents( fakeRoomStore.givenNotMutedUnreadEvents(
flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE)) flowOf(A_ROOM_OVERVIEW.withUnreads(A_MESSAGE), A_ROOM_OVERVIEW.withUnreads(A_MESSAGE))
) )
@ -115,7 +115,7 @@ class ObserveUnreadRenderNotificationsUseCaseTest {
} }
private fun givenNoInitialUnreads(vararg unreads: Map<MatrixRoomOverview, List<MatrixRoomEvent>>) = private fun givenNoInitialUnreads(vararg unreads: Map<MatrixRoomOverview, List<MatrixRoomEvent>>) =
fakeRoomStore.givenUnreadEvents(flowOf(NO_UNREADS, *unreads)) fakeRoomStore.givenNotMutedUnreadEvents(flowOf(NO_UNREADS, *unreads))
} }
private fun Map<MatrixRoomOverview, List<MatrixRoomEvent>>.engine() = this private fun Map<MatrixRoomOverview, List<MatrixRoomEvent>>.engine() = this

View File

@ -22,6 +22,7 @@ import org.junit.Test
import test.FlowTestObserver import test.FlowTestObserver
import test.delegateReturn import test.delegateReturn
private const val IS_ROOM_MUTED = false
private val A_ROOM_ID = aRoomId() private val A_ROOM_ID = aRoomId()
private val AN_USER_ID = aUserId() private val AN_USER_ID = aUserId()
private val A_ROOM_STATE = aMatrixRoomState() private val A_ROOM_STATE = aMatrixRoomState()
@ -63,6 +64,7 @@ class TimelineUseCaseTest {
fakeMergeWithLocalEchosUseCase.givenMerging(A_ROOM_STATE, A_ROOM_MEMBER, A_LOCAL_ECHOS_LIST).returns(A_MERGED_ROOM_STATE.engine()) fakeMergeWithLocalEchosUseCase.givenMerging(A_ROOM_STATE, A_ROOM_MEMBER, A_LOCAL_ECHOS_LIST).returns(A_MERGED_ROOM_STATE.engine())
timelineUseCase.invoke(A_ROOM_ID, AN_USER_ID) timelineUseCase.invoke(A_ROOM_ID, AN_USER_ID)
.test(this) .test(this)
.assertValues( .assertValues(
@ -103,6 +105,7 @@ class TimelineUseCaseTest {
fakeSyncService.givenRoom(A_ROOM_ID).returns(flowOf(roomState)) fakeSyncService.givenRoom(A_ROOM_ID).returns(flowOf(roomState))
fakeMessageService.givenEchos(A_ROOM_ID).returns(flowOf(echos)) fakeMessageService.givenEchos(A_ROOM_ID).returns(flowOf(echos))
fakeSyncService.givenEvents(A_ROOM_ID).returns(flowOf(events)) fakeSyncService.givenEvents(A_ROOM_ID).returns(flowOf(events))
fakeRoomService.givenMuted(A_ROOM_ID).returns(flowOf(IS_ROOM_MUTED))
} }
} }
@ -129,10 +132,12 @@ class FakeMessageService : MessageService by mockk() {
class FakeRoomService : RoomService by mockk() { class FakeRoomService : RoomService by mockk() {
fun givenFindMember(roomId: RoomId, userId: UserId) = coEvery { findMember(roomId, userId) }.delegateReturn() fun givenFindMember(roomId: RoomId, userId: UserId) = coEvery { findMember(roomId, userId) }.delegateReturn()
fun givenMuted(roomId: RoomId) = every { observeIsMuted(roomId) }.delegateReturn()
} }
fun aMessengerState( fun aMessengerState(
self: UserId = aUserId(), self: UserId = aUserId(),
roomState: app.dapk.st.engine.RoomState, roomState: app.dapk.st.engine.RoomState,
typing: Typing? = null typing: Typing? = null,
) = MessengerPageState(self, roomState, typing) isMuted: Boolean = IS_ROOM_MUTED,
) = MessengerPageState(self, roomState, typing, isMuted)

View File

@ -27,7 +27,7 @@ interface RoomService : MatrixService {
suspend fun muteRoom(roomId: RoomId) suspend fun muteRoom(roomId: RoomId)
suspend fun unmuteRoom(roomId: RoomId) suspend fun unmuteRoom(roomId: RoomId)
fun observeIssMuted(roomId: RoomId): Flow<Boolean> fun observeIsMuted(roomId: RoomId): Flow<Boolean>
data class JoinedMember( data class JoinedMember(
val userId: UserId, val userId: UserId,

View File

@ -102,7 +102,7 @@ class DefaultRoomService(
singleRoomStore.unmute(roomId) singleRoomStore.unmute(roomId)
} }
override fun observeIssMuted(roomId: RoomId): Flow<Boolean> = singleRoomStore.isMuted(roomId) override fun observeIsMuted(roomId: RoomId): Flow<Boolean> = singleRoomStore.isMuted(roomId)
} }
interface SingleRoomStore { interface SingleRoomStore {

View File

@ -34,4 +34,8 @@ class FakeRoomStore : RoomStore by mockk() {
every { observeUnread() } returns unreadEvents every { observeUnread() } returns unreadEvents
} }
fun givenNotMutedUnreadEvents(unreadEvents: Flow<Map<RoomOverview, List<RoomEvent>>>) {
every { observeNotMutedUnread() } returns unreadEvents
}
} }

View File

@ -23,6 +23,7 @@ import app.dapk.st.matrix.message.internal.ImageContentReader
import app.dapk.st.matrix.push.installPushService import app.dapk.st.matrix.push.installPushService
import app.dapk.st.matrix.room.RoomMessenger import app.dapk.st.matrix.room.RoomMessenger
import app.dapk.st.matrix.room.installRoomService import app.dapk.st.matrix.room.installRoomService
import app.dapk.st.matrix.room.internal.SingleRoomStore
import app.dapk.st.matrix.room.roomService import app.dapk.st.matrix.room.roomService
import app.dapk.st.matrix.sync.* import app.dapk.st.matrix.sync.*
import app.dapk.st.matrix.sync.internal.request.ApiToDeviceEvent import app.dapk.st.matrix.sync.internal.request.ApiToDeviceEvent
@ -31,6 +32,9 @@ import app.dapk.st.olm.DeviceKeyFactory
import app.dapk.st.olm.OlmPersistenceWrapper import app.dapk.st.olm.OlmPersistenceWrapper
import app.dapk.st.olm.OlmWrapper import app.dapk.st.olm.OlmWrapper
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.amshove.kluent.fail import org.amshove.kluent.fail
import test.impl.InMemoryDatabase import test.impl.InMemoryDatabase
@ -178,7 +182,8 @@ class TestMatrix(
} }
} }
}, },
roomInviteRemover = { storeModule.overviewStore().removeInvites(listOf(it)) } roomInviteRemover = { storeModule.overviewStore().removeInvites(listOf(it)) },
singleRoomStore = singleRoomStoreAdapter(storeModule.roomStore())
) )
installSyncService( installSyncService(
@ -378,4 +383,10 @@ class ProxyDeviceService(private val deviceService: DeviceService) : DeviceServi
} }
private fun singleRoomStoreAdapter(roomStore: RoomStore) = object : SingleRoomStore {
override suspend fun mute(roomId: RoomId) = roomStore.mute(roomId)
override suspend fun unmute(roomId: RoomId) = roomStore.unmute(roomId)
override fun isMuted(roomId: RoomId): Flow<Boolean> = roomStore.observeMuted().map { it.contains(roomId) }.distinctUntilChanged()
}
fun MatrixClient.proxyDeviceService() = this.deviceService() as ProxyDeviceService fun MatrixClient.proxyDeviceService() = this.deviceService() as ProxyDeviceService