Split MatrixRoom into BaseRoom and JoinedRoom (#4561)

`JoinedRoom` will now contain both a mandatory live timeline reference and all the functionality associated to it.

`BaseRoom` on the other hand will contain only functionality that's shared for both joined and not joined rooms.

`NotJoinedRoom` is a wrapper around `RoomPreviewInfo` data and a possible local `BaseRoom`, if it exists.

The `RustRoomFactory` cache is now gone since the persistent event cache should have the same effect.
This commit is contained in:
Jorge Martin Espinosa 2025-04-23 15:53:40 +02:00 committed by GitHub
parent 91cb84ce8d
commit 619aa6f2de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
193 changed files with 2921 additions and 2567 deletions

View file

@ -10,14 +10,17 @@ package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.appnav.di.RoomComponentFactory
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import javax.inject.Inject
@ContributesBinding(SessionScope::class)
class DefaultRoomComponentFactory @Inject constructor(
private val roomComponentBuilder: RoomComponent.Builder
) : RoomComponentFactory {
override fun create(room: MatrixRoom): Any {
return roomComponentBuilder.room(room).build()
override fun create(room: JoinedRoom): Any {
return roomComponentBuilder
.joinedRoom(room)
.baseRoom(room)
.build()
}
}

View file

@ -14,7 +14,8 @@ import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
@SingleIn(RoomScope::class)
@MergeSubcomponent(RoomScope::class)
@ -22,7 +23,11 @@ interface RoomComponent : NodeFactoriesBindings {
@MergeSubcomponent.Builder
interface Builder {
@BindsInstance
fun room(room: MatrixRoom): Builder
fun joinedRoom(room: JoinedRoom): Builder
@BindsInstance
fun baseRoom(room: BaseRoom): Builder
fun build(): RoomComponent
}

View file

@ -7,8 +7,8 @@
package io.element.android.appnav.di
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
interface RoomComponentFactory {
fun create(room: MatrixRoom): Any
fun create(room: JoinedRoom): Any
}

View file

@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
@VisibleForTesting
@ -42,7 +43,9 @@ class SendQueues @Inject constructor(
) { syncState, _ -> syncState }
.debounce(SEND_QUEUES_RETRY_DELAY_MILLIS)
.onEach { syncState ->
Timber.tag("SendQueues").d("Sync state changed: $syncState")
if (syncState == SyncState.Running) {
Timber.tag("SendQueues").d("Enabling send queues again")
matrixClient.setAllSendQueuesEnabled(enabled = true)
}
}

View file

@ -35,7 +35,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.services.appnavstate.api.AppNavigationStateService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -72,7 +72,7 @@ class JoinedRoomLoadedFlowNode @AssistedInject constructor(
}
data class Inputs(
val room: MatrixRoom,
val room: JoinedRoom,
val initialElement: RoomNavigationTarget,
) : NodeInputs
@ -95,6 +95,7 @@ class JoinedRoomLoadedFlowNode @AssistedInject constructor(
},
onDestroy = {
Timber.v("OnDestroy")
inputs.room.destroy()
appNavigationStateService.onLeavingRoom(id)
}
)

View file

@ -13,7 +13,7 @@ import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
@ -27,7 +27,7 @@ import javax.inject.Inject
sealed interface LoadingRoomState {
data object Loading : LoadingRoomState
data object Error : LoadingRoomState
data class Loaded(val room: MatrixRoom) : LoadingRoomState
data class Loaded(val room: JoinedRoom) : LoadingRoomState
}
open class LoadingRoomStateProvider : PreviewParameterProvider<LoadingRoomState> {
@ -41,7 +41,7 @@ open class LoadingRoomStateProvider : PreviewParameterProvider<LoadingRoomState>
@SingleIn(SessionScope::class)
class LoadingRoomStateFlowFactory @Inject constructor(private val matrixClient: MatrixClient) {
fun create(lifecycleScope: CoroutineScope, roomId: RoomId): StateFlow<LoadingRoomState> =
getRoomFlow(roomId)
getJoinedRoomFlow(roomId)
.map { room ->
if (room != null) {
LoadingRoomState.Loaded(room)
@ -51,8 +51,8 @@ class LoadingRoomStateFlowFactory @Inject constructor(private val matrixClient:
}
.stateIn(lifecycleScope, SharingStarted.Eagerly, LoadingRoomState.Loading)
private fun getRoomFlow(roomId: RoomId): Flow<MatrixRoom?> = suspend {
matrixClient.getRoom(roomId = roomId)
private fun getJoinedRoomFlow(roomId: RoomId): Flow<JoinedRoom?> = suspend {
matrixClient.getJoinedRoom(roomId = roomId)
}
.asFlow()
}

View file

@ -23,16 +23,17 @@ import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
import io.element.android.features.messages.api.MessagesEntryPoint
import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint
import io.element.android.libraries.architecture.childNode
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.services.appnavstate.test.FakeAppNavigationStateService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
class JoinRoomLoadedFlowNodeTest {
class JoinBaseRoomLoadedFlowNodeTest {
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
@ -68,7 +69,7 @@ class JoinRoomLoadedFlowNodeTest {
}
private class FakeRoomComponentFactory : RoomComponentFactory {
override fun create(room: MatrixRoom): Any {
override fun create(room: JoinedRoom): Any {
return Unit
}
}
@ -114,9 +115,7 @@ class JoinRoomLoadedFlowNodeTest {
@Test
fun `given a room flow node when initialized then it loads messages entry point`() = runTest {
// GIVEN
val room = FakeMatrixRoom(
updateMembersResult = { }
)
val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(updateMembersResult = {}))
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())
val roomFlowNode = createJoinedRoomLoadedFlowNode(
@ -137,9 +136,7 @@ class JoinRoomLoadedFlowNodeTest {
@Test
fun `given a room flow node when callback on room details is triggered then it loads room details entry point`() = runTest {
// GIVEN
val room = FakeMatrixRoom(
updateMembersResult = { }
)
val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(updateMembersResult = {}))
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
val fakeRoomDetailsEntryPoint = FakeRoomDetailsEntryPoint()
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())

View file

@ -10,7 +10,7 @@ package io.element.android.appnav.loggedin
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.tests.testutils.lambda.assert
import io.element.android.tests.testutils.lambda.lambdaRecorder
@ -35,8 +35,8 @@ class SendQueuesTest {
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
val room = FakeMatrixRoom(
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
val room = FakeJoinedRoom(
setSendQueueEnabledResult = setRoomSendQueueEnabledLambda
)
matrixClient.givenGetRoomResult(room.roomId, room)
sut.launchIn(backgroundScope)
@ -61,8 +61,8 @@ class SendQueuesTest {
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
syncService.emitSyncState(SyncState.Offline)
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
val room = FakeMatrixRoom(
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
val room = FakeJoinedRoom(
setSendQueueEnabledResult = setRoomSendQueueEnabledLambda
)
matrixClient.givenGetRoomResult(room.roomId, room)

View file

@ -15,15 +15,16 @@ import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import kotlinx.coroutines.test.runTest
import org.junit.Test
class LoadingRoomStateFlowFactoryTest {
class LoadingBaseRoomStateFlowFactoryTest {
@Test
fun `flow should emit Loading and then Loaded when there is a room in cache`() = runTest {
val room = FakeMatrixRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID)
val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID))
val matrixClient = FakeMatrixClient(A_SESSION_ID).apply {
givenGetRoomResult(A_ROOM_ID, room)
}
@ -38,7 +39,7 @@ class LoadingRoomStateFlowFactoryTest {
@Test
fun `flow should emit Loading and then Loaded when there is a room in cache after SS is loaded`() = runTest {
val room = FakeMatrixRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID)
val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID))
val roomListService = FakeRoomListService()
val matrixClient = FakeMatrixClient(A_SESSION_ID, roomListService = roomListService)
val flowFactory = LoadingRoomStateFlowFactory(matrixClient)

View file

@ -241,7 +241,7 @@ class CallScreenPresenter @AssistedInject constructor(
private suspend fun MatrixClient.notifyCallStartIfNeeded(roomId: RoomId) {
if (!notifiedCallStart) {
getRoom(roomId)?.sendCallNotificationIfNeeded()
getJoinedRoom(roomId)?.sendCallNotificationIfNeeded()
?.onSuccess { notifiedCallStart = true }
}
}

View file

@ -33,7 +33,7 @@ class DefaultCallWidgetProvider @Inject constructor(
theme: String?,
): Result<CallWidgetProvider.GetWidgetResult> = runCatching {
val matrixClient = matrixClientsProvider.getOrRestore(sessionId).getOrThrow()
val room = matrixClient.getRoom(roomId) ?: error("Room not found")
val room = matrixClient.getJoinedRoom(roomId) ?: error("Room not found")
val customBaseUrl = appPreferencesStore.getCustomElementCallBaseUrlFlow().firstOrNull()
val baseUrl = customBaseUrl ?: EMBEDDED_CALL_WIDGET_BASE_URL

View file

@ -26,7 +26,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.libraries.matrix.test.widget.FakeMatrixWidgetDriver
import io.element.android.libraries.network.useragent.UserAgentProvider
@ -84,7 +84,7 @@ import kotlin.time.Duration.Companion.seconds
fun `present - with CallType RoomCall sets call as active, loads URL, runs WidgetDriver and notifies the other clients a call started`() = runTest {
val sendCallNotificationIfNeededLambda = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
val syncService = FakeSyncService(SyncState.Running)
val fakeRoom = FakeMatrixRoom(sendCallNotificationIfNeededResult = sendCallNotificationIfNeededLambda)
val fakeRoom = FakeJoinedRoom(sendCallNotificationIfNeededResult = sendCallNotificationIfNeededLambda)
val client = FakeMatrixClient(syncService = syncService).apply {
givenGetRoomResult(A_ROOM_ID, fakeRoom)
}

View file

@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID_2
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.push.api.notifications.ForegroundServiceType
import io.element.android.libraries.push.api.notifications.NotificationIdProvider
@ -227,7 +227,7 @@ class DefaultActiveCallManagerTest {
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `observeRingingCalls - will cancel the active ringing call if the call is cancelled`() = runTest {
val room = FakeMatrixRoom().apply {
val room = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo())
}
val client = FakeMatrixClient().apply {
@ -254,7 +254,7 @@ class DefaultActiveCallManagerTest {
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `observeRingingCalls - will do nothing if either the session or the room are not found`() = runTest {
val room = FakeMatrixRoom().apply {
val room = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo())
}
val client = FakeMatrixClient().apply {

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.widget.FakeCallWidgetSettingsProvider
import io.element.android.libraries.matrix.test.widget.FakeMatrixWidgetDriver
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
@ -41,7 +41,7 @@ class DefaultCallWidgetProviderTest {
@Test
fun `getWidget - fails if it can't generate the URL for the widget`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.failure(Exception("Can't generate URL for widget")) }
)
val client = FakeMatrixClient().apply {
@ -53,7 +53,7 @@ class DefaultCallWidgetProviderTest {
@Test
fun `getWidget - fails if it can't get the widget driver`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
getWidgetDriverResult = { Result.failure(Exception("Can't get a widget driver")) }
)
@ -66,7 +66,7 @@ class DefaultCallWidgetProviderTest {
@Test
fun `getWidget - returns a widget driver when all steps are successful`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
getWidgetDriverResult = { Result.success(FakeMatrixWidgetDriver()) },
)
@ -79,7 +79,7 @@ class DefaultCallWidgetProviderTest {
@Test
fun `getWidget - will use a custom base url if it exists`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
getWidgetDriverResult = { Result.success(FakeMatrixWidgetDriver()) },
)

View file

@ -66,7 +66,7 @@ private const val AN_URI_FROM_CAMERA_2 = "content://uri_from_camera_2"
private const val AN_URI_FROM_GALLERY = "content://uri_from_gallery"
@RunWith(RobolectricTestRunner::class)
class ConfigureRoomPresenterTest {
class ConfigureBaseRoomPresenterTest {
@get:Rule
val warmUpRule = WarmUpRule()

View file

@ -21,7 +21,7 @@ import io.element.android.tests.testutils.test
import kotlinx.coroutines.test.runTest
import org.junit.Test
class JoinRoomByAddressPresenterTest {
class JoinBaseRoomByAddressPresenterTest {
@Test
fun `present - initial state`() = runTest {
val presenter = createJoinRoomByAddressPresenter()

View file

@ -23,7 +23,7 @@ import org.junit.rules.TestRule
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class JoinRoomByAddressViewTest {
class JoinBaseRoomByAddressViewTest {
@get:Rule
val rule = createAndroidComposeRule<ComponentActivity>()

View file

@ -36,7 +36,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
class CreateRoomRootPresenterTest {
class CreateBaseRoomRootPresenterTest {
@get:Rule
val warmUpRule = WarmUpRule()

View file

@ -33,7 +33,7 @@ import org.junit.runner.RunWith
import org.robolectric.annotation.Config
@RunWith(AndroidJUnit4::class)
class CreateRoomRootViewTest {
class CreateBaseRoomRootViewTest {
@get:Rule
val rule = createAndroidComposeRule<ComponentActivity>()

View file

@ -121,7 +121,7 @@ class AcceptDeclineInvitePresenter @Inject constructor(
declinedAction: MutableState<AsyncAction<RoomId>>,
) = launch {
suspend {
client.getPendingRoom(inviteData.roomId)?.use {
client.getRoom(inviteData.roomId)?.use {
it.leave().getOrThrow()
}
if (blockUser) {

View file

@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeRoomPreview
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.join.FakeJoinRoom
import io.element.android.libraries.push.api.notifications.NotificationCleaner
import io.element.android.libraries.push.test.notifications.FakeNotificationCleaner
@ -88,11 +88,9 @@ class AcceptDeclineInvitePresenterTest {
val declineInviteFailure = lambdaRecorder { ->
Result.failure<Unit>(RuntimeException("Failed to leave room"))
}
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteFailure))
}
)
val client = FakeMatrixClient().apply {
givenGetRoomResult(A_ROOM_ID, FakeBaseRoom(leaveRoomLambda = declineInviteFailure))
}
val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID, A_ROOM_ID_2, A_ROOM_ID_3))
val presenter = createAcceptDeclineInvitePresenter(
client = client,
@ -138,11 +136,9 @@ class AcceptDeclineInvitePresenterTest {
val declineInviteSuccess = lambdaRecorder { ->
Result.success(Unit)
}
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteSuccess))
}
)
val client = FakeMatrixClient().apply {
givenGetRoomResult(A_ROOM_ID, FakeBaseRoom(leaveRoomLambda = declineInviteSuccess))
}
val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID, A_ROOM_ID_2, A_ROOM_ID_3))
val presenter = createAcceptDeclineInvitePresenter(
client = client,
@ -186,11 +182,10 @@ class AcceptDeclineInvitePresenterTest {
val declineInviteSuccess = lambdaRecorder { -> Result.success(Unit) }
val ignoreUserSuccess = lambdaRecorder { _: UserId -> Result.success(Unit) }
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteSuccess))
},
ignoreUserResult = ignoreUserSuccess
)
).apply {
givenGetRoomResult(A_ROOM_ID, FakeBaseRoom(leaveRoomLambda = declineInviteSuccess))
}
val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID, A_ROOM_ID_2, A_ROOM_ID_3))
val presenter = createAcceptDeclineInvitePresenter(
client = client,
@ -229,11 +224,9 @@ class AcceptDeclineInvitePresenterTest {
val declineInviteFailure = lambdaRecorder { ->
Result.failure<Unit>(RuntimeException("Failed to leave room"))
}
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteFailure))
}
)
val client = FakeMatrixClient().apply {
givenGetRoomResult(A_ROOM_ID, FakeBaseRoom(leaveRoomLambda = declineInviteFailure))
}
val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID, A_ROOM_ID_2, A_ROOM_ID_3))
val presenter = createAcceptDeclineInvitePresenter(
client = client,

View file

@ -44,7 +44,7 @@ import io.element.android.libraries.matrix.api.exception.ClientException
import io.element.android.libraries.matrix.api.exception.ErrorKind
import io.element.android.libraries.matrix.api.getRoomInfoFlow
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.matrix.api.room.isDm
@ -131,7 +131,7 @@ class JoinRoomPresenter @AssistedInject constructor(
val result = matrixClient.getRoomPreview(roomIdOrAlias, serverNames)
value = result.fold(
onSuccess = { preview ->
val membershipInfo = when (preview.info.membership) {
val membershipInfo = when (preview.previewInfo.membership) {
CurrentUserMembership.INVITED,
CurrentUserMembership.BANNED,
CurrentUserMembership.KNOCKED -> {
@ -139,7 +139,7 @@ class JoinRoomPresenter @AssistedInject constructor(
}
else -> null
}
preview.info.toContentState(
preview.previewInfo.toContentState(
senderMember = membershipInfo?.senderMember,
reason = membershipInfo?.currentUserMember?.membershipChangeReason,
)
@ -296,7 +296,7 @@ internal fun RoomDescription.toContentState(): ContentState {
}
@VisibleForTesting
internal fun MatrixRoomInfo.toContentState(membershipSender: RoomMember?, reason: String?): ContentState {
internal fun RoomInfo.toContentState(membershipSender: RoomMember?, reason: String?): ContentState {
return ContentState.Loaded(
roomId = id,
name = name,

View file

@ -21,8 +21,8 @@ interface CancelKnockRoom {
class DefaultCancelKnockRoom @Inject constructor(private val client: MatrixClient) : CancelKnockRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client
.getPendingRoom(roomId)
?.leave()
.getRoom(roomId)
?.use { it.leave() }
?: Result.failure(IllegalStateException("No pending room found"))
}
}

View file

@ -20,9 +20,7 @@ interface ForgetRoom {
@ContributesBinding(SessionScope::class)
class DefaultForgetRoom @Inject constructor(private val client: MatrixClient) : ForgetRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client
.getPendingRoom(roomId)
?.forget()
?: Result.failure(IllegalStateException("No pending room found"))
return client.getRoom(roomId)?.use { it.forget() }
?: Result.failure(IllegalStateException("Room not found"))
}
}

View file

@ -64,7 +64,7 @@ import org.junit.Test
import java.util.Optional
@Suppress("LargeClass")
class JoinRoomPresenterTest {
class JoinBaseRoomPresenterTest {
@get:Rule
val warmUpRule = WarmUpRule()
@ -273,7 +273,7 @@ class JoinRoomPresenterTest {
fun `present - when room is banned, then join authorization is equal to IsBanned`() = runTest {
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.BANNED, joinRule = JoinRule.Public)
val matrixClient = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(
info = aRoomPreviewInfo(
@ -546,7 +546,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(
info = aRoomPreviewInfo(
@ -591,7 +591,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as Private`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(joinRule = JoinRule.Private))
)
@ -611,7 +611,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as Custom`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(joinRule = JoinRule.Custom("custom")))
)
@ -631,7 +631,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as Invite`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(joinRule = JoinRule.Invite))
)
@ -651,7 +651,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as KnockRestricted`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(joinRule = JoinRule.KnockRestricted(emptyList())))
)
@ -671,7 +671,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as Restricted`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(joinRule = JoinRule.Restricted(emptyList())))
)
@ -691,7 +691,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded as Space`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.success(
aRoomPreview(info = aRoomPreviewInfo(isSpace = true))
)
@ -711,7 +711,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded with error`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.failure(AN_EXCEPTION)
}
)
@ -741,7 +741,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is not known RoomPreview is loaded with error Forbidden`() = runTest {
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
getNotJoinedRoomResult = { _, _ ->
Result.failure(ClientException.MatrixApi(ErrorKind.Forbidden, "403", "Forbidden", null))
}
)

View file

@ -25,7 +25,7 @@ import org.junit.rules.TestRule
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class JoinRoomViewTest {
class JoinBaseRoomViewTest {
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
@Test

View file

@ -7,7 +7,7 @@
package io.element.android.features.knockrequests.impl.data
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.powerlevels.canBan
import io.element.android.libraries.matrix.api.room.powerlevels.canInvite
import io.element.android.libraries.matrix.api.room.powerlevels.canKick
@ -22,7 +22,7 @@ data class KnockRequestPermissions(
val canHandle = canAccept || canDecline || canBan
}
fun MatrixRoom.knockRequestPermissionsFlow(): Flow<KnockRequestPermissions> {
fun JoinedRoom.knockRequestPermissionsFlow(): Flow<KnockRequestPermissions> {
return syncUpdateFlow.map {
val canAccept = canInvite().getOrDefault(false)
val canDecline = canKick().getOrDefault(false)

View file

@ -14,14 +14,14 @@ import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
@Module
@ContributesTo(RoomScope::class)
object KnockRequestsModule {
@Provides
@SingleIn(RoomScope::class)
fun knockRequestsService(room: MatrixRoom, featureFlagService: FeatureFlagService): KnockRequestsService {
fun knockRequestsService(room: JoinedRoom, featureFlagService: FeatureFlagService): KnockRequestsService {
return KnockRequestsService(
knockRequestsFlow = room.knockRequestsFlow,
permissionsFlow = room.knockRequestPermissionsFlow(),

View file

@ -16,7 +16,7 @@ import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.assert
@ -30,7 +30,7 @@ import org.junit.Rule
import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class)
class LeaveRoomPresenterTest {
class LeaveBaseRoomPresenterTest {
@get:Rule
val warmUpRule = WarmUpRule()
@ -53,7 +53,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom().apply {
result = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo(isDirect = false, isPublic = true, joinedMembersCount = 10))
}
)
@ -75,7 +75,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom().apply {
result = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo(isPublic = false))
},
)
@ -97,7 +97,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom().apply {
result = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo(joinedMembersCount = 1))
},
)
@ -119,7 +119,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom().apply {
result = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo(isDirect = true, activeMembersCount = 2))
},
)
@ -142,7 +142,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom(
result = FakeBaseRoom(
leaveRoomLambda = leaveRoomLambda
),
)
@ -167,7 +167,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom(
result = FakeBaseRoom(
leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
),
)
@ -191,7 +191,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom(
result = FakeBaseRoom(
leaveRoomLambda = { Result.success(Unit) }
),
)
@ -215,7 +215,7 @@ class LeaveRoomPresenterTest {
client = FakeMatrixClient().apply {
givenGetRoomResult(
roomId = A_ROOM_ID,
result = FakeMatrixRoom(
result = FakeBaseRoom(
leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
),
)

View file

@ -24,7 +24,7 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS
import io.element.android.features.messages.api.MessageComposerContext
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.launch
@ -32,7 +32,7 @@ import javax.inject.Inject
class SendLocationPresenter @Inject constructor(
permissionsPresenterFactory: PermissionsPresenter.Factory,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val analyticsService: AnalyticsService,
private val messageComposerContext: MessageComposerContext,
private val locationActions: LocationActions,

View file

@ -20,12 +20,12 @@ import io.element.android.features.location.impl.common.permissions.PermissionsE
import io.element.android.features.location.impl.common.permissions.PermissionsPresenter
import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.messages.test.FakeMessageComposerContext
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
@ -47,12 +47,12 @@ class SendLocationPresenterTest {
private val fakeBuildMeta = aBuildMeta(applicationName = "app name")
private fun createSendLocationPresenter(
matrixRoom: MatrixRoom = FakeMatrixRoom(),
joinedRoom: JoinedRoom = FakeJoinedRoom(),
): SendLocationPresenter = SendLocationPresenter(
permissionsPresenterFactory = object : PermissionsPresenter.Factory {
override fun create(permissions: List<String>): PermissionsPresenter = fakePermissionsPresenter
},
room = matrixRoom,
room = joinedRoom,
analyticsService = fakeAnalyticsService,
messageComposerContext = fakeMessageComposerContext,
locationActions = fakeLocationActions,
@ -265,10 +265,10 @@ class SendLocationPresenterTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
Result.success(Unit)
}
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
)
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
aPermissionsState(
permissions = PermissionsState.Permissions.AllGranted,
@ -326,10 +326,10 @@ class SendLocationPresenterTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
Result.success(Unit)
}
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
)
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
aPermissionsState(
permissions = PermissionsState.Permissions.NoneGranted,
@ -387,10 +387,10 @@ class SendLocationPresenterTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
Result.success(Unit)
}
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
)
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
aPermissionsState(
permissions = PermissionsState.Permissions.NoneGranted,

View file

@ -69,7 +69,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.alias.matches
import io.element.android.libraries.matrix.api.room.joinedRoomMembers
import io.element.android.libraries.matrix.api.timeline.Timeline
@ -101,7 +101,7 @@ class MessagesFlowNode @AssistedInject constructor(
private val mediaViewerEntryPoint: MediaViewerEntryPoint,
private val analyticsService: AnalyticsService,
private val locationService: LocationService,
private val room: MatrixRoom,
private val room: BaseRoom,
private val roomMemberProfilesCache: RoomMemberProfilesCache,
private val roomNamesCache: RoomNamesCache,
private val mentionSpanUpdater: MentionSpanUpdater,

View file

@ -53,7 +53,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.alias.matches
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.mediaplayer.api.MediaPlayer
@ -67,7 +67,7 @@ class MessagesNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val coroutineScope: CoroutineScope,
private val room: MatrixRoom,
private val room: BaseRoom,
private val analyticsService: AnalyticsService,
messageComposerPresenterFactory: MessageComposerPresenter.Factory,
timelinePresenterFactory: TimelinePresenter.Factory,

View file

@ -65,10 +65,10 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
@ -90,7 +90,7 @@ import timber.log.Timber
class MessagesPresenter @AssistedInject constructor(
@Assisted private val navigator: MessagesNavigator,
private val room: MatrixRoom,
private val room: JoinedRoom,
@Assisted private val composerPresenter: Presenter<MessageComposerState>,
private val voiceMessageComposerPresenter: Presenter<VoiceMessageComposerState>,
@Assisted private val timelinePresenter: Presenter<TimelineState>,
@ -279,7 +279,7 @@ class MessagesPresenter @AssistedInject constructor(
}
}
private fun MatrixRoomInfo.avatarData(): AvatarData {
private fun RoomInfo.avatarData(): AvatarData {
return AvatarData(
id = id.value,
name = name,
@ -288,7 +288,7 @@ class MessagesPresenter @AssistedInject constructor(
)
}
private fun MatrixRoomInfo.heroes(): List<AvatarData> {
private fun RoomInfo.heroes(): List<AvatarData> {
return heroes.map { user ->
user.getAvatarData(size = AvatarSize.TimelineRoom)
}
@ -382,8 +382,8 @@ class MessagesPresenter @AssistedInject constructor(
inviteProgress.value = AsyncData.Loading()
runCatching {
val memberList = when (val memberState = room.membersStateFlow.value) {
is MatrixRoomMembersState.Ready -> memberState.roomMembers
is MatrixRoomMembersState.Error -> memberState.prevRoomMembers.orEmpty()
is RoomMembersState.Ready -> memberState.roomMembers
is RoomMembersState.Error -> memberState.prevRoomMembers.orEmpty()
else -> emptyList()
}

View file

@ -43,7 +43,7 @@ import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -63,7 +63,7 @@ class DefaultActionListPresenter @AssistedInject constructor(
private val postProcessor: TimelineItemActionPostProcessor,
private val appPreferencesStore: AppPreferencesStore,
private val isPinnedMessagesFeatureEnabled: IsPinnedMessagesFeatureEnabled,
private val room: MatrixRoom,
private val room: BaseRoom,
private val userSendFailureFactory: VerifiedUserSendFailureFactory,
private val featureFlagService: FeatureFlagService,
private val dateFormatter: DateFormatter,

View file

@ -14,7 +14,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.ui.room.observeRoomMemberIdentityStateChange
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CoroutineScope
@ -23,7 +23,7 @@ import timber.log.Timber
import javax.inject.Inject
class IdentityChangeStatePresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val encryptionService: EncryptionService,
) : Presenter<IdentityChangeState> {
@Composable

View file

@ -7,12 +7,12 @@
package io.element.android.features.messages.impl.crypto.sendfailure
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import javax.inject.Inject
class VerifiedUserSendFailureFactory @Inject constructor(
private val room: MatrixRoom,
private val room: BaseRoom,
) {
suspend fun create(
sendState: LocalEventSendState?,

View file

@ -19,13 +19,13 @@ import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUser
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import kotlinx.coroutines.launch
import javax.inject.Inject
class ResolveVerifiedUserSendFailurePresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val verifiedUserSendFailureFactory: VerifiedUserSendFailureFactory,
) : Presenter<ResolveVerifiedUserSendFailureState> {
@Composable

View file

@ -10,7 +10,7 @@ package io.element.android.features.messages.impl.crypto.sendfailure.resolve
import androidx.compose.runtime.mutableStateOf
import io.element.android.libraries.matrix.api.core.SendHandle
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import timber.log.Timber
@ -21,7 +21,7 @@ import timber.log.Timber
* This way, the user can resolve and resend the message for each user concerned, one by one.
*/
class VerifiedUserSendFailureResolver(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val transactionId: TransactionId,
private val sendHandle: SendHandle,
private val iterator: VerifiedUserSendFailureIterator,

View file

@ -21,7 +21,7 @@ class MatrixComposerDraftStore @Inject constructor(
private val client: MatrixClient,
) : ComposerDraftStore {
override suspend fun loadDraft(roomId: RoomId): ComposerDraft? {
return client.getRoom(roomId)?.let { room ->
return client.getRoom(roomId)?.use { room ->
room.loadComposerDraft()
.onFailure {
Timber.e(it, "Failed to load composer draft for room $roomId")
@ -35,7 +35,7 @@ class MatrixComposerDraftStore @Inject constructor(
}
override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) {
client.getRoom(roomId)?.let { room ->
client.getRoom(roomId)?.use { room ->
val updateDraftResult = if (draft == null) {
room.clearComposerDraft()
} else {

View file

@ -49,7 +49,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.IntentionalMention
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType
import io.element.android.libraries.matrix.api.room.isDm
@ -98,7 +98,7 @@ import io.element.android.libraries.core.mimetype.MimeTypes.Any as AnyMimeTypes
class MessageComposerPresenter @AssistedInject constructor(
@Assisted private val navigator: MessagesNavigator,
private val appCoroutineScope: CoroutineScope,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val mediaPickerProvider: PickerProvider,
private val featureFlagService: FeatureFlagService,
private val sessionPreferencesStore: SessionPreferencesStore,

View file

@ -9,8 +9,8 @@ package io.element.android.features.messages.impl.messagecomposer.suggestions
import io.element.android.libraries.core.data.filterUpTo
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.textcomposer.mentions.ResolvedSuggestion
@ -33,7 +33,7 @@ class SuggestionsProcessor @Inject constructor() {
*/
suspend fun process(
suggestion: Suggestion?,
roomMembersState: MatrixRoomMembersState,
roomMembersState: RoomMembersState,
roomAliasSuggestions: List<RoomAliasSuggestion>,
currentUserId: UserId,
canSendRoomMention: suspend () -> Boolean,

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
@ -33,7 +33,7 @@ import javax.inject.Inject
@SingleIn(RoomScope::class)
class PinnedEventsTimelineProvider @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val syncService: SyncService,
private val featureFlagService: FeatureFlagService,
private val dispatchers: CoroutineDispatchers,
@ -62,6 +62,7 @@ class PinnedEventsTimelineProvider @Inject constructor(
}
}
.launchIn(scope)
.invokeOnCompletion { timelineStateFlow.value.dataOrNull()?.close() }
}
private suspend fun onActive() = coroutineScope {

View file

@ -20,7 +20,7 @@ import androidx.compose.runtime.setValue
import io.element.android.features.messages.impl.pinned.PinnedEventsTimelineProvider
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -32,7 +32,7 @@ import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
class PinnedMessagesBannerPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: BaseRoom,
private val itemFactory: PinnedMessagesBannerItemFactory,
private val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider,
) : Presenter<PinnedMessagesBannerState> {

View file

@ -38,7 +38,7 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
@ -60,7 +60,7 @@ import timber.log.Timber
class PinnedMessagesListPresenter @AssistedInject constructor(
@Assisted private val navigator: PinnedMessagesListNavigator,
private val room: MatrixRoom,
private val room: JoinedRoom,
timelineItemsFactoryCreator: TimelineItemsFactory.Creator,
private val timelineProvider: PinnedEventsTimelineProvider,
private val timelineProtectionPresenter: Presenter<TimelineProtectionState>,

View file

@ -25,13 +25,13 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatch
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
class ReportMessagePresenter @AssistedInject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
@Assisted private val inputs: Inputs,
private val snackbarDispatcher: SnackbarDispatcher,
) : Presenter<ReportMessageState> {

View file

@ -12,7 +12,7 @@ import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
@ -42,7 +42,7 @@ import javax.inject.Inject
@SingleIn(RoomScope::class)
@ContributesBinding(RoomScope::class, boundType = TimelineProvider::class)
class TimelineController @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
) : Closeable, TimelineProvider {
private val coroutineScope = CoroutineScope(SupervisorJob())

View file

@ -38,7 +38,7 @@ import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.roomMembers
@ -62,7 +62,7 @@ const val FOCUS_ON_PINNED_EVENT_DEBOUNCE_DURATION_IN_MILLIS = 200L
class TimelinePresenter @AssistedInject constructor(
timelineItemsFactoryCreator: TimelineItemsFactory.Creator,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val dispatchers: CoroutineDispatchers,
private val appScope: CoroutineScope,
@Assisted private val navigator: MessagesNavigator,

View file

@ -15,7 +15,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.api.user.MatrixUser
@ -24,7 +24,7 @@ import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
class ReactionSummaryPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: BaseRoom,
) : Presenter<ReactionSummaryState> {
@Composable
override fun present(): ReactionSummaryState {

View file

@ -13,19 +13,18 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MediaPreviewValue
import io.element.android.libraries.matrix.api.media.isPreviewEnabled
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.collections.immutable.toImmutableSet
import javax.inject.Inject
class TimelineProtectionPresenter @Inject constructor(
private val appPreferencesStore: AppPreferencesStore,
private val room: MatrixRoom,
private val room: BaseRoom,
) : Presenter<TimelineProtectionState> {
private val allowedEvents = mutableStateOf<Set<EventId>>(setOf())

View file

@ -18,7 +18,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
@ -32,7 +32,7 @@ import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
class TypingNotificationPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val sessionPreferencesStore: SessionPreferencesStore,
) : Presenter<TypingNotificationState> {
@Composable

View file

@ -51,9 +51,8 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
@ -70,7 +69,8 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.sync.FakeSyncService
@ -128,19 +128,21 @@ class MessagesPresenterTest {
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `present - check that the room's unread flag is removed`() = runTest {
val room = FakeMatrixRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
assertThat(room.markAsReadCalls).isEmpty()
val presenter = createMessagesPresenter(matrixRoom = room)
assertThat(room.baseRoom.markAsReadCalls).isEmpty()
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
runCurrent()
assertThat(room.setUnreadFlagCalls).isEqualTo(listOf(false))
assertThat(room.baseRoom.setUnreadFlagCalls).isEqualTo(listOf(false))
cancelAndIgnoreRemainingEvents()
}
}
@ -155,16 +157,18 @@ class MessagesPresenterTest {
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = timeline,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
val presenter = createMessagesPresenter(joinedRoom = room, coroutineDispatchers = coroutineDispatchers)
presenter.testWithLifecycleOwner {
skipItems(1)
val initialState = awaitItem()
@ -189,16 +193,18 @@ class MessagesPresenterTest {
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = timeline,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
val presenter = createMessagesPresenter(joinedRoom = room, coroutineDispatchers = coroutineDispatchers)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
@ -245,18 +251,20 @@ class MessagesPresenterTest {
fun `present - handle action copy link`() = runTest {
val clipboardHelper = FakeClipboardHelper()
val event = aMessageEvent()
val matrixRoom = FakeMatrixRoom(
eventPermalinkResult = { Result.success("a link") },
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
eventPermalinkResult = { Result.success("a link") },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(
clipboardHelper = clipboardHelper,
matrixRoom = matrixRoom,
joinedRoom = room,
)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
@ -466,20 +474,22 @@ class MessagesPresenterTest {
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
val liveTimeline = FakeTimeline()
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = liveTimeline,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val redactEventLambda = lambdaRecorder { _: EventOrTransactionId, _: String? -> Result.success(Unit) }
liveTimeline.redactEventLambda = redactEventLambda
val presenter = createMessagesPresenter(
matrixRoom = matrixRoom,
joinedRoom = joinedRoom,
coroutineDispatchers = coroutineDispatchers,
)
presenter.testWithLifecycleOwner {
@ -535,18 +545,19 @@ class MessagesPresenterTest {
@Test
fun `present - shows prompt to reinvite users in DM`() = runTest {
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 1, activeMembersCount = 1))
},
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 1, activeMembersCount = 1))
}
val presenter = createMessagesPresenter(matrixRoom = room)
)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
// Initially the composer doesn't have focus, so we don't show the alert
@ -567,18 +578,19 @@ class MessagesPresenterTest {
@Test
fun `present - doesn't show reinvite prompt in non-direct room`() = runTest {
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = false, joinedMembersCount = 1, activeMembersCount = 1))
},
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = false, joinedMembersCount = 1, activeMembersCount = 1))
}
val presenter = createMessagesPresenter(matrixRoom = room)
)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
assertThat(initialState.showReinvitePrompt).isFalse()
@ -592,18 +604,19 @@ class MessagesPresenterTest {
@Test
fun `present - doesn't show reinvite prompt if other party is present`() = runTest {
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 2, activeMembersCount = 2))
},
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 2, activeMembersCount = 2))
}
val presenter = createMessagesPresenter(matrixRoom = room)
)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = awaitItem()
assertThat(initialState.showReinvitePrompt).isFalse()
@ -618,25 +631,26 @@ class MessagesPresenterTest {
@Test
fun `present - handle reinviting other user when memberlist is ready`() = runTest {
val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) }
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
inviteUserResult = inviteUserResult,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
inviteUserResult = inviteUserResult,
)
room.givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
aRoomMember(userId = A_SESSION_ID_2, membership = RoomMembershipState.LEAVE),
)
)
)
val presenter = createMessagesPresenter(matrixRoom = room)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite))
@ -652,18 +666,19 @@ class MessagesPresenterTest {
@Test
fun `present - handle reinviting other user when memberlist is error`() = runTest {
val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) }
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
inviteUserResult = inviteUserResult,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
inviteUserResult = inviteUserResult,
)
room.givenRoomMembersState(
MatrixRoomMembersState.Error(
RoomMembersState.Error(
failure = Throwable(),
prevRoomMembers = persistentListOf(
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
@ -671,7 +686,7 @@ class MessagesPresenterTest {
)
)
)
val presenter = createMessagesPresenter(matrixRoom = room)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite))
@ -688,17 +703,18 @@ class MessagesPresenterTest {
@Test
fun `present - handle reinviting other user when memberlist is not ready`() = runTest {
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
room.givenRoomMembersState(MatrixRoomMembersState.Unknown)
val presenter = createMessagesPresenter(matrixRoom = room)
room.givenRoomMembersState(RoomMembersState.Unknown)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite))
@ -712,25 +728,26 @@ class MessagesPresenterTest {
@Test
fun `present - handle reinviting other user when inviting fails`() = runTest {
val room = FakeMatrixRoom(
sessionId = A_SESSION_ID,
inviteUserResult = { Result.failure(Throwable("Oops!")) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
inviteUserResult = { Result.failure(Throwable("Oops!")) },
)
room.givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
aRoomMember(userId = A_SESSION_ID_2, membership = RoomMembershipState.LEAVE),
)
)
)
val presenter = createMessagesPresenter(matrixRoom = room)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite))
@ -749,21 +766,23 @@ class MessagesPresenterTest {
@Test
fun `present - permission to post`() = runTest {
val matrixRoom = FakeMatrixRoom(
canUserSendMessageResult = { _, messageEventType ->
when (messageEventType) {
MessageEventType.ROOM_MESSAGE -> Result.success(true)
MessageEventType.REACTION -> Result.success(true)
else -> lambdaError()
}
},
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
canUserSendMessageResult = { _, messageEventType ->
when (messageEventType) {
MessageEventType.ROOM_MESSAGE -> Result.success(true)
MessageEventType.REACTION -> Result.success(true)
else -> lambdaError()
}
},
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
skipItems(1)
val state = awaitItem()
@ -773,21 +792,23 @@ class MessagesPresenterTest {
@Test
fun `present - no permission to post`() = runTest {
val matrixRoom = FakeMatrixRoom(
canUserSendMessageResult = { _, messageEventType ->
when (messageEventType) {
MessageEventType.ROOM_MESSAGE -> Result.success(false)
MessageEventType.REACTION -> Result.success(false)
else -> lambdaError()
}
},
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
canUserSendMessageResult = { _, messageEventType ->
when (messageEventType) {
MessageEventType.ROOM_MESSAGE -> Result.success(false)
MessageEventType.REACTION -> Result.success(false)
else -> lambdaError()
}
},
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner {
// Default value
assertThat(awaitItem().userEventPermissions.canSendMessage).isTrue()
@ -797,15 +818,17 @@ class MessagesPresenterTest {
@Test
fun `present - permission to redact own`() = runTest {
val matrixRoom = FakeMatrixRoom(
canRedactOwnResult = { Result.success(true) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOtherResult = { Result.success(false) },
canUserJoinCallResult = { Result.success(true) },
val joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOtherResult = { Result.success(false) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
)
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
val presenter = createMessagesPresenter(joinedRoom = joinedRoom)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilPredicate { it.userEventPermissions.canRedactOwn }.last()
assertThat(initialState.userEventPermissions.canRedactOwn).isTrue()
@ -816,15 +839,17 @@ class MessagesPresenterTest {
@Test
fun `present - permission to redact other`() = runTest {
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOtherResult = { Result.success(true) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(false) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
),
typingNoticeResult = { Result.success(Unit) },
)
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
val presenter = createMessagesPresenter(joinedRoom = joinedRoom)
presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilPredicate { it.userEventPermissions.canRedactOther }.last()
assertThat(initialState.userEventPermissions.canRedactOwn).isFalse()
@ -863,16 +888,18 @@ class MessagesPresenterTest {
val failurePinEventLambda = lambdaRecorder { _: EventId -> Result.failure<Boolean>(A_THROWABLE) }
val analyticsService = FakeAnalyticsService()
val timeline = FakeTimeline()
val room = FakeMatrixRoom(
liveTimeline = timeline,
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
)
val presenter = createMessagesPresenter(matrixRoom = room, analyticsService = analyticsService)
val presenter = createMessagesPresenter(joinedRoom = room, analyticsService = analyticsService)
presenter.testWithLifecycleOwner {
val messageEvent = aMessageEvent(
content = aTimelineItemTextContent()
@ -901,16 +928,18 @@ class MessagesPresenterTest {
val failureUnpinEventLambda = lambdaRecorder { _: EventId -> Result.failure<Boolean>(A_THROWABLE) }
val timeline = FakeTimeline()
val analyticsService = FakeAnalyticsService()
val room = FakeMatrixRoom(
liveTimeline = timeline,
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
)
val presenter = createMessagesPresenter(matrixRoom = room, analyticsService = analyticsService)
val presenter = createMessagesPresenter(joinedRoom = room, analyticsService = analyticsService)
presenter.testWithLifecycleOwner {
val messageEvent = aMessageEvent(
content = aTimelineItemTextContent()
@ -1058,17 +1087,19 @@ class MessagesPresenterTest {
val timeline = FakeTimeline().apply {
this.editCaptionLambda = editCaptionLambda
}
val room = FakeMatrixRoom(
liveTimeline = timeline,
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
),
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
)
val presenter = createMessagesPresenter(
matrixRoom = room,
joinedRoom = room,
)
presenter.testWithLifecycleOwner {
skipItems(1)
@ -1094,21 +1125,23 @@ class MessagesPresenterTest {
@Test
fun `present - when room is encrypted and a DM, the DM user's identity state is fetched onResume`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
sessionId = A_SESSION_ID,
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
initialRoomInfo = aRoomInfo(isDirect = true, isEncrypted = true)
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(aRoomMember(userId = A_SESSION_ID), aRoomMember(userId = A_USER_ID_2))))
}
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(aRoomMember(userId = A_SESSION_ID), aRoomMember(userId = A_USER_ID_2))))
},
typingNoticeResult = { Result.success(Unit) },
)
val encryptionService = FakeEncryptionService(getUserIdentityResult = { Result.success(IdentityState.Verified) })
val presenter = createMessagesPresenter(matrixRoom = room, encryptionService = encryptionService)
val presenter = createMessagesPresenter(joinedRoom = room, encryptionService = encryptionService)
val lifecycleOwner = FakeLifecycleOwner()
presenter.testWithLifecycleOwner(lifecycleOwner) {
val initialState = awaitItem()
@ -1124,16 +1157,19 @@ class MessagesPresenterTest {
private fun TestScope.createMessagesPresenter(
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
matrixRoom: MatrixRoom = FakeMatrixRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
joinedRoom: FakeJoinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserSendMessageResult = { _, _ -> Result.success(true) },
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(id = roomId, name = ""))
},
liveTimeline = FakeTimeline(),
typingNoticeResult = { Result.success(Unit) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(id = roomId, name = ""))
},
),
navigator: FakeMessagesNavigator = FakeMessagesNavigator(),
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(),
@ -1150,7 +1186,7 @@ class MessagesPresenterTest {
actionListEventSink: (ActionListEvents) -> Unit = {},
): MessagesPresenter {
return MessagesPresenter(
room = matrixRoom,
room = joinedRoom,
composerPresenter = messageComposerPresenter,
voiceMessageComposerPresenter = { aVoiceMessageComposerState() },
timelinePresenter = { aTimelineState(eventSink = timelineEventSink) },
@ -1171,7 +1207,7 @@ class MessagesPresenterTest {
buildMeta = aBuildMeta(),
dispatchers = coroutineDispatchers,
htmlConverterProvider = FakeHtmlConverterProvider(),
timelineController = TimelineController(matrixRoom),
timelineController = TimelineController(joinedRoom),
permalinkParser = permalinkParser,
encryptionService = encryptionService,
analyticsService = analyticsService,

View file

@ -29,13 +29,13 @@ import io.element.android.features.poll.api.pollcontent.aPollAnswerItemList
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_CAPTION
import io.element.android.libraries.matrix.test.A_MESSAGE
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
import io.element.android.tests.testutils.WarmUpRule
@ -893,7 +893,7 @@ class ActionListPresenterTest {
@Test
fun `present - compute message when event is already pinned`() = runTest {
val room = FakeMatrixRoom().apply {
val room = FakeBaseRoom().apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
val presenter = createActionListPresenter(
@ -1251,7 +1251,7 @@ class ActionListPresenterTest {
@Test
fun `present - compute for verified user send failure`() = runTest {
val room = FakeMatrixRoom(
val room = FakeBaseRoom(
userDisplayNameResult = { Result.success("Alice") }
)
val presenter = createActionListPresenter(isDeveloperModeEnabled = false, isPinFeatureEnabled = false, room = room)
@ -1279,7 +1279,7 @@ class ActionListPresenterTest {
private fun createActionListPresenter(
isDeveloperModeEnabled: Boolean,
isPinFeatureEnabled: Boolean,
room: MatrixRoom = FakeMatrixRoom(),
room: BaseRoom = FakeBaseRoom(),
allowCaption: Boolean = true,
): ActionListPresenter {
val preferencesStore = InMemoryAppPreferencesStore(isDeveloperModeEnabled = isDeveloperModeEnabled)

View file

@ -29,12 +29,12 @@ import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.api.media.ImageInfo
import io.element.android.libraries.matrix.api.media.VideoInfo
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
import io.element.android.libraries.matrix.test.A_CAPTION
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
@ -110,7 +110,7 @@ class AttachmentsPreviewPresenterTest {
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
progressCallbackValues = listOf(
Pair(0, 10),
Pair(5, 10),
@ -148,7 +148,7 @@ class AttachmentsPreviewPresenterTest {
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
)
val onDoneListener = lambdaRecorder<Unit> { }
@ -184,7 +184,7 @@ class AttachmentsPreviewPresenterTest {
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
)
val onDoneListener = lambdaRecorder<Unit> { }
@ -216,7 +216,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send media with pre-processing failure after user sends media`() = runTest {
val room = FakeMatrixRoom()
val room = FakeJoinedRoom()
val onDoneListener = lambdaRecorder<Unit> { }
val processLatch = CompletableDeferred<Unit>()
val presenter = createAttachmentsPreviewPresenter(
@ -242,7 +242,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send media with pre-processing failure before user sends media`() = runTest {
val room = FakeMatrixRoom()
val room = FakeJoinedRoom()
val onDoneListener = lambdaRecorder<Unit> { }
val processLatch = CompletableDeferred<Unit>()
val presenter = createAttachmentsPreviewPresenter(
@ -297,7 +297,7 @@ class AttachmentsPreviewPresenterTest {
val mediaPreProcessor = FakeMediaPreProcessor().apply {
givenImageResult()
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendImageResult = sendImageResult,
)
val onDoneListener = lambdaRecorder<Unit> { }
@ -339,7 +339,7 @@ class AttachmentsPreviewPresenterTest {
val mediaPreProcessor = FakeMediaPreProcessor().apply {
givenVideoResult()
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendVideoResult = sendVideoResult,
)
val onDoneListener = lambdaRecorder<Unit> { }
@ -381,7 +381,7 @@ class AttachmentsPreviewPresenterTest {
val mediaPreProcessor = FakeMediaPreProcessor().apply {
givenAudioResult()
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendAudioResult = sendAudioResult,
)
val onDoneListener = lambdaRecorder<Unit> { }
@ -418,7 +418,7 @@ class AttachmentsPreviewPresenterTest {
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.failure(failure)
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
)
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = false)
@ -448,7 +448,7 @@ class AttachmentsPreviewPresenterTest {
Result.failure(failure)
}
val onDoneListenerResult = lambdaRecorder<Unit> {}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
)
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = true, onDoneListener = onDoneListenerResult)
@ -518,7 +518,7 @@ class AttachmentsPreviewPresenterTest {
localMedia: LocalMedia = aLocalMedia(
uri = mockMediaUrl,
),
room: MatrixRoom = FakeMatrixRoom(),
room: JoinedRoom = FakeJoinedRoom(),
permalinkBuilder: PermalinkBuilder = FakePermalinkBuilder(),
mediaPreProcessor: MediaPreProcessor = FakeMediaPreProcessor(),
temporaryUriDeleter: TemporaryUriDeleter = FakeTemporaryUriDeleter(),

View file

@ -13,12 +13,12 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.tests.testutils.WarmUpRule
@ -26,6 +26,7 @@ import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -45,14 +46,15 @@ class IdentityChangeStatePresenterTest {
@Test
fun `present - when the room emits identity change, the presenter emits new state`() = runTest {
val room = FakeMatrixRoom().apply {
val identityStateChanges = MutableStateFlow(emptyList<IdentityStateChange>())
val room = FakeJoinedRoom(identityStateChangesFlow = identityStateChanges).apply {
givenRoomInfo(aRoomInfo(isEncrypted = true))
}
val presenter = createIdentityChangeStatePresenter(room)
presenter.test {
val initialState = awaitItem()
assertThat(initialState.roomMemberIdentityStateChanges).isEmpty()
room.emitIdentityStateChanges(
identityStateChanges.emit(
listOf(
IdentityStateChange(
userId = A_USER_ID_2,
@ -70,12 +72,16 @@ class IdentityChangeStatePresenterTest {
@Test
fun `present - when the clear room emits identity change, the presenter does not emit new state`() = runTest {
val room = FakeMatrixRoom(enableEncryptionResult = { Result.success(Unit) })
val identityStateChanges = MutableStateFlow(emptyList<IdentityStateChange>())
val room = FakeJoinedRoom(
identityStateChangesFlow = identityStateChanges,
enableEncryptionResult = { Result.success(Unit) }
)
val presenter = createIdentityChangeStatePresenter(room)
presenter.test {
val initialState = awaitItem()
assertThat(initialState.roomMemberIdentityStateChanges).isEmpty()
room.emitIdentityStateChanges(
identityStateChanges.emit(
listOf(
IdentityStateChange(
userId = A_USER_ID_2,
@ -100,9 +106,10 @@ class IdentityChangeStatePresenterTest {
@Test
fun `present - when the room emits identity change, the presenter emits new state with member details`() =
runTest {
val room = FakeMatrixRoom().apply {
val identityStateChanges = MutableStateFlow(emptyList<IdentityStateChange>())
val room = FakeJoinedRoom(identityStateChangesFlow = identityStateChanges).apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
listOf(
aRoomMember(
A_USER_ID_2,
@ -117,7 +124,7 @@ class IdentityChangeStatePresenterTest {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.roomMemberIdentityStateChanges).isEmpty()
room.emitIdentityStateChanges(
identityStateChanges.emit(
listOf(
IdentityStateChange(
userId = A_USER_ID_2,
@ -166,7 +173,7 @@ class IdentityChangeStatePresenterTest {
}
private fun createIdentityChangeStatePresenter(
room: MatrixRoom = FakeMatrixRoom(),
room: JoinedRoom = FakeJoinedRoom(),
encryptionService: EncryptionService = FakeEncryptionService(),
): IdentityChangeStatePresenter {
return IdentityChangeStatePresenter(

View file

@ -13,13 +13,13 @@ import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUser
import io.element.android.features.messages.impl.fixtures.aMessageEvent
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_TRANSACTION_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.coroutines.test.runTest
@ -81,11 +81,13 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user unsigned device failure dismiss scenario`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
)
)
val presenter = createResolveVerifiedUserSendFailurePresenter(room)
presenter.test {
val failedMessage = aVerifiedUserHasUnsignedDeviceFailedMessage()
@ -107,11 +109,13 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user unsigned device failure retry scenario`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
)
)
val presenter = createResolveVerifiedUserSendFailurePresenter(room)
presenter.test {
val failedMessage = aVerifiedUserHasUnsignedDeviceFailedMessage()
@ -138,10 +142,12 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user unsigned device failure resolve and resend scenario`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
),
ignoreDeviceTrustAndResendResult = { _, _ ->
Result.success(Unit)
},
@ -179,10 +185,12 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user unsigned device failure resolve and resend scenario with error`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
),
ignoreDeviceTrustAndResendResult = { _, _ ->
Result.failure(Exception())
},
@ -212,11 +220,13 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user changed identity failure retry scenario`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
)
)
val presenter = createResolveVerifiedUserSendFailurePresenter(room)
presenter.test {
val failedMessage = aVerifiedUserChangedIdentityMessage()
@ -243,10 +253,12 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user changed identity failure resolve and resend scenario`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
),
withdrawVerificationAndResendResult = { _, _ ->
Result.success(Unit)
},
@ -284,10 +296,12 @@ class ResolveVerifiedUserSendFailurePresenterTest {
@Test
fun `present - verified user changed identity failure resolve and resend scenario with error`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
userDisplayNameResult = { userId ->
Result.success(userId.value)
},
),
withdrawVerificationAndResendResult = { _, _ ->
Result.failure(Exception())
},
@ -337,7 +351,7 @@ class ResolveVerifiedUserSendFailurePresenterTest {
}
private fun createResolveVerifiedUserSendFailurePresenter(
room: MatrixRoom = FakeMatrixRoom(),
room: FakeJoinedRoom = FakeJoinedRoom(),
): ResolveVerifiedUserSendFailurePresenter {
return ResolveVerifiedUserSendFailurePresenter(
room = room,

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomSummary
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider
@ -49,8 +49,8 @@ class ForwardMessagesPresenterTest {
val timeline = FakeTimeline().apply {
this.forwardEventLambda = forwardEventLambda
}
val room = FakeMatrixRoom(liveTimeline = timeline)
val presenter = aForwardMessagesPresenter(fakeMatrixRoom = room)
val room = FakeJoinedRoom(liveTimeline = timeline)
val presenter = aForwardMessagesPresenter(fakeRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -73,8 +73,8 @@ class ForwardMessagesPresenterTest {
val timeline = FakeTimeline().apply {
this.forwardEventLambda = forwardEventLambda
}
val room = FakeMatrixRoom(liveTimeline = timeline)
val presenter = aForwardMessagesPresenter(fakeMatrixRoom = room)
val room = FakeJoinedRoom(liveTimeline = timeline)
val presenter = aForwardMessagesPresenter(fakeRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -93,11 +93,11 @@ class ForwardMessagesPresenterTest {
private fun CoroutineScope.aForwardMessagesPresenter(
eventId: EventId = AN_EVENT_ID,
fakeMatrixRoom: FakeMatrixRoom = FakeMatrixRoom(),
fakeRoom: FakeJoinedRoom = FakeJoinedRoom(),
coroutineScope: CoroutineScope = this,
) = ForwardMessagesPresenter(
eventId = eventId.value,
timelineProvider = LiveTimelineProvider(fakeMatrixRoom),
timelineProvider = LiveTimelineProvider(fakeRoom),
appCoroutineScope = coroutineScope,
)
}

View file

@ -42,8 +42,8 @@ import io.element.android.libraries.matrix.api.media.VideoInfo
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.IntentionalMention
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType
@ -65,7 +65,8 @@ import io.element.android.libraries.matrix.test.A_USER_ID_3
import io.element.android.libraries.matrix.test.A_USER_ID_4
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
@ -267,13 +268,13 @@ class MessageComposerPresenterTest {
val timeline = FakeTimeline().apply {
this.editCaptionLambda = editCaptionLambda
}
val fakeMatrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(
coroutineScope = this,
room = fakeMatrixRoom,
room = joinedRoom,
isRichTextEditorEnabled = false,
)
val permalinkBuilder = FakePermalinkBuilder(permalinkForUserLambda = { Result.success("") })
@ -382,7 +383,7 @@ class MessageComposerPresenterTest {
fun `present - send message with rich text enabled`() = runTest {
val presenter = createPresenter(
coroutineScope = this,
room = FakeMatrixRoom(
room = FakeJoinedRoom(
sendMessageResult = { _, _, _ -> Result.success(Unit) },
typingNoticeResult = { Result.success(Unit) }
),
@ -416,7 +417,7 @@ class MessageComposerPresenterTest {
val presenter = createPresenter(
coroutineScope = this,
isRichTextEditorEnabled = false,
room = FakeMatrixRoom(
room = FakeJoinedRoom(
sendMessageResult = { _, _, _ -> Result.success(Unit) },
typingNoticeResult = { Result.success(Unit) }
),
@ -454,13 +455,13 @@ class MessageComposerPresenterTest {
val timeline = FakeTimeline().apply {
this.editMessageLambda = editMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(
this,
fakeMatrixRoom,
joinedRoom,
)
moleculeFlow(RecompositionMode.Immediate) {
val state = presenter.present()
@ -509,14 +510,14 @@ class MessageComposerPresenterTest {
val roomEditMessageLambda = lambdaRecorder { _: EventId?, _: String, _: String?, _: List<IntentionalMention> ->
Result.success(Unit)
}
val fakeMatrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
editMessageLambda = roomEditMessageLambda,
)
val presenter = createPresenter(
this,
fakeMatrixRoom,
joinedRoom,
)
moleculeFlow(RecompositionMode.Immediate) {
val state = presenter.present()
@ -566,13 +567,13 @@ class MessageComposerPresenterTest {
val timeline = FakeTimeline().apply {
this.editMessageLambda = editMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
)
val presenter = createPresenter(
this,
fakeMatrixRoom,
joinedRoom,
)
moleculeFlow(RecompositionMode.Immediate) {
val state = presenter.present()
@ -618,13 +619,13 @@ class MessageComposerPresenterTest {
val timeline = FakeTimeline().apply {
this.replyMessageLambda = replyMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(
this,
fakeMatrixRoom,
joinedRoom,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -689,7 +690,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Pick image from gallery`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
@ -730,7 +731,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Pick video from gallery`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
@ -788,7 +789,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Pick file from storage will open the preview`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
@ -811,7 +812,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - create poll`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(this, room = room)
@ -830,7 +831,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - share location`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(this, room = room)
@ -849,7 +850,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Take photo`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
@ -874,7 +875,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Take photo with permission request`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val permissionPresenter = FakePermissionsPresenter()
@ -901,7 +902,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Record video`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
@ -926,7 +927,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - Record video with permission request`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
)
val permissionPresenter = FakePermissionsPresenter()
@ -1001,12 +1002,12 @@ class MessageComposerPresenterTest {
val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN)
val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN)
var canUserTriggerRoomNotificationResult = true
val room = FakeMatrixRoom(
canUserTriggerRoomNotificationResult = { Result.success(canUserTriggerRoomNotificationResult) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(canUserTriggerRoomNotificationResult) }),
typingNoticeResult = { Result.success(Unit) }
).apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(currentUser, invitedUser, bob, david),
)
)
@ -1057,12 +1058,12 @@ class MessageComposerPresenterTest {
val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE)
val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN)
val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN)
val room = FakeMatrixRoom(
canUserTriggerRoomNotificationResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(true) }),
typingNoticeResult = { Result.success(Unit) }
).apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(currentUser, invitedUser, bob, david),
)
)
@ -1124,7 +1125,7 @@ class MessageComposerPresenterTest {
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<IntentionalMention> ->
Result.success(Unit)
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = timeline,
sendMessageResult = sendMessageResult,
typingNoticeResult = { Result.success(Unit) }
@ -1206,8 +1207,8 @@ class MessageComposerPresenterTest {
@Test
fun `present - handle typing notice event`() = runTest {
val typingNoticeResult = lambdaRecorder<Boolean, Result<Unit>> { Result.success(Unit) }
val room = FakeMatrixRoom(
typingNoticeResult = typingNoticeResult
val room = FakeJoinedRoom(
typingNoticeResult = typingNoticeResult,
)
val presenter = createPresenter(room = room, coroutineScope = this)
moleculeFlow(RecompositionMode.Immediate) {
@ -1217,6 +1218,7 @@ class MessageComposerPresenterTest {
typingNoticeResult.assertions().isNeverCalled()
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true))
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false))
advanceUntilIdle()
typingNoticeResult.assertions().isCalledExactly(2)
.withSequence(
listOf(value(true)),
@ -1228,7 +1230,7 @@ class MessageComposerPresenterTest {
@Test
fun `present - handle typing notice event when sending typing notice is disabled`() = runTest {
val typingNoticeResult = lambdaRecorder<Boolean, Result<Unit>> { Result.success(Unit) }
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
typingNoticeResult = typingNoticeResult
)
val store = InMemorySessionPreferencesStore(
@ -1383,7 +1385,7 @@ class MessageComposerPresenterTest {
val timeline = FakeTimeline().apply {
this.loadReplyDetailsLambda = loadReplyDetailsLambda
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = timeline,
typingNoticeResult = { Result.success(Unit) },
)
@ -1524,7 +1526,7 @@ class MessageComposerPresenterTest {
private fun createPresenter(
coroutineScope: CoroutineScope,
room: MatrixRoom = FakeMatrixRoom(
room: JoinedRoom = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) }
),
navigator: MessagesNavigator = FakeMessagesNavigator(),

View file

@ -9,7 +9,7 @@ package io.element.android.features.messages.impl.messagecomposer.suggestions
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.test.A_ROOM_ALIAS
import io.element.android.libraries.matrix.test.A_USER_ID
@ -35,7 +35,7 @@ class SuggestionsProcessorTest {
fun `processing null suggestion will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = null,
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember())),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember())),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -47,7 +47,7 @@ class SuggestionsProcessorTest {
fun `processing Command will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = aCommandSuggestion,
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember())),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember())),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -59,7 +59,7 @@ class SuggestionsProcessorTest {
fun `processing Custom will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = aCustomSuggestion,
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember())),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember())),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -71,7 +71,7 @@ class SuggestionsProcessorTest {
fun `processing Mention suggestion with not loaded members will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion(""),
roomMembersState = MatrixRoomMembersState.Unknown,
roomMembersState = RoomMembersState.Unknown,
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -83,7 +83,7 @@ class SuggestionsProcessorTest {
fun `processing Mention suggestion with no members will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion(""),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -95,7 +95,7 @@ class SuggestionsProcessorTest {
fun `processing Room suggestion with no aliases will return empty suggestion`() = runTest {
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion(""),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID,
canSendRoomMention = { true },
@ -108,7 +108,7 @@ class SuggestionsProcessorTest {
val aRoomSummary = aRoomSummary(canonicalAlias = A_ROOM_ALIAS)
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion("ALI"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = listOf(
RoomAliasSuggestion(
roomAlias = A_ROOM_ALIAS,
@ -137,7 +137,7 @@ class SuggestionsProcessorTest {
val aRoomSummary = aRoomSummary(canonicalAlias = A_ROOM_ALIAS)
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion("ali"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = listOf(
RoomAliasSuggestion(
roomAlias = A_ROOM_ALIAS,
@ -166,7 +166,7 @@ class SuggestionsProcessorTest {
val aRoomSummary = aRoomSummary(canonicalAlias = A_ROOM_ALIAS)
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion("tot"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = listOf(
RoomAliasSuggestion(
roomAlias = A_ROOM_ALIAS,
@ -186,7 +186,7 @@ class SuggestionsProcessorTest {
val aRoomSummary = aRoomSummary(canonicalAlias = A_ROOM_ALIAS)
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion("lement"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = listOf(
RoomAliasSuggestion(
roomAlias = A_ROOM_ALIAS,
@ -215,7 +215,7 @@ class SuggestionsProcessorTest {
val aRoomSummary = aRoomSummary(canonicalAlias = A_ROOM_ALIAS)
val result = suggestionsProcessor.process(
suggestion = aRoomSuggestion("lement"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf()),
roomMembersState = RoomMembersState.Ready(persistentListOf()),
roomAliasSuggestions = listOf(
RoomAliasSuggestion(
roomAlias = A_ROOM_ALIAS,
@ -235,7 +235,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = null)
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("ali"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { true },
@ -252,7 +252,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = null)
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("ali"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = UserId("@alice:server.org"),
canSendRoomMention = { true },
@ -265,7 +265,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "alice")
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("bo"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { true },
@ -278,7 +278,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), membership = RoomMembershipState.INVITE)
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("ali"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { true },
@ -291,7 +291,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "bob")
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("bo"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { true },
@ -308,7 +308,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "ro")
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("ro"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { true },
@ -326,7 +326,7 @@ class SuggestionsProcessorTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "ro")
val result = suggestionsProcessor.process(
suggestion = aMentionSuggestion("ro"),
roomMembersState = MatrixRoomMembersState.Ready(persistentListOf(aRoomMember)),
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
roomAliasSuggestions = emptyList(),
currentUserId = A_USER_ID_2,
canSendRoomMention = { false },

View file

@ -12,14 +12,14 @@ import io.element.android.features.messages.impl.pinned.PinnedEventsTimelineProv
import io.element.android.libraries.eventformatter.test.FakePinnedMessagesBannerFormatter
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
import io.element.android.libraries.matrix.test.A_UNIQUE_ID_2
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
@ -54,7 +54,7 @@ class PinnedMessagesBannerPresenterTest {
@Test
fun `present - loading state`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
createTimelineResult = { Result.success(FakeTimeline()) }
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
@ -85,7 +85,7 @@ class PinnedMessagesBannerPresenterTest {
)
)
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) }
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID, AN_EVENT_ID_2)))
@ -124,7 +124,7 @@ class PinnedMessagesBannerPresenterTest {
)
)
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) }
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID, AN_EVENT_ID_2)))
@ -159,7 +159,7 @@ class PinnedMessagesBannerPresenterTest {
@Test
fun `present - timeline failed`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
createTimelineResult = { Result.failure(Exception()) }
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
@ -179,7 +179,7 @@ class PinnedMessagesBannerPresenterTest {
}
private fun TestScope.createPinnedMessagesBannerPresenter(
room: MatrixRoom = FakeMatrixRoom(),
room: JoinedRoom = FakeJoinedRoom(),
itemFactory: PinnedMessagesBannerItemFactory = PinnedMessagesBannerItemFactory(
coroutineDispatchers = testCoroutineDispatchers(),
formatter = FakePinnedMessagesBannerFormatter(

View file

@ -20,14 +20,15 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatch
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
@ -51,11 +52,13 @@ import org.junit.Test
class PinnedMessagesListPresenterTest {
@Test
fun `present - initial state feature disabled`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
)
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = false)
presenter.test {
val initialState = awaitItem()
@ -66,13 +69,15 @@ class PinnedMessagesListPresenterTest {
@Test
fun `present - initial state feature enabled`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = true)
presenter.test {
val initialState = awaitItem()
@ -83,14 +88,16 @@ class PinnedMessagesListPresenterTest {
@Test
fun `present - timeline failure state`() = runTest {
val room = FakeMatrixRoom(
createTimelineResult = { Result.failure(RuntimeException()) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.failure(RuntimeException()) },
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -102,14 +109,16 @@ class PinnedMessagesListPresenterTest {
@Test
fun `present - empty state`() = runTest {
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(FakeTimeline()) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf()))
}
},
createTimelineResult = { Result.success(FakeTimeline()) },
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -122,14 +131,16 @@ class PinnedMessagesListPresenterTest {
@Test
fun `present - filled state`() = runTest {
val pinnedEventsTimeline = createPinnedMessagesTimeline()
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.success(pinnedEventsTimeline) },
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -149,14 +160,16 @@ class PinnedMessagesListPresenterTest {
val failureUnpinEventLambda = lambdaRecorder { _: EventId? -> Result.failure<Boolean>(A_THROWABLE) }
val pinnedEventsTimeline = createPinnedMessagesTimeline()
val analyticsService = FakeAnalyticsService()
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.success(pinnedEventsTimeline) },
)
val presenter = createPinnedMessagesListPresenter(room = room, isFeatureEnabled = true, analyticsService = analyticsService)
presenter.test {
skipItems(3)
@ -195,14 +208,16 @@ class PinnedMessagesListPresenterTest {
this.onViewInTimelineClickLambda = onViewInTimelineClickLambda
}
val pinnedEventsTimeline = createPinnedMessagesTimeline()
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.success(pinnedEventsTimeline) },
)
val presenter = createPinnedMessagesListPresenter(room = room, navigator = navigator, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -224,14 +239,16 @@ class PinnedMessagesListPresenterTest {
this.onShowEventDebugInfoClickLambda = onShowEventDebugInfoClickLambda
}
val pinnedEventsTimeline = createPinnedMessagesTimeline()
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.success(pinnedEventsTimeline) },
)
val presenter = createPinnedMessagesListPresenter(room = room, navigator = navigator, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -253,14 +270,16 @@ class PinnedMessagesListPresenterTest {
this.onForwardEventClickLambda = onForwardEventClickLambda
}
val pinnedEventsTimeline = createPinnedMessagesTimeline()
val room = FakeMatrixRoom(
createTimelineResult = { Result.success(pinnedEventsTimeline) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
canRedactOtherResult = { Result.success(true) },
canUserPinUnpinResult = { Result.success(true) },
).apply {
givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID)))
}
},
createTimelineResult = { Result.success(pinnedEventsTimeline) },
)
val presenter = createPinnedMessagesListPresenter(room = room, navigator = navigator, isFeatureEnabled = true)
presenter.test {
skipItems(3)
@ -294,7 +313,7 @@ class PinnedMessagesListPresenterTest {
private fun TestScope.createPinnedMessagesListPresenter(
navigator: PinnedMessagesListNavigator = FakePinnedMessagesListNavigator(),
room: MatrixRoom = FakeMatrixRoom(),
room: JoinedRoom = FakeJoinedRoom(),
syncService: SyncService = FakeSyncService(),
isFeatureEnabled: Boolean = true,
analyticsService: AnalyticsService = FakeAnalyticsService(),

View file

@ -15,10 +15,10 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder
import kotlinx.coroutines.test.runTest
@ -78,10 +78,10 @@ class ReportMessagePresenterTest {
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
Result.success(Unit)
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(matrixRoom = room)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -100,10 +100,10 @@ class ReportMessagePresenterTest {
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
Result.success(Unit)
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(matrixRoom = room)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -120,10 +120,10 @@ class ReportMessagePresenterTest {
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
Result.failure(Exception("Failed to report content"))
}
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
reportContentResult = reportContentResult
)
val presenter = createReportMessagePresenter(matrixRoom = room)
val presenter = createReportMessagePresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -141,11 +141,11 @@ class ReportMessagePresenterTest {
private fun createReportMessagePresenter(
inputs: ReportMessagePresenter.Inputs = ReportMessagePresenter.Inputs(AN_EVENT_ID, A_USER_ID),
matrixRoom: MatrixRoom = FakeMatrixRoom(),
joinedRoom: JoinedRoom = FakeJoinedRoom(),
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
) = ReportMessagePresenter(
inputs = inputs,
room = matrixRoom,
room = joinedRoom,
snackbarDispatcher = snackbarDispatcher,
)
}

View file

@ -14,7 +14,7 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
import io.element.android.tests.testutils.lambda.lambdaError
@ -29,11 +29,11 @@ class TimelineControllerTest {
fun `test switching between live and detached timeline`() = runTest {
val liveTimeline = FakeTimeline(name = "live")
val detachedTimeline = FakeTimeline(name = "detached")
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = { Result.success(detachedTimeline) }
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
awaitItem().also { state ->
@ -61,7 +61,7 @@ class TimelineControllerTest {
val detachedTimeline1 = FakeTimeline(name = "detached 1")
val detachedTimeline2 = FakeTimeline(name = "detached 2")
var callNumber = 0
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = {
callNumber++
@ -72,7 +72,7 @@ class TimelineControllerTest {
}
}
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
awaitItem().also { state ->
@ -97,10 +97,10 @@ class TimelineControllerTest {
@Test
fun `test switching to live when already in live should have no effect`() = runTest {
val liveTimeline = FakeTimeline(name = "live")
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
awaitItem().also { state ->
assertThat(state).isEqualTo(liveTimeline)
@ -115,11 +115,11 @@ class TimelineControllerTest {
fun `test closing the TimelineController should close the detached timeline`() = runTest {
val liveTimeline = FakeTimeline(name = "live")
val detachedTimeline = FakeTimeline(name = "detached")
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = { Result.success(detachedTimeline) }
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
awaitItem().also { state ->
assertThat(state).isEqualTo(liveTimeline)
@ -144,10 +144,10 @@ class TimelineControllerTest {
)
)
)
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
assertThat(sut.timelineItems().first()).hasSize(1)
}
@ -165,11 +165,11 @@ class TimelineControllerTest {
val detachedTimeline = FakeTimeline(name = "detached").apply {
sendMessageLambda = lambdaForDetached
}
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = { Result.success(detachedTimeline) }
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
sut.focusOnEvent(AN_EVENT_ID)
awaitItem().also { state ->
@ -190,11 +190,11 @@ class TimelineControllerTest {
fun `test last forward pagination on a detached timeline should switch to live timeline`() = runTest {
val liveTimeline = FakeTimeline(name = "live")
val detachedTimeline = FakeTimeline(name = "detached")
val matrixRoom = FakeMatrixRoom(
val joinedRoom = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = { Result.success(detachedTimeline) }
)
val sut = TimelineController(matrixRoom)
val sut = TimelineController(joinedRoom)
sut.activeTimelineFlow().test {
awaitItem().also { state ->

View file

@ -30,7 +30,7 @@ import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
import io.element.android.features.roomcall.api.aStandByCallState
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.api.timeline.Timeline
@ -43,7 +43,8 @@ import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
import io.element.android.libraries.matrix.test.A_UNIQUE_ID_2
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.aMessageContent
@ -128,9 +129,9 @@ import kotlin.time.Duration.Companion.seconds
)
)
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = timeline,
canUserSendMessageResult = { _, _ -> Result.success(true) },
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) })
)
val sessionPreferencesStore = InMemorySessionPreferencesStore(isSendPublicReadReceiptsEnabled = false)
val presenter = createTimelinePresenter(
@ -144,7 +145,7 @@ import kotlin.time.Duration.Companion.seconds
val initialState = awaitFirstItem()
initialState.eventSink.invoke(TimelineEvents.OnScrollFinished(0))
runCurrent()
assertThat(room.markAsReadCalls).isNotEmpty()
assertThat(room.baseRoom.markAsReadCalls).isNotEmpty()
cancelAndIgnoreRemainingEvents()
}
}
@ -481,10 +482,10 @@ import kotlin.time.Duration.Companion.seconds
val liveTimeline = FakeTimeline(
timelineItems = flowOf(emptyList())
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = liveTimeline,
createTimelineResult = { Result.success(detachedTimeline) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }),
)
val presenter = createTimelinePresenter(
room = room,
@ -523,7 +524,7 @@ import kotlin.time.Duration.Companion.seconds
process(listOf(aMessageEvent(eventId = AN_EVENT_ID)))
}
val presenter = createTimelinePresenter(
room = FakeMatrixRoom(
room = FakeJoinedRoom(
liveTimeline = FakeTimeline(
timelineItems = flowOf(
listOf(
@ -534,7 +535,7 @@ import kotlin.time.Duration.Companion.seconds
)
)
),
canUserSendMessageResult = { _, _ -> Result.success(true) },
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }),
),
timelineItemIndexer = timelineItemIndexer,
)
@ -557,12 +558,12 @@ import kotlin.time.Duration.Companion.seconds
@Test
fun `present - focus on event error case`() = runTest {
val presenter = createTimelinePresenter(
room = FakeMatrixRoom(
room = FakeJoinedRoom(
liveTimeline = FakeTimeline(
timelineItems = flowOf(emptyList()),
),
createTimelineResult = { Result.failure(Throwable("An error")) },
canUserSendMessageResult = { _, _ -> Result.success(true) },
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }),
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -628,11 +629,11 @@ import kotlin.time.Duration.Companion.seconds
)
)
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = timeline,
canUserSendMessageResult = { _, _ -> Result.success(true) },
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }),
).apply {
givenRoomMembersState(MatrixRoomMembersState.Unknown)
givenRoomMembersState(RoomMembersState.Unknown)
}
val avatarUrl = "https://domain.com/avatar.jpg"
@ -647,7 +648,7 @@ import kotlin.time.Duration.Companion.seconds
assertThat(event.readReceiptState.receipts.first().avatarData.url).isNull()
room.givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(aRoomMember(userId = A_USER_ID, avatarUrl = avatarUrl))
)
)
@ -663,9 +664,9 @@ import kotlin.time.Duration.Companion.seconds
private fun TestScope.createTimelinePresenter(
timeline: Timeline = FakeTimeline(),
room: FakeMatrixRoom = FakeMatrixRoom(
room: FakeJoinedRoom = FakeJoinedRoom(
liveTimeline = timeline,
canUserSendMessageResult = { _, _ -> Result.success(true) }
baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }),
),
redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(),
messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(),

View file

@ -12,12 +12,12 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.timeline.model.anAggregatedReaction
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.tests.testutils.WarmUpRule
import kotlinx.collections.immutable.persistentListOf
@ -32,8 +32,8 @@ class ReactionSummaryPresenterTest {
private val aggregatedReaction = anAggregatedReaction(userId = A_USER_ID, key = "👍", isHighlighted = true)
private val roomMember = aRoomMember(userId = A_USER_ID, avatarUrl = AN_AVATAR_URL, displayName = A_USER_NAME)
private val summaryEvent = ReactionSummaryEvents.ShowReactionSummary(AN_EVENT_ID, listOf(aggregatedReaction), aggregatedReaction.key)
private val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
private val room = FakeBaseRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(roomMember)))
}
private val presenter = ReactionSummaryPresenter(room)

View file

@ -9,10 +9,10 @@ package io.element.android.features.messages.impl.timeline.protection
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.media.MediaPreviewValue
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
@ -55,7 +55,7 @@ class TimelineProtectionPresenterTest {
@Test
fun `present - media preview value private in public room`() = runTest {
val appPreferencesStore = InMemoryAppPreferencesStore(timelineMediaPreviewValue = MediaPreviewValue.Private)
val room = FakeMatrixRoom(initialRoomInfo = aRoomInfo(joinRule = JoinRule.Public))
val room = FakeBaseRoom(initialRoomInfo = aRoomInfo(joinRule = JoinRule.Public))
val presenter = createPresenter(appPreferencesStore, room)
presenter.test {
skipItems(1)
@ -72,7 +72,7 @@ class TimelineProtectionPresenterTest {
@Test
fun `present - media preview value private in non public room`() = runTest {
val appPreferencesStore = InMemoryAppPreferencesStore(timelineMediaPreviewValue = MediaPreviewValue.Private)
val room = FakeMatrixRoom(initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite))
val room = FakeBaseRoom(initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite))
val presenter = createPresenter(appPreferencesStore, room)
presenter.test {
val initialState = awaitItem()
@ -85,7 +85,7 @@ class TimelineProtectionPresenterTest {
private fun createPresenter(
appPreferencesStore: AppPreferencesStore = InMemoryAppPreferencesStore(),
room: MatrixRoom = FakeMatrixRoom(),
room: BaseRoom = FakeBaseRoom(),
) = TimelineProtectionPresenter(
appPreferencesStore = appPreferencesStore,
room = room,

View file

@ -13,19 +13,20 @@ import app.cash.turbine.Event
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.A_USER_ID_3
import io.element.android.libraries.matrix.test.A_USER_ID_4
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
import io.element.android.tests.testutils.WarmUpRule
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -50,12 +51,13 @@ class TypingNotificationPresenterTest {
@Test
fun `present - typing notification disabled`() = runTest {
val room = FakeMatrixRoom()
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val sessionPreferencesStore = InMemorySessionPreferencesStore(
isRenderTypingNotificationsEnabled = false
isRenderTypingNotificationsEnabled = false,
)
val presenter = createPresenter(
matrixRoom = room,
joinedRoom = room,
sessionPreferencesStore = sessionPreferencesStore,
)
moleculeFlow(RecompositionMode.Immediate) {
@ -65,7 +67,7 @@ class TypingNotificationPresenterTest {
val initialState = awaitItem()
assertThat(initialState.renderTypingNotifications).isFalse()
assertThat(initialState.typingMembers).isEmpty()
room.givenRoomTypingMembers(listOf(A_USER_ID_2))
typingMembersFlow.emit(listOf(A_USER_ID_2))
expectNoEvents()
// Preferences changes
sessionPreferencesStore.setRenderTypingNotifications(true)
@ -89,14 +91,15 @@ class TypingNotificationPresenterTest {
@Test
fun `present - state is updated when a member is typing, member is not known`() = runTest {
val room = FakeMatrixRoom()
val presenter = createPresenter(matrixRoom = room)
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
room.givenRoomTypingMembers(listOf(A_USER_ID_2))
typingMembersFlow.emit(listOf(A_USER_ID_2))
val oneMemberTypingState = awaitItem()
assertThat(oneMemberTypingState.typingMembers.size).isEqualTo(1)
assertThat(oneMemberTypingState.typingMembers.first()).isEqualTo(
@ -105,7 +108,7 @@ class TypingNotificationPresenterTest {
)
)
// User stops typing
room.givenRoomTypingMembers(emptyList())
typingMembersFlow.emit(emptyList())
skipItems(1)
val finalState = awaitItem()
assertThat(finalState.typingMembers).isEmpty()
@ -115,9 +118,10 @@ class TypingNotificationPresenterTest {
@Test
fun `present - state is updated when a member is typing, member is known`() = runTest {
val aKnownRoomMember = createKnownRoomMember(userId = A_USER_ID_2)
val room = FakeMatrixRoom().apply {
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow).apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
listOf(
createKnownRoomMember(A_USER_ID),
aKnownRoomMember,
@ -127,13 +131,13 @@ class TypingNotificationPresenterTest {
)
)
}
val presenter = createPresenter(matrixRoom = room)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
room.givenRoomTypingMembers(listOf(A_USER_ID_2))
typingMembersFlow.emit(listOf(A_USER_ID_2))
val oneMemberTypingState = awaitItem()
assertThat(oneMemberTypingState.typingMembers.size).isEqualTo(1)
assertThat(oneMemberTypingState.typingMembers.first()).isEqualTo(
@ -142,7 +146,7 @@ class TypingNotificationPresenterTest {
)
)
// User stops typing
room.givenRoomTypingMembers(emptyList())
typingMembersFlow.emit(emptyList())
skipItems(1)
val finalState = awaitItem()
assertThat(finalState.typingMembers).isEmpty()
@ -152,14 +156,15 @@ class TypingNotificationPresenterTest {
@Test
fun `present - state is updated when a member is typing, member is not known, then known`() = runTest {
val aKnownRoomMember = createKnownRoomMember(A_USER_ID_2)
val room = FakeMatrixRoom()
val presenter = createPresenter(matrixRoom = room)
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
room.givenRoomTypingMembers(listOf(A_USER_ID_2))
typingMembersFlow.emit(listOf(A_USER_ID_2))
val oneMemberTypingState = awaitItem()
assertThat(oneMemberTypingState.typingMembers.size).isEqualTo(1)
assertThat(oneMemberTypingState.typingMembers.first()).isEqualTo(
@ -169,7 +174,7 @@ class TypingNotificationPresenterTest {
)
// User is getting known
room.givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
listOf(aKnownRoomMember).toImmutableList()
)
)
@ -185,19 +190,20 @@ class TypingNotificationPresenterTest {
@Test
fun `present - reserveSpace becomes true once we get the first typing notification with room members`() = runTest {
val room = FakeMatrixRoom()
val presenter = createPresenter(matrixRoom = room)
val typingMembersFlow = MutableStateFlow<List<UserId>>(emptyList())
val room = FakeJoinedRoom(roomTypingMembersFlow = typingMembersFlow)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.typingMembers).isEmpty()
room.givenRoomTypingMembers(listOf(A_USER_ID_2))
typingMembersFlow.emit(listOf(A_USER_ID_2))
skipItems(1)
val updatedTypingState = awaitItem()
assertThat(updatedTypingState.reserveSpace).isTrue()
// User stops typing
room.givenRoomTypingMembers(emptyList())
typingMembersFlow.emit(emptyList())
// Is still true for all future events
val futureEvents = cancelAndConsumeRemainingEvents()
for (event in futureEvents) {
@ -209,14 +215,14 @@ class TypingNotificationPresenterTest {
}
private fun createPresenter(
matrixRoom: MatrixRoom = FakeMatrixRoom().apply {
joinedRoom: JoinedRoom = FakeJoinedRoom().apply {
givenRoomInfo(aRoomInfo(id = roomId, name = ""))
},
sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(
isRenderTypingNotificationsEnabled = true
),
) = TypingNotificationPresenter(
room = matrixRoom,
room = joinedRoom,
sessionPreferencesStore = sessionPreferencesStore,
)

View file

@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.core.ProgressCallback
import io.element.android.libraries.matrix.api.media.AudioInfo
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
@ -64,11 +64,11 @@ class VoiceMessageComposerPresenterTest {
lambdaRecorder<File, AudioInfo, List<Float>, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
private val matrixRoom = FakeMatrixRoom(
private val joinedRoom = FakeJoinedRoom(
sendVoiceMessageResult = sendVoiceMessageResult
)
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
private val mediaSender = MediaSender(mediaPreProcessor, matrixRoom, InMemorySessionPreferencesStore())
private val mediaSender = MediaSender(mediaPreProcessor, joinedRoom, InMemorySessionPreferencesStore())
private val messageComposerContext = FakeMessageComposerContext()
companion object {

View file

@ -12,13 +12,13 @@ import im.vector.app.features.analytics.plan.PollEnd
import io.element.android.features.poll.api.actions.EndPollAction
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.services.analytics.api.AnalyticsService
import javax.inject.Inject
@ContributesBinding(RoomScope::class)
class DefaultEndPollAction @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val analyticsService: AnalyticsService,
) : EndPollAction {
override suspend fun execute(pollStartId: EventId): Result<Unit> {

View file

@ -12,13 +12,13 @@ import im.vector.app.features.analytics.plan.PollVote
import io.element.android.features.poll.api.actions.SendPollResponseAction
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.services.analytics.api.AnalyticsService
import javax.inject.Inject
@ContributesBinding(RoomScope::class)
class DefaultSendPollResponseAction @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val analyticsService: AnalyticsService,
) : SendPollResponseAction {
override suspend fun execute(pollStartId: EventId, answerId: String): Result<Unit> {

View file

@ -9,7 +9,7 @@ package io.element.android.features.poll.impl.data
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.poll.PollKind
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.first
import javax.inject.Inject
class PollRepository @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val timelineProvider: TimelineProvider,
) {
suspend fun getPoll(eventId: EventId): Result<PollContent> = runCatching {

View file

@ -23,7 +23,7 @@ import io.element.android.features.poll.impl.history.model.PollHistoryFilter
import io.element.android.features.poll.impl.history.model.PollHistoryItems
import io.element.android.features.poll.impl.history.model.PollHistoryItemsFactory
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.Timeline
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.map
@ -35,7 +35,7 @@ class PollHistoryPresenter @Inject constructor(
private val sendPollResponseAction: SendPollResponseAction,
private val endPollAction: EndPollAction,
private val pollHistoryItemFactory: PollHistoryItemsFactory,
private val room: MatrixRoom,
private val room: JoinedRoom,
) : Presenter<PollHistoryState> {
@Composable
override fun present(): PollHistoryState {

View file

@ -21,12 +21,11 @@ import io.element.android.features.poll.impl.anOngoingPollContent
import io.element.android.features.poll.impl.data.PollRepository
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.poll.PollKind
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider
import io.element.android.services.analytics.test.FakeAnalyticsService
@ -52,7 +51,7 @@ class CreatePollPresenterTest {
private val timeline = FakeTimeline(
timelineItems = aPollTimelineItems(mapOf(pollEventId to existingPoll))
)
private val fakeMatrixRoom = FakeMatrixRoom(
private val fakeJoinedRoom = FakeJoinedRoom(
liveTimeline = timeline
)
private val fakeAnalyticsService = FakeAnalyticsService()
@ -81,7 +80,7 @@ class CreatePollPresenterTest {
@Test
fun `in edit mode, if poll doesn't exist, error is tracked and screen is closed`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
liveTimeline = FakeTimeline()
)
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(AN_EVENT_ID), room = room)
@ -121,7 +120,7 @@ class CreatePollPresenterTest {
fun `create poll sends a poll start event`() = runTest {
val createPollResult = lambdaRecorder<String, List<String>, Int, PollKind, Result<Unit>> { _, _, _, _ -> Result.success(Unit) }
val presenter = createCreatePollPresenter(
room = FakeMatrixRoom(
room = FakeJoinedRoom(
createPollResult = createPollResult
),
mode = CreatePollMode.NewPoll,
@ -169,7 +168,7 @@ class CreatePollPresenterTest {
Result.failure(error)
}
val presenter = createCreatePollPresenter(
room = FakeMatrixRoom(
room = FakeJoinedRoom(
createPollResult = createPollResult
),
mode = CreatePollMode.NewPoll,
@ -258,7 +257,7 @@ class CreatePollPresenterTest {
Result.failure<Unit>(error)
}
val presenter = createCreatePollPresenter(
room = FakeMatrixRoom(
room = FakeJoinedRoom(
editPollResult = editPollResult,
liveTimeline = timeline,
),
@ -551,7 +550,7 @@ class CreatePollPresenterTest {
private fun createCreatePollPresenter(
mode: CreatePollMode = CreatePollMode.NewPoll,
room: MatrixRoom = fakeMatrixRoom,
room: FakeJoinedRoom = fakeJoinedRoom,
): CreatePollPresenter = CreatePollPresenter(
repository = PollRepository(room, LiveTimelineProvider(room)),
analyticsService = fakeAnalyticsService,

View file

@ -22,12 +22,11 @@ import io.element.android.features.poll.impl.model.DefaultPollContentStateFactor
import io.element.android.features.poll.test.actions.FakeEndPollAction
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.assert
@ -57,7 +56,7 @@ class PollHistoryPresenterTest {
),
backwardPaginationStatus = backwardPaginationStatus
)
private val room = FakeMatrixRoom(
private val room = FakeJoinedRoom(
liveTimeline = timeline
)
@ -155,7 +154,7 @@ class PollHistoryPresenterTest {
}
private fun TestScope.createPollHistoryPresenter(
room: MatrixRoom = FakeMatrixRoom(),
room: FakeJoinedRoom = FakeJoinedRoom(),
appCoroutineScope: CoroutineScope = this,
endPollAction: EndPollAction = FakeEndPollAction(),
sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(),

View file

@ -16,12 +16,12 @@ import io.element.android.features.call.api.CurrentCall
import io.element.android.features.call.api.CurrentCallService
import io.element.android.features.roomcall.api.RoomCallState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.ui.room.canCall
import javax.inject.Inject
class RoomCallStatePresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val currentCallService: CurrentCallService,
) : Presenter<RoomCallState> {
@Composable

View file

@ -12,8 +12,9 @@ import io.element.android.features.call.api.CurrentCall
import io.element.android.features.call.api.CurrentCallService
import io.element.android.features.call.test.FakeCurrentCallService
import io.element.android.features.roomcall.api.RoomCallState
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.tests.testutils.test
import kotlinx.coroutines.flow.MutableStateFlow
@ -23,10 +24,12 @@ import org.junit.Test
class RoomCallStatePresenterTest {
@Test
fun `present - initial state`() = runTest {
val room = FakeMatrixRoom(
canUserJoinCallResult = { Result.success(false) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(false) },
)
)
val presenter = createRoomCallStatePresenter(matrixRoom = room)
val presenter = createRoomCallStatePresenter(joinedRoom = room)
presenter.test {
val initialState = awaitItem()
assertThat(initialState).isEqualTo(
@ -39,10 +42,12 @@ class RoomCallStatePresenterTest {
@Test
fun `present - initial state - user can join call`() = runTest {
val room = FakeMatrixRoom(
canUserJoinCallResult = { Result.success(true) },
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(true) },
)
)
val presenter = createRoomCallStatePresenter(matrixRoom = room)
val presenter = createRoomCallStatePresenter(joinedRoom = room)
presenter.test {
skipItems(1)
val initialState = awaitItem()
@ -56,11 +61,13 @@ class RoomCallStatePresenterTest {
@Test
fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest {
val room = FakeMatrixRoom(
canUserJoinCallResult = { Result.success(false) },
initialRoomInfo = aRoomInfo(hasRoomCall = true),
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(false) },
initialRoomInfo = aRoomInfo(hasRoomCall = true),
)
)
val presenter = createRoomCallStatePresenter(matrixRoom = room)
val presenter = createRoomCallStatePresenter(joinedRoom = room)
presenter.test {
assertThat(awaitItem()).isEqualTo(
RoomCallState.OnGoing(
@ -74,7 +81,8 @@ class RoomCallStatePresenterTest {
@Test
fun `present - user has joined the call on another session`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(true) },
).apply {
givenRoomInfo(
@ -84,7 +92,8 @@ class RoomCallStatePresenterTest {
)
)
}
val presenter = createRoomCallStatePresenter(matrixRoom = room)
)
val presenter = createRoomCallStatePresenter(joinedRoom = room)
presenter.test {
skipItems(1)
assertThat(awaitItem()).isEqualTo(
@ -99,7 +108,8 @@ class RoomCallStatePresenterTest {
@Test
fun `present - user has joined the call locally`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(true) },
).apply {
givenRoomInfo(
@ -109,8 +119,9 @@ class RoomCallStatePresenterTest {
)
)
}
)
val presenter = createRoomCallStatePresenter(
matrixRoom = room,
joinedRoom = room,
currentCallService = FakeCurrentCallService(MutableStateFlow(CurrentCall.RoomCall(room.roomId))),
)
presenter.test {
@ -127,7 +138,8 @@ class RoomCallStatePresenterTest {
@Test
fun `present - user leaves the call`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canUserJoinCallResult = { Result.success(true) },
).apply {
givenRoomInfo(
@ -137,10 +149,11 @@ class RoomCallStatePresenterTest {
)
)
}
)
val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.RoomCall(room.roomId))
val currentCallService = FakeCurrentCallService(currentCall = currentCall)
val presenter = createRoomCallStatePresenter(
matrixRoom = room,
joinedRoom = room,
currentCallService = currentCallService
)
presenter.test {
@ -188,11 +201,11 @@ class RoomCallStatePresenterTest {
}
private fun createRoomCallStatePresenter(
matrixRoom: MatrixRoom,
joinedRoom: JoinedRoom,
currentCallService: CurrentCallService = FakeCurrentCallService(),
): RoomCallStatePresenter {
return RoomCallStatePresenter(
room = matrixRoom,
room = joinedRoom,
currentCallService = currentCallService,
)
}

View file

@ -50,7 +50,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.verification.VerificationRequest
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
@ -64,7 +64,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
@Assisted plugins: List<Plugin>,
private val pollHistoryEntryPoint: PollHistoryEntryPoint,
private val elementCallEntryPoint: ElementCallEntryPoint,
private val room: MatrixRoom,
private val room: BaseRoom,
private val analyticsService: AnalyticsService,
private val messagesEntryPoint: MessagesEntryPoint,
private val knockRequestsListEntryPoint: KnockRequestsListEntryPoint,

View file

@ -24,7 +24,7 @@ import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -36,7 +36,7 @@ class RoomDetailsNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: RoomDetailsPresenter,
private val room: MatrixRoom,
private val room: BaseRoom,
private val analyticsService: AnalyticsService,
) : Node(buildContext, plugins = plugins) {
interface Callback : Plugin {

View file

@ -35,9 +35,9 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.powerlevels.canInvite
@ -61,7 +61,7 @@ import javax.inject.Inject
class RoomDetailsPresenter @Inject constructor(
private val client: MatrixClient,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val featureFlagService: FeatureFlagService,
private val notificationSettingsService: NotificationSettingsService,
private val roomMembersDetailsPresenterFactory: RoomMemberDetailsPresenter.Factory,
@ -235,12 +235,12 @@ class RoomDetailsPresenter @Inject constructor(
}
@Composable
private fun getCanInvite(membersState: MatrixRoomMembersState) = produceState(false, membersState) {
private fun getCanInvite(membersState: RoomMembersState) = produceState(false, membersState) {
value = room.canInvite().getOrElse { false }
}
@Composable
private fun getCanSendState(membersState: MatrixRoomMembersState, type: StateEventType) = produceState(false, membersState) {
private fun getCanSendState(membersState: RoomMembersState, type: StateEventType) = produceState(false, membersState) {
value = room.canSendState(type).getOrElse { false }
}

View file

@ -9,7 +9,7 @@ package io.element.android.features.roomdetails.impl.analytics
import im.vector.app.features.analytics.plan.RoomModeration
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.services.analytics.api.AnalyticsService
internal fun RoomMember.Role.toAnalyticsMemberRole(): RoomModeration.Role = when (this) {
@ -22,7 +22,7 @@ internal fun analyticsMemberRoleForPowerLevel(powerLevel: Long): RoomModeration.
return RoomMember.Role.forPowerLevel(powerLevel).toAnalyticsMemberRole()
}
internal fun AnalyticsService.trackPermissionChangeAnalytics(initial: MatrixRoomPowerLevels?, updated: MatrixRoomPowerLevels) {
internal fun AnalyticsService.trackPermissionChangeAnalytics(initial: RoomPowerLevels?, updated: RoomPowerLevels) {
if (updated.ban != initial?.ban) {
capture(RoomModeration(RoomModeration.Action.ChangePermissionsBanMembers, analyticsMemberRoleForPowerLevel(updated.ban)))
}

View file

@ -16,14 +16,14 @@ import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
@Module
@ContributesTo(RoomScope::class)
object RoomMemberModule {
@Provides
fun provideRoomMemberDetailsPresenterFactory(
room: MatrixRoom,
room: JoinedRoom,
userProfilePresenterFactory: UserProfilePresenterFactory,
encryptionService: EncryptionService,
clipboardHelper: ClipboardHelper,

View file

@ -25,7 +25,7 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.powerlevels.canSendState
import io.element.android.libraries.matrix.ui.media.AvatarAction
@ -43,7 +43,7 @@ import timber.log.Timber
import javax.inject.Inject
class RoomDetailsEditPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val mediaPickerProvider: PickerProvider,
private val mediaPreProcessor: MediaPreProcessor,
private val temporaryUriDeleter: TemporaryUriDeleter,

View file

@ -20,7 +20,7 @@ import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.apperror.api.AppErrorStateService
@ -33,7 +33,7 @@ class RoomInviteMembersNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
coroutineDispatchers: CoroutineDispatchers,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val presenter: RoomInviteMembersPresenter,
private val appErrorStateService: AppErrorStateService,
private val analyticsService: AnalyticsService,

View file

@ -9,14 +9,14 @@ package io.element.android.features.roomdetails.impl.members
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.roomMembers
import kotlinx.coroutines.withContext
import javax.inject.Inject
class RoomMemberListDataSource @Inject constructor(
private val room: MatrixRoom,
private val room: BaseRoom,
private val coroutineDispatchers: CoroutineDispatchers,
) {
suspend fun search(query: String): List<RoomMember> = withContext(coroutineDispatchers.io) {

View file

@ -28,9 +28,9 @@ import io.element.android.libraries.designsystem.theme.components.SearchBarResul
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.ui.room.canInviteAsState
@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.withContext
class RoomMemberListPresenter @AssistedInject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val roomMemberListDataSource: RoomMemberListDataSource,
private val coroutineDispatchers: CoroutineDispatchers,
private val roomMembersModerationPresenter: Presenter<RoomMembersModerationState>,
@ -86,11 +86,11 @@ class RoomMemberListPresenter @AssistedInject constructor(
}
LaunchedEffect(membersState, roomMemberIdentityStates) {
if (membersState is MatrixRoomMembersState.Unknown) {
if (membersState is RoomMembersState.Unknown) {
return@LaunchedEffect
}
val finalMembersState = membersState
if (finalMembersState is MatrixRoomMembersState.Error && finalMembersState.roomMembers().orEmpty().isEmpty()) {
if (finalMembersState is RoomMembersState.Error && finalMembersState.roomMembers().orEmpty().isEmpty()) {
// Cannot fetch members and no cached members, display the error
roomMembers = AsyncData.Failure(finalMembersState.failure)
return@LaunchedEffect
@ -116,7 +116,7 @@ class RoomMemberListPresenter @AssistedInject constructor(
.map { it.withIdentityState(roomMemberIdentityStates) }
.toImmutableList(),
)
roomMembers = if (membersState is MatrixRoomMembersState.Pending) {
roomMembers = if (membersState is RoomMembersState.Pending) {
AsyncData.Loading(result)
} else {
AsyncData.Success(result)
@ -147,7 +147,7 @@ class RoomMemberListPresenter @AssistedInject constructor(
.toImmutableList(),
)
SearchBarResultState.Results(
if (membersState is MatrixRoomMembersState.Pending) {
if (membersState is RoomMembersState.Pending) {
AsyncData.Loading(result)
} else {
AsyncData.Success(result)

View file

@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.ui.room.getRoomMemberAsState
import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange
import io.element.android.libraries.ui.strings.CommonStrings
@ -45,7 +45,7 @@ import kotlinx.coroutines.launch
*/
class RoomMemberDetailsPresenter @AssistedInject constructor(
@Assisted private val roomMemberId: UserId,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val encryptionService: EncryptionService,
private val clipboardHelper: ClipboardHelper,
userProfilePresenterFactory: UserProfilePresenterFactory,

View file

@ -22,7 +22,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.ui.room.canBanAsState
@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
class RoomMembersModerationPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val dispatchers: CoroutineDispatchers,
private val analyticsService: AnalyticsService,
) : Presenter<RoomMembersModerationState> {

View file

@ -26,7 +26,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.core.coroutine.suspendWithMinimumDuration
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.RoomNotificationSettings
import kotlinx.coroutines.CoroutineScope
@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.seconds
class RoomNotificationSettingsPresenter @AssistedInject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val notificationSettingsService: NotificationSettingsService,
@Assisted private val showUserDefinedSettingStyle: Boolean,
) : Presenter<RoomNotificationSettingsState> {

View file

@ -19,7 +19,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
@ -32,7 +32,7 @@ class RolesAndPermissionsNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: RolesAndPermissionsPresenter,
private val room: MatrixRoom,
private val room: BaseRoom,
) : Node(buildContext, plugins = plugins), RolesAndPermissionsNavigator {
interface Callback : Plugin, RolesAndPermissionsNavigator {
override fun openAdminList()

View file

@ -21,8 +21,8 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.activeRoomMembers
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
@ -32,7 +32,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
class RolesAndPermissionsPresenter @Inject constructor(
private val room: MatrixRoom,
private val room: JoinedRoom,
private val dispatchers: CoroutineDispatchers,
private val analyticsService: AnalyticsService,
) : Presenter<RolesAndPermissionsState> {
@ -109,7 +109,7 @@ class RolesAndPermissionsPresenter @Inject constructor(
}
}
private fun MatrixRoomInfo.userCountWithRole(userIds: List<UserId>, role: RoomMember.Role): Int {
private fun RoomInfo.userCountWithRole(userIds: List<UserId>, role: RoomMember.Role): Int {
return this.userPowerLevels.count { (userId, level) ->
RoomMember.Role.forPowerLevel(level) == role && userId in userIds
}

View file

@ -30,7 +30,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.room.powerlevels.usersWithRole
@ -50,7 +50,7 @@ import kotlinx.coroutines.launch
class ChangeRolesPresenter @AssistedInject constructor(
@Assisted private val role: RoomMember.Role,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val dispatchers: CoroutineDispatchers,
private val analyticsService: AnalyticsService,
) : Presenter<ChangeRolesState> {

View file

@ -21,8 +21,8 @@ import dagger.assisted.AssistedInject
import io.element.android.features.roomdetails.impl.analytics.trackPermissionChangeAnalytics
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
class ChangeRoomPermissionsPresenter @AssistedInject constructor(
@Assisted private val section: ChangeRoomPermissionsSection,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val analyticsService: AnalyticsService,
) : Presenter<ChangeRoomPermissionsState> {
companion object {
@ -59,8 +59,8 @@ class ChangeRoomPermissionsPresenter @AssistedInject constructor(
private val items: ImmutableList<RoomPermissionType> = itemsForSection(section)
private var initialPermissions by mutableStateOf<MatrixRoomPowerLevels?>(null)
private var currentPermissions by mutableStateOf<MatrixRoomPowerLevels?>(null)
private var initialPermissions by mutableStateOf<RoomPowerLevels?>(null)
private var currentPermissions by mutableStateOf<RoomPowerLevels?>(null)
private var saveAction by mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized)
private var confirmExitAction by mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized)

View file

@ -8,12 +8,12 @@
package io.element.android.features.roomdetails.impl.rolesandpermissions.permissions
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import kotlinx.collections.immutable.ImmutableList
data class ChangeRoomPermissionsState(
val section: ChangeRoomPermissionsSection,
val currentPermissions: MatrixRoomPowerLevels?,
val currentPermissions: RoomPowerLevels?,
val items: ImmutableList<RoomPermissionType>,
val hasChanges: Boolean,
val saveAction: AsyncAction<Unit>,

View file

@ -10,7 +10,7 @@ package io.element.android.features.roomdetails.impl.rolesandpermissions.permiss
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import kotlinx.collections.immutable.toPersistentList
class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPermissionsState> {
@ -36,7 +36,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPe
internal fun aChangeRoomPermissionsState(
section: ChangeRoomPermissionsSection,
currentPermissions: MatrixRoomPowerLevels = previewPermissions(),
currentPermissions: RoomPowerLevels = previewPermissions(),
items: List<RoomPermissionType> = ChangeRoomPermissionsPresenter.itemsForSection(section),
hasChanges: Boolean = false,
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
@ -52,8 +52,8 @@ internal fun aChangeRoomPermissionsState(
eventSink = eventSink,
)
private fun previewPermissions(): MatrixRoomPowerLevels {
return MatrixRoomPowerLevels(
private fun previewPermissions(): RoomPowerLevels {
return RoomPowerLevels(
// MembershipModeration section
invite = RoomMember.Role.ADMIN.powerLevel,
kick = RoomMember.Role.MODERATOR.powerLevel,

View file

@ -36,7 +36,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@ -133,7 +133,7 @@ fun ChangeRoomPermissionsView(
private fun SelectRoleItem(
permissionsItem: RoomPermissionType,
role: RoomMember.Role,
currentPermissions: MatrixRoomPowerLevels?,
currentPermissions: RoomPowerLevels?,
onClick: (RoomPermissionType, RoomMember.Role) -> Unit
) {
val title = when (role) {
@ -153,7 +153,7 @@ private fun SelectRoleItem(
)
}
private fun MatrixRoomPowerLevels.isSelected(item: RoomPermissionType, role: RoomMember.Role): Boolean {
private fun RoomPowerLevels.isSelected(item: RoomPermissionType, role: RoomMember.Role): Boolean {
return when (item) {
RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(ban) == role
RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(invite) == role

View file

@ -29,8 +29,8 @@ import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
@ -43,7 +43,7 @@ import kotlinx.coroutines.launch
class SecurityAndPrivacyPresenter @AssistedInject constructor(
@Assisted private val navigator: SecurityAndPrivacyNavigator,
private val matrixClient: MatrixClient,
private val room: MatrixRoom,
private val room: JoinedRoom,
) : Presenter<SecurityAndPrivacyState> {
@AssistedFactory
interface Factory {
@ -279,6 +279,6 @@ private fun SecurityAndPrivacyHistoryVisibility.map(): RoomHistoryVisibility {
}
}
private fun MatrixRoomInfo.firstDisplayableAlias(serverName: String): RoomAlias? {
private fun RoomInfo.firstDisplayableAlias(serverName: String): RoomAlias? {
return aliases.firstOrNull { it.matchesServer(serverName) } ?: aliases.firstOrNull()
}

View file

@ -25,8 +25,8 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
import io.element.android.libraries.matrix.api.roomAliasFromName
import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity
@ -37,7 +37,7 @@ import kotlinx.coroutines.launch
class EditRoomAddressPresenter @AssistedInject constructor(
@Assisted private val navigator: SecurityAndPrivacyNavigator,
private val client: MatrixClient,
private val room: MatrixRoom,
private val room: JoinedRoom,
private val roomAliasHelper: RoomAliasHelper,
) : Presenter<EditRoomAddressState> {
@AssistedFactory
@ -139,7 +139,7 @@ class EditRoomAddressPresenter @AssistedInject constructor(
/**
* Returns the first alias that matches the given server name, or null if none match.
*/
private fun MatrixRoomInfo.firstAliasMatching(serverName: String): RoomAlias? {
private fun RoomInfo.firstAliasMatching(serverName: String): RoomAlias? {
// Check if the canonical alias matches the homeserver
if (canonicalAlias?.matchesServer(serverName) == true) {
return canonicalAlias

View file

@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.produceState
import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.SecurityAndPrivacyPermissions.Companion.DEFAULT
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.powerlevels.canSendState
@ -37,7 +37,7 @@ data class SecurityAndPrivacyPermissions(
}
@Composable
fun MatrixRoom.securityAndPrivacyPermissionsAsState(updateKey: Long): State<SecurityAndPrivacyPermissions> {
fun BaseRoom.securityAndPrivacyPermissionsAsState(updateKey: Long): State<SecurityAndPrivacyPermissions> {
return produceState(DEFAULT, key1 = updateKey) {
value = SecurityAndPrivacyPermissions(
canChangeRoomAccess = canSendState(type = StateEventType.ROOM_JOIN_RULES).getOrElse { false },

View file

@ -21,11 +21,66 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME
import io.element.android.libraries.matrix.test.A_ROOM_TOPIC
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.tests.testutils.lambda.lambdaError
fun aMatrixRoom(
fun aRoom(
sessionId: SessionId = A_SESSION_ID,
roomId: RoomId = A_ROOM_ID,
displayName: String = A_ROOM_NAME,
rawName: String? = displayName,
topic: String? = A_ROOM_TOPIC,
avatarUrl: String? = AN_AVATAR_URL,
canonicalAlias: RoomAlias? = A_ROOM_ALIAS,
isEncrypted: Boolean = true,
isPublic: Boolean = true,
isDirect: Boolean = false,
joinRule: JoinRule? = null,
activeMemberCount: Long = 1,
joinedMemberCount: Long = 1,
invitedMemberCount: Long = 0,
canInviteResult: (UserId) -> Result<Boolean> = { lambdaError() },
canBanResult: (UserId) -> Result<Boolean> = { lambdaError() },
canKickResult: (UserId) -> Result<Boolean> = { lambdaError() },
canSendStateResult: (UserId, StateEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
userDisplayNameResult: (UserId) -> Result<String?> = { lambdaError() },
userAvatarUrlResult: () -> Result<String?> = { lambdaError() },
canUserJoinCallResult: (UserId) -> Result<Boolean> = { lambdaError() },
getUpdatedMemberResult: (UserId) -> Result<RoomMember> = { lambdaError() },
userRoleResult: () -> Result<RoomMember.Role> = { lambdaError() },
setIsFavoriteResult: (Boolean) -> Result<Unit> = { lambdaError() },
) = FakeBaseRoom(
sessionId = sessionId,
roomId = roomId,
canInviteResult = canInviteResult,
canBanResult = canBanResult,
canKickResult = canKickResult,
canSendStateResult = canSendStateResult,
userDisplayNameResult = userDisplayNameResult,
userAvatarUrlResult = userAvatarUrlResult,
canUserJoinCallResult = canUserJoinCallResult,
getUpdatedMemberResult = getUpdatedMemberResult,
userRoleResult = userRoleResult,
setIsFavoriteResult = setIsFavoriteResult,
initialRoomInfo = aRoomInfo(
name = displayName,
rawName = rawName,
topic = topic,
avatarUrl = avatarUrl,
canonicalAlias = canonicalAlias,
isDirect = isDirect,
isPublic = isPublic,
isEncrypted = isEncrypted,
joinRule = joinRule,
joinedMembersCount = joinedMemberCount,
activeMembersCount = activeMemberCount,
invitedMembersCount = invitedMemberCount,
)
)
fun aJoinedRoom(
sessionId: SessionId = A_SESSION_ID,
roomId: RoomId = A_ROOM_ID,
displayName: String = A_ROOM_NAME,
@ -60,31 +115,33 @@ fun aMatrixRoom(
updateCanonicalAliasResult: (RoomAlias?, List<RoomAlias>) -> Result<Unit> = { _, _ -> lambdaError() },
publishRoomAliasInRoomDirectoryResult: (RoomAlias) -> Result<Boolean> = { lambdaError() },
removeRoomAliasFromRoomDirectoryResult: (RoomAlias) -> Result<Boolean> = { lambdaError() },
) = FakeMatrixRoom(
sessionId = sessionId,
roomId = roomId,
notificationSettingsService = notificationSettingsService,
canInviteResult = canInviteResult,
canBanResult = canBanResult,
canKickResult = canKickResult,
canSendStateResult = canSendStateResult,
userDisplayNameResult = userDisplayNameResult,
userAvatarUrlResult = userAvatarUrlResult,
setIsFavoriteResult: (Boolean) -> Result<Unit> = { lambdaError() },
) = FakeJoinedRoom(
roomNotificationSettingsService = notificationSettingsService,
setNameResult = setNameResult,
setTopicResult = setTopicResult,
updateAvatarResult = updateAvatarResult,
removeAvatarResult = removeAvatarResult,
canUserJoinCallResult = canUserJoinCallResult,
getUpdatedMemberResult = getUpdatedMemberResult,
userRoleResult = userRoleResult,
kickUserResult = kickUserResult,
banUserResult = banUserResult,
unBanUserResult = unBanUserResult,
updateCanonicalAliasResult = updateCanonicalAliasResult,
publishRoomAliasInRoomDirectoryResult = publishRoomAliasInRoomDirectoryResult,
removeRoomAliasFromRoomDirectoryResult = removeRoomAliasFromRoomDirectoryResult,
initialRoomInfo = aRoomInfo(
name = displayName,
baseRoom = aRoom(
sessionId = sessionId,
roomId = roomId,
canInviteResult = canInviteResult,
canBanResult = canBanResult,
canKickResult = canKickResult,
canSendStateResult = canSendStateResult,
userDisplayNameResult = userDisplayNameResult,
userAvatarUrlResult = userAvatarUrlResult,
canUserJoinCallResult = canUserJoinCallResult,
getUpdatedMemberResult = getUpdatedMemberResult,
userRoleResult = userRoleResult,
setIsFavoriteResult = setIsFavoriteResult,
displayName = displayName,
rawName = rawName,
topic = topic,
avatarUrl = avatarUrl,
@ -93,8 +150,8 @@ fun aMatrixRoom(
isPublic = isPublic,
isEncrypted = isEncrypted,
joinRule = joinRule,
joinedMembersCount = joinedMemberCount,
activeMembersCount = activeMemberCount,
invitedMembersCount = invitedMemberCount,
joinedMemberCount = joinedMemberCount,
activeMemberCount = activeMemberCount,
invitedMemberCount = invitedMemberCount,
)
)

View file

@ -25,8 +25,8 @@ import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.join.JoinRule
@ -39,7 +39,6 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService
@ -70,7 +69,7 @@ class RoomDetailsPresenterTest {
}
private fun TestScope.createRoomDetailsPresenter(
room: MatrixRoom = aMatrixRoom(),
room: JoinedRoom = aJoinedRoom(),
leaveRoomState: LeaveRoomState = aLeaveRoomState(),
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
@ -116,7 +115,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state is created from initial room info`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -145,7 +144,7 @@ class RoomDetailsPresenterTest {
avatarUrl = AN_AVATAR_URL,
pinnedEventIds = listOf(AN_EVENT_ID),
)
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -166,7 +165,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state with no room name`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
displayName = "",
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
@ -185,7 +184,7 @@ class RoomDetailsPresenterTest {
fun `present - initial state with DM member sets custom DM roomType`() = runTest {
val myRoomMember = aRoomMember(A_SESSION_ID)
val otherRoomMember = aRoomMember(A_USER_ID_2)
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -198,7 +197,7 @@ class RoomDetailsPresenterTest {
},
).apply {
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
givenRoomMembersState(RoomMembersState.Ready(roomMembers))
givenRoomInfo(
aRoomInfo(
@ -222,7 +221,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when user can invite others to room`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -240,7 +239,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when user can not invite others to room`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(false) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -255,7 +254,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when canInvite errors`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.failure(Throwable("Whoops")) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -270,7 +269,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when user can edit one attribute`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
StateEventType.ROOM_TOPIC -> Result.success(true)
@ -296,7 +295,7 @@ class RoomDetailsPresenterTest {
fun `present - initial state when user can edit attributes in a DM`() = runTest {
val myRoomMember = aRoomMember(A_SESSION_ID)
val otherRoomMember = aRoomMember(A_USER_ID_2)
val room = aMatrixRoom(
val room = aJoinedRoom(
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
StateEventType.ROOM_TOPIC,
@ -316,7 +315,7 @@ class RoomDetailsPresenterTest {
},
).apply {
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
givenRoomMembersState(RoomMembersState.Ready(roomMembers))
givenRoomInfo(
aRoomInfo(
@ -343,7 +342,7 @@ class RoomDetailsPresenterTest {
fun `present - initial state when in a DM with no topic`() = runTest {
val myRoomMember = aRoomMember(A_SESSION_ID)
val otherRoomMember = aRoomMember(A_USER_ID_2)
val room = aMatrixRoom(
val room = aJoinedRoom(
isDirect = true,
topic = null,
canSendStateResult = { _, stateEventType ->
@ -365,7 +364,7 @@ class RoomDetailsPresenterTest {
},
).apply {
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
givenRoomMembersState(RoomMembersState.Ready(roomMembers))
givenRoomInfo(
aRoomInfo(
@ -378,7 +377,7 @@ class RoomDetailsPresenterTest {
val presenter = createRoomDetailsPresenter(room)
presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) {
skipItems(1)
skipItems(2)
// There's no topic, so we hide the entire UI for DMs
assertThat(awaitItem().roomTopic).isEqualTo(RoomTopicState.Hidden)
@ -389,7 +388,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when user can edit all attributes`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
StateEventType.ROOM_TOPIC,
@ -416,7 +415,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - initial state when user can edit no attributes`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
StateEventType.ROOM_TOPIC,
@ -441,7 +440,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - topic state is hidden when no topic and user has no permission`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = null,
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
@ -467,7 +466,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - topic state is 'can add topic' when no topic and user has permission`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = null,
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
@ -499,7 +498,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - leave room event is passed on to leave room presenter`() = runTest {
val leaveRoomEventRecorder = EventsRecorder<LeaveRoomEvent>()
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -519,7 +518,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - notification mode changes`() = runTest {
val notificationSettingsService = FakeNotificationSettingsService()
val room = aMatrixRoom(
val room = aJoinedRoom(
notificationSettingsService = notificationSettingsService,
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
@ -548,7 +547,7 @@ class RoomDetailsPresenterTest {
fun `present - mute room notifications`() = runTest {
val notificationSettingsService =
FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
val room = aMatrixRoom(
val room = aJoinedRoom(
notificationSettingsService = notificationSettingsService,
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
@ -576,7 +575,7 @@ class RoomDetailsPresenterTest {
initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
initialEncryptedGroupDefaultMode = RoomNotificationMode.ALL_MESSAGES
)
val room = aMatrixRoom(
val room = aJoinedRoom(
notificationSettingsService = notificationSettingsService,
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
@ -601,7 +600,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
val setIsFavoriteResult = lambdaRecorder<Boolean, Result<Unit>> { _ -> Result.success(Unit) }
val room = FakeMatrixRoom(
val room = aJoinedRoom(
setIsFavoriteResult = setIsFavoriteResult,
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
@ -630,7 +629,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - changes in room info updates the is favorite flag`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -651,7 +650,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - show knock requests`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },
@ -677,7 +676,7 @@ class RoomDetailsPresenterTest {
@Test
fun `present - show security and privacy`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canInviteResult = { Result.success(true) },
canUserJoinCallResult = { Result.success(true) },
canSendStateResult = { _, _ -> Result.success(true) },

Some files were not shown because too many files have changed in this diff Show more