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

@ -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) },

View file

@ -10,11 +10,11 @@ package io.element.android.features.roomdetails.impl.edit
import android.net.Uri
import app.cash.turbine.ReceiveTurbine
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aJoinedRoom
import io.element.android.libraries.androidutils.file.TemporaryUriDeleter
import io.element.android.libraries.architecture.AsyncAction
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.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.A_ROOM_NAME
@ -74,7 +74,7 @@ class RoomDetailsEditPresenterTest {
}
private fun createRoomDetailsEditPresenter(
room: MatrixRoom,
room: JoinedRoom,
permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(),
temporaryUriDeleter: TemporaryUriDeleter = FakeTemporaryUriDeleter(),
): RoomDetailsEditPresenter {
@ -89,7 +89,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - initial state is created from room info`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
avatarUrl = AN_AVATAR_URL,
displayName = A_ROOM_NAME,
rawName = A_ROOM_RAW_NAME,
@ -118,7 +118,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets canChangeName if user has permission`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
avatarUrl = AN_AVATAR_URL,
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
@ -151,7 +151,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets canChangeAvatar if user has permission`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
avatarUrl = AN_AVATAR_URL,
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
@ -183,7 +183,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets canChangeTopic if user has permission`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
avatarUrl = AN_AVATAR_URL,
canSendStateResult = { _, stateEventType ->
when (stateEventType) {
@ -215,7 +215,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - updates state in response to changes`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -260,7 +260,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - obtains avatar uris from gallery`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -284,7 +284,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - obtains avatar uris from camera`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -325,7 +325,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - updates save button state`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -375,7 +375,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - updates save button state when initial values are null`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = null,
displayName = "fallback",
avatarUrl = null,
@ -428,7 +428,7 @@ class RoomDetailsEditPresenterTest {
val setNameResult = lambdaRecorder { _: String -> Result.success(Unit) }
val setTopicResult = lambdaRecorder { _: String -> Result.success(Unit) }
val removeAvatarResult = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -457,7 +457,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - save doesn't change room details if they're the same trimmed`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -479,7 +479,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - save doesn't change topic if it was unset and is now blank`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = null,
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -501,7 +501,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - save doesn't change name if it's now empty`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -524,7 +524,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - save processes and sets avatar when processor returns successfully`() = runTest {
val updateAvatarResult = lambdaRecorder { _: String, _: ByteArray -> Result.success(Unit) }
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -552,7 +552,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - save does not set avatar data if processor fails`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -576,7 +576,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets save action to failure if name update fails`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -588,7 +588,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets save action to failure if topic update fails`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -600,7 +600,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets save action to failure if removing avatar fails`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -613,7 +613,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - sets save action to failure if setting avatar fails`() = runTest {
givenPickerReturnsFile()
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -626,7 +626,7 @@ class RoomDetailsEditPresenterTest {
@Test
fun `present - CancelSaveChanges resets save action state`() = runTest {
givenPickerReturnsFile()
val room = aMatrixRoom(
val room = aJoinedRoom(
topic = "My topic",
displayName = "Name",
avatarUrl = AN_AVATAR_URL,
@ -650,7 +650,7 @@ class RoomDetailsEditPresenterTest {
}
private suspend fun saveAndAssertFailure(
room: MatrixRoom,
room: JoinedRoom,
event: RoomDetailsEditEvents,
deleteCallbackNumberOfInvocation: Int = 2,
) {

View file

@ -11,19 +11,19 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aRoom
import io.element.android.features.roomdetails.impl.members.RoomMemberListDataSource
import io.element.android.features.roomdetails.impl.members.aRoomMember
import io.element.android.features.roomdetails.impl.members.aRoomMemberList
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
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.BaseRoom
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.user.MatrixUser
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.ui.components.aMatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import io.element.android.libraries.usersearch.api.UserSearchResult
@ -47,7 +47,7 @@ internal class RoomInviteMembersPresenterTest {
fun `present - initial state has no results and no search`() = runTest {
val presenter = RoomInviteMembersPresenter(
userRepository = FakeUserRepository(),
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers()
)
@ -69,7 +69,7 @@ internal class RoomInviteMembersPresenterTest {
fun `present - updates search active state`() = runTest {
val presenter = RoomInviteMembersPresenter(
userRepository = FakeUserRepository(),
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers()
)
@ -91,7 +91,7 @@ internal class RoomInviteMembersPresenterTest {
val repository = FakeUserRepository()
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -118,7 +118,7 @@ internal class RoomInviteMembersPresenterTest {
val repository = FakeUserRepository()
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -159,9 +159,9 @@ internal class RoomInviteMembersPresenterTest {
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(
matrixRoom = FakeMatrixRoom().apply {
room = FakeBaseRoom().apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
@ -219,9 +219,9 @@ internal class RoomInviteMembersPresenterTest {
val repository = FakeUserRepository()
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(FakeMatrixRoom().apply {
roomMemberListDataSource = createDataSource(FakeBaseRoom().apply {
givenRoomMembersState(
MatrixRoomMembersState.Ready(
RoomMembersState.Ready(
persistentListOf(
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
@ -295,7 +295,7 @@ internal class RoomInviteMembersPresenterTest {
val repository = FakeUserRepository()
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -336,7 +336,7 @@ internal class RoomInviteMembersPresenterTest {
val repository = FakeUserRepository()
val presenter = RoomInviteMembersPresenter(
userRepository = repository,
roomMemberListDataSource = createDataSource(FakeMatrixRoom()),
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -397,11 +397,11 @@ internal class RoomInviteMembersPresenterTest {
}
private fun TestScope.createDataSource(
matrixRoom: MatrixRoom = aMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
room: BaseRoom = aRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
},
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers()
) = RoomMemberListDataSource(matrixRoom, coroutineDispatchers)
) = RoomMemberListDataSource(room, coroutineDispatchers)
private fun SearchBarResultState<ImmutableList<InvitableUser>>.users() =
(this as? SearchBarResultState.Results<ImmutableList<InvitableUser>>)?.results.orEmpty()

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID_4
import io.element.android.libraries.matrix.test.A_USER_ID_5
import org.junit.Test
class PowerLevelRoomMemberComparatorTest {
class PowerLevelBaseRoomMemberComparatorTest {
@Test
fun `order is Admin, then Moderator, then User`() {
val memberList = listOf(

View file

@ -17,10 +17,12 @@ import io.element.android.features.roomdetails.impl.members.moderation.aRoomMemb
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.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.BaseRoom
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.encryption.FakeEncryptionService
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.EventsRecorder
import io.element.android.tests.testutils.WarmUpRule
@ -38,14 +40,16 @@ class RoomMemberListPresenterTest {
@Test
fun `member loading is done automatically on start, but is async`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
).apply {
// Needed to avoid discarding the loaded members as a partial and invalid result
givenRoomInfo(aRoomInfo(joinedMembersCount = 2))
}
val presenter = createPresenter(matrixRoom = room)
)
val presenter = createPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -55,7 +59,7 @@ class RoomMemberListPresenterTest {
assertThat(initialState.searchQuery).isEmpty()
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
assertThat(initialState.isSearchActive).isFalse()
room.givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
// Skip item while the new members state is processed
skipItems(1)
val loadedMembersState = awaitItem()
@ -69,9 +73,11 @@ class RoomMemberListPresenterTest {
@Test
fun `open search`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -89,10 +95,12 @@ class RoomMemberListPresenterTest {
@Test
fun `search for something which is not found`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -113,9 +121,11 @@ class RoomMemberListPresenterTest {
@Test
fun `search for something which is found`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -139,9 +149,11 @@ class RoomMemberListPresenterTest {
@Test
fun `present - asynchronously sets canInvite when user has correct power level`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
canInviteResult = { Result.success(true) },
updateMembersResult = { Result.success(Unit) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canInviteResult = { Result.success(true) },
updateMembersResult = { Result.success(Unit) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -156,9 +168,11 @@ class RoomMemberListPresenterTest {
@Test
fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
canInviteResult = { Result.success(false) },
updateMembersResult = { Result.success(Unit) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canInviteResult = { Result.success(false) },
updateMembersResult = { Result.success(Unit) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -173,9 +187,11 @@ class RoomMemberListPresenterTest {
@Test
fun `present - asynchronously sets canInvite when power level check fails`() = runTest {
val presenter = createPresenter(
matrixRoom = FakeMatrixRoom(
canInviteResult = { Result.failure(Throwable("Eek")) },
updateMembersResult = { Result.success(Unit) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canInviteResult = { Result.failure(Throwable("Eek")) },
updateMembersResult = { Result.success(Unit) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -194,9 +210,11 @@ class RoomMemberListPresenterTest {
val presenter = createPresenter(
roomMembersModerationStateLambda = roomMembersModerationStateLambda,
navigator = navigator,
matrixRoom = FakeMatrixRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -221,9 +239,11 @@ class RoomMemberListPresenterTest {
val presenter = createPresenter(
roomMembersModerationStateLambda = roomMembersModerationStateLambda,
navigator = navigator,
matrixRoom = FakeMatrixRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
joinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) },
canInviteResult = { Result.success(true) }
)
)
)
moleculeFlow(RecompositionMode.Immediate) {
@ -247,24 +267,26 @@ private class FakeRoomMemberListNavigator : RoomMemberListNavigator {
@ExperimentalCoroutinesApi
private fun TestScope.createDataSource(
matrixRoom: MatrixRoom = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
room: BaseRoom = FakeBaseRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
},
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers()
) = RoomMemberListDataSource(matrixRoom, coroutineDispatchers)
) = RoomMemberListDataSource(room, coroutineDispatchers)
@ExperimentalCoroutinesApi
private fun TestScope.createPresenter(
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true),
matrixRoom: MatrixRoom = FakeMatrixRoom(
updateMembersResult = { Result.success(Unit) }
joinedRoom: JoinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
updateMembersResult = { Result.success(Unit) }
)
),
roomMemberListDataSource: RoomMemberListDataSource = createDataSource(coroutineDispatchers = coroutineDispatchers),
roomMembersModerationStateLambda: () -> RoomMembersModerationState = { aRoomMembersModerationState() },
encryptedService: FakeEncryptionService = FakeEncryptionService(),
navigator: RoomMemberListNavigator = object : RoomMemberListNavigator {}
) = RoomMemberListPresenter(
room = matrixRoom,
room = joinedRoom,
roomMemberListDataSource = roomMemberListDataSource,
coroutineDispatchers = coroutineDispatchers,
roomMembersModerationPresenter = { roomMembersModerationStateLambda() },

View file

@ -11,7 +11,7 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aJoinedRoom
import io.element.android.features.roomdetails.impl.members.aRoomMember
import io.element.android.features.userprofile.api.UserProfileEvents
import io.element.android.features.userprofile.api.UserProfilePresenterFactory
@ -23,12 +23,13 @@ import io.element.android.libraries.architecture.Presenter
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.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.AN_EXCEPTION
import io.element.android.libraries.matrix.test.A_USER_ID
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.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.WarmUpRule
import io.element.android.tests.testutils.consumeItemsUntilPredicate
@ -36,6 +37,7 @@ import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -48,12 +50,12 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - returns the room member's data, then updates it if needed`() = runTest {
val roomMember = aRoomMember(displayName = "Alice")
val room = aMatrixRoom(
val room = aJoinedRoom(
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
getUpdatedMemberResult = { Result.success(roomMember) },
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(roomMember)))
}
val presenter = createRoomMemberDetailsPresenter(
room = room,
@ -75,12 +77,12 @@ class RoomMemberDetailsPresenterTest {
displayName = "Alice",
avatarUrl = "Alice Avatar url",
)
val room = aMatrixRoom(
val room = aJoinedRoom(
userDisplayNameResult = { Result.failure(Throwable()) },
userAvatarUrlResult = { Result.failure(Throwable()) },
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(roomMember)))
}
val presenter = createRoomMemberDetailsPresenter(
@ -98,12 +100,12 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - will fallback to original data if the updated data is null`() = runTest {
val roomMember = aRoomMember(displayName = "Alice")
val room = aMatrixRoom(
val room = aJoinedRoom(
userDisplayNameResult = { Result.success(null) },
userAvatarUrlResult = { Result.success(null) },
getUpdatedMemberResult = { Result.success(roomMember) }
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(roomMember)))
}
val presenter = createRoomMemberDetailsPresenter(
room = room,
@ -119,7 +121,7 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - will fallback to user profile if user is not a member of the room`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
userDisplayNameResult = { Result.failure(Exception("Not a member!")) },
userAvatarUrlResult = { Result.failure(Exception("Not a member!")) },
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
@ -142,7 +144,7 @@ class RoomMemberDetailsPresenterTest {
displayName = null,
avatarUrl = null,
)
val room = aMatrixRoom(
val room = aJoinedRoom(
userDisplayNameResult = { Result.success(null) },
userAvatarUrlResult = { Result.success(null) },
getUpdatedMemberResult = { Result.success(roomMember) },
@ -169,12 +171,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - when user's identity is verified, the value in the state is VERIFIED`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(IdentityState.Verified) },
)
@ -188,12 +192,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - when user's identity is unknown, the value in the state is UNKNOWN`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(null) },
)
@ -207,12 +213,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - when user's identity is pinned, the value in the state is UNVERIFIED`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(IdentityState.Pinned) },
)
@ -226,12 +234,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - when user's identity is pin violation, the value in the state is UNVERIFIED`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(IdentityState.PinViolation) },
)
@ -245,12 +255,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - when user's identity has a verification violation, the value in the state is VERIFICATION_VIOLATION`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(IdentityState.VerificationViolation) },
)
@ -264,11 +276,15 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - user identity updates in real time if the room is encrypted`() = runTest {
val room = FakeMatrixRoom(
val identityStateChanges = MutableStateFlow(emptyList<IdentityStateChange>())
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
),
identityStateChangesFlow = identityStateChanges,
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(null) },
@ -280,24 +296,28 @@ class RoomMemberDetailsPresenterTest {
room.emitSyncUpdate()
room.emitIdentityStateChanges(listOf(IdentityStateChange(A_USER_ID, IdentityState.Pinned)))
identityStateChanges.emit(listOf(IdentityStateChange(A_USER_ID, IdentityState.Pinned)))
consumeItemsUntilPredicate { it.verificationState == UserProfileVerificationState.UNVERIFIED }
room.emitIdentityStateChanges(listOf(IdentityStateChange(A_USER_ID, IdentityState.Verified)))
identityStateChanges.emit(listOf(IdentityStateChange(A_USER_ID, IdentityState.Verified)))
consumeItemsUntilPredicate { it.verificationState == UserProfileVerificationState.VERIFIED }
room.emitIdentityStateChanges(listOf(IdentityStateChange(A_USER_ID, IdentityState.VerificationViolation)))
identityStateChanges.emit(listOf(IdentityStateChange(A_USER_ID, IdentityState.VerificationViolation)))
consumeItemsUntilPredicate { it.verificationState == UserProfileVerificationState.VERIFICATION_VIOLATION }
}
}
@Test
fun `present - user identity can't update in real time if the room is not encrypted`() = runTest {
val room = FakeMatrixRoom(
val identityStateChanges = MutableStateFlow(emptyList<IdentityStateChange>())
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = false),
),
identityStateChangesFlow = identityStateChanges,
)
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(null) },
@ -308,7 +328,7 @@ class RoomMemberDetailsPresenterTest {
assertThat(awaitItem().verificationState).isEqualTo(UserProfileVerificationState.UNKNOWN)
room.emitSyncUpdate()
room.emitIdentityStateChanges(listOf(IdentityStateChange(A_USER_ID, IdentityState.Pinned)))
identityStateChanges.emit(listOf(IdentityStateChange(A_USER_ID, IdentityState.Pinned)))
// No new events emitted
ensureAllEventsConsumed()
@ -317,12 +337,14 @@ class RoomMemberDetailsPresenterTest {
@Test
fun `present - handles WithdrawVerification action`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
getUpdatedMemberResult = { Result.success(aRoomMember(A_USER_ID)) },
userDisplayNameResult = { Result.success("A custom name") },
userAvatarUrlResult = { Result.success("A custom avatar") },
initialRoomInfo = aRoomInfo(isEncrypted = true),
)
)
val withdrawVerificationResult = lambdaRecorder<UserId, Result<Unit>> { Result.success(Unit) }
val encryptionService = FakeEncryptionService(
getUserIdentityResult = { Result.success(IdentityState.VerificationViolation) },
@ -342,7 +364,7 @@ class RoomMemberDetailsPresenterTest {
}
private fun createRoomMemberDetailsPresenter(
room: MatrixRoom,
room: JoinedRoom,
userProfilePresenterFactory: UserProfilePresenterFactory = UserProfilePresenterFactory {
Presenter {
aUserProfileState(

View file

@ -12,19 +12,19 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.RoomModeration
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aJoinedRoom
import io.element.android.features.roomdetails.impl.members.aRoomMember
import io.element.android.features.roomdetails.impl.members.aVictor
import io.element.android.libraries.architecture.AsyncAction
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.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.test.A_REASON
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.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.lambda.lambdaRecorder
@ -39,7 +39,7 @@ import org.junit.Test
class RoomMembersModerationPresenterTest {
@Test
fun `canDisplayModerationActions - when room is DM is false`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
isPublic = true,
activeMemberCount = 2,
canKickResult = { Result.success(true) },
@ -48,7 +48,7 @@ class RoomMembersModerationPresenterTest {
).apply {
givenRoomInfo(aRoomInfo(isDirect = true, activeMembersCount = 2))
}
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
presenter.test {
assertThat(awaitItem().canDisplayModerationActions).isFalse()
}
@ -56,13 +56,13 @@ class RoomMembersModerationPresenterTest {
@Test
fun `canDisplayModerationActions - when user can kick other users, FF is enabled and room is not a DM returns true`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
activeMemberCount = 10,
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
presenter.test {
skipItems(1)
assertThat(awaitItem().canDisplayModerationActions).isTrue()
@ -71,13 +71,13 @@ class RoomMembersModerationPresenterTest {
@Test
fun `canDisplayModerationActions - when user can ban other users, FF is enabled and room is not a DM returns true`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
activeMemberCount = 10,
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
presenter.test {
skipItems(1)
assertThat(awaitItem().canDisplayModerationActions).isTrue()
@ -86,13 +86,13 @@ class RoomMembersModerationPresenterTest {
@Test
fun `present - SelectRoomMember when the current user has permissions displays member actions`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
)
val selectedMember = aVictor()
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -112,14 +112,14 @@ class RoomMembersModerationPresenterTest {
@Test
fun `present - SelectRoomMember displays only view profile if selected member has same power level as the current user`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
sessionId = A_USER_ID,
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
)
val selectedMember = aRoomMember(A_USER_ID_2, powerLevel = 100L)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -138,12 +138,12 @@ class RoomMembersModerationPresenterTest {
@Test
fun `present - SelectRoomMember displays an unban confirmation dialog when the member is banned`() = runTest {
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -160,14 +160,14 @@ class RoomMembersModerationPresenterTest {
fun `present - Kick requires confirmation and then kicks the user`() = runTest {
val analyticsService = FakeAnalyticsService()
val kickUserResult = lambdaRecorder<UserId, String?, Result<Unit>> { _, _ -> Result.success(Unit) }
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
kickUserResult = kickUserResult,
)
val selectedMember = aVictor()
val presenter = createRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room, analyticsService = analyticsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -198,14 +198,14 @@ class RoomMembersModerationPresenterTest {
fun `present - BanUser requires confirmation and then bans the user`() = runTest {
val analyticsService = FakeAnalyticsService()
val banUserResult = lambdaRecorder<UserId, String?, Result<Unit>> { _, _ -> Result.success(Unit) }
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
banUserResult = banUserResult,
)
val selectedMember = aVictor()
val presenter = createRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room, analyticsService = analyticsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -237,15 +237,15 @@ class RoomMembersModerationPresenterTest {
fun `present - UnbanUser requires confirmation and then unbans the user`() = runTest {
val analyticsService = FakeAnalyticsService()
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
unBanUserResult = { _, _ -> Result.success(Unit) },
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(selectedMember)))
givenRoomMembersState(RoomMembersState.Ready(persistentListOf(selectedMember)))
}
val presenter = createRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room, analyticsService = analyticsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -269,12 +269,12 @@ class RoomMembersModerationPresenterTest {
@Test
fun `present - Reset removes the selected user and actions`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
userRoleResult = { Result.success(RoomMember.Role.USER) },
)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -291,7 +291,7 @@ class RoomMembersModerationPresenterTest {
@Test
fun `present - Reset resets any async actions`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canKickResult = { Result.success(true) },
canBanResult = { Result.success(true) },
kickUserResult = { _, _ -> Result.failure(Throwable("Eek")) },
@ -299,7 +299,7 @@ class RoomMembersModerationPresenterTest {
unBanUserResult = { _, _ -> Result.failure(Throwable("Eek")) },
userRoleResult = { Result.success(RoomMember.Role.USER) },
)
val presenter = createRoomMembersModerationPresenter(matrixRoom = room)
val presenter = createRoomMembersModerationPresenter(joinedRoom = room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -338,12 +338,12 @@ class RoomMembersModerationPresenterTest {
}
private fun TestScope.createRoomMembersModerationPresenter(
matrixRoom: FakeMatrixRoom = aMatrixRoom(),
joinedRoom: FakeJoinedRoom = aJoinedRoom(),
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
): RoomMembersModerationPresenter {
return RoomMembersModerationPresenter(
room = matrixRoom,
room = joinedRoom,
dispatchers = dispatchers,
analyticsService = analyticsService,
)

View file

@ -11,12 +11,12 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aJoinedRoom
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THROWABLE
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.FakeJoinedRoom
import io.element.android.tests.testutils.awaitLastSequentialItem
import io.element.android.tests.testutils.consumeItemsUntilPredicate
import kotlinx.coroutines.test.runTest
@ -158,7 +158,7 @@ class RoomNotificationSettingsPresenterTest {
val notificationService = FakeNotificationSettingsService().apply {
givenCanHomeServerPushEncryptedEventsToDeviceResult(Result.success(false))
}
val room = aMatrixRoom(notificationSettingsService = notificationService, isEncrypted = true)
val room = aJoinedRoom(notificationSettingsService = notificationService, isEncrypted = true)
val presenter = createRoomNotificationSettingsPresenter(notificationService, room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -172,7 +172,7 @@ class RoomNotificationSettingsPresenterTest {
val notificationService = FakeNotificationSettingsService().apply {
givenCanHomeServerPushEncryptedEventsToDeviceResult(Result.success(false))
}
val room = aMatrixRoom(notificationSettingsService = notificationService, isEncrypted = false)
val room = aJoinedRoom(notificationSettingsService = notificationService, isEncrypted = false)
val presenter = createRoomNotificationSettingsPresenter(notificationService, room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -183,7 +183,7 @@ class RoomNotificationSettingsPresenterTest {
private fun createRoomNotificationSettingsPresenter(
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
room: FakeMatrixRoom = aMatrixRoom(notificationSettingsService = notificationSettingsService),
room: FakeJoinedRoom = aJoinedRoom(notificationSettingsService = notificationSettingsService),
): RoomNotificationSettingsPresenter {
return RoomNotificationSettingsPresenter(
room = room,

View file

@ -15,7 +15,7 @@ import im.vector.app.features.analytics.plan.RoomModeration
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.room.RoomMember
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.defaultRoomPowerLevels
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.testCoroutineDispatchers
@ -59,7 +59,7 @@ class RolesAndPermissionPresenterTest {
fun `present - DemoteSelfTo changes own role to the specified one`() = runTest(StandardTestDispatcher()) {
val presenter = createRolesAndPermissionsPresenter(
dispatchers = testCoroutineDispatchers(),
room = FakeMatrixRoom(
room = FakeJoinedRoom(
updateUserRoleResult = { Result.success(Unit) }
),
)
@ -80,7 +80,7 @@ class RolesAndPermissionPresenterTest {
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `present - DemoteSelfTo can handle failures and clean them`() = runTest(StandardTestDispatcher()) {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.failure(Exception("Failed to update role")) }
)
val presenter = createRolesAndPermissionsPresenter(room = room, dispatchers = testCoroutineDispatchers())
@ -120,7 +120,7 @@ class RolesAndPermissionPresenterTest {
val analyticsService = FakeAnalyticsService()
val presenter = createRolesAndPermissionsPresenter(
analyticsService = analyticsService,
room = FakeMatrixRoom(
room = FakeJoinedRoom(
resetPowerLevelsResult = { Result.success(defaultRoomPowerLevels()) }
)
)
@ -153,7 +153,7 @@ class RolesAndPermissionPresenterTest {
}
private fun TestScope.createRolesAndPermissionsPresenter(
room: FakeMatrixRoom = FakeMatrixRoom(),
room: FakeJoinedRoom = FakeJoinedRoom(),
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
analyticsService: FakeAnalyticsService = FakeAnalyticsService()
): RolesAndPermissionsPresenter {

View file

@ -16,12 +16,13 @@ import io.element.android.features.roomdetails.impl.members.aRoomMemberList
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
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.user.MatrixUser
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.libraries.matrix.test.room.aRoomInfo
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.testCoroutineDispatchers
@ -54,8 +55,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - initial results are loaded automatically`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
}
val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -68,8 +69,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - ToggleSearchActive changes the value`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
}
val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -87,8 +88,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - QueryChanged produces new results`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
}
val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -113,8 +114,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - changes in the room members produce new results`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
}
val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -126,7 +127,7 @@ class ChangeRolesPresenterTest {
assertThat(initialResults?.moderators).hasSize(1)
assertThat(initialResults?.admins).hasSize(1)
room.givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList().take(1).toPersistentList()))
room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList().take(1).toPersistentList()))
skipItems(1)
val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
@ -139,8 +140,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - UserSelectionToggle adds and removes users from the selected user list`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(room = room)
@ -161,8 +162,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - hasPendingChanges is true when the initial selected users don't match the new ones`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(room = room)
@ -190,8 +191,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Exit will display success if no pending changes`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(room = room)
@ -210,8 +211,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - CancelExit will remove exit confirmation`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(room = room)
@ -236,8 +237,8 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Exit will display a confirmation dialog if there are pending changes, calling it again will actually exit`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(room = room)
@ -264,11 +265,11 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save will display a confirmation when adding admins`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.success(Unit) },
updateMembersResult = { Result.success(Unit) },
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room)
@ -285,14 +286,19 @@ class ChangeRolesPresenterTest {
assertThat(confirmingState.savingState).isEqualTo(AsyncAction.ConfirmingNoParams)
confirmingState.eventSink(ChangeRolesEvent.Save)
val loadingState = awaitItem()
assertThat(loadingState.savingState).isInstanceOf(AsyncAction.Loading::class.java)
skipItems(1)
assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Success(Unit))
}
}
@Test
fun `present - CancelSave will remove the confirmation dialog`() = runTest {
val room = FakeMatrixRoom().apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.ADMIN, room = room)
@ -317,11 +323,11 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save will just save the data for moderators`() = runTest {
val analyticsService = FakeAnalyticsService()
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.success(Unit) },
updateMembersResult = { Result.success(Unit) },
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
}
val presenter = createChangeRolesPresenter(
@ -339,6 +345,11 @@ class ChangeRolesPresenterTest {
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
awaitItem().eventSink(ChangeRolesEvent.Save)
val loadingState = awaitItem()
assertThat(loadingState.savingState).isInstanceOf(AsyncAction.Loading::class.java)
skipItems(1)
assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Success(Unit))
assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.ChangeMemberRole, RoomModeration.Role.Moderator))
}
@ -346,10 +357,10 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save can handle failures and ClearError clears them`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) }
).apply {
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.MODERATOR, room = room)
@ -363,6 +374,9 @@ class ChangeRolesPresenterTest {
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
awaitItem().eventSink(ChangeRolesEvent.Save)
val loadingState = awaitItem()
assertThat(loadingState.savingState).isInstanceOf(AsyncAction.Loading::class.java)
skipItems(1)
val failedState = awaitItem()
assertThat(failedState.savingState).isInstanceOf(AsyncAction.Failure::class.java)
@ -373,7 +387,7 @@ class ChangeRolesPresenterTest {
private fun TestScope.createChangeRolesPresenter(
role: RoomMember.Role = RoomMember.Role.ADMIN,
room: FakeMatrixRoom = FakeMatrixRoom(),
room: FakeJoinedRoom = FakeJoinedRoom(),
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
): ChangeRolesPresenter {

View file

@ -18,14 +18,15 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.RoomMember.Role.ADMIN
import io.element.android.libraries.matrix.api.room.RoomMember.Role.MODERATOR
import io.element.android.libraries.matrix.api.room.RoomMember.Role.USER
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
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.defaultRoomPowerLevels
import io.element.android.services.analytics.test.FakeAnalyticsService
import kotlinx.coroutines.test.runTest
import org.junit.Test
class ChangeRoomPermissionsPresenterTest {
class ChangeBaseRoomPermissionsPresenterTest {
@Test
fun `present - initial state`() = runTest {
val section = ChangeRoomPermissionsSection.RoomDetails
@ -132,7 +133,7 @@ class ChangeRoomPermissionsPresenterTest {
(items.last() as? Event.Item<ChangeRoomPermissionsState>)?.value?.run {
assertThat(currentPermissions).isEqualTo(
MatrixRoomPowerLevels(
RoomPowerLevels(
invite = MODERATOR.powerLevel,
kick = MODERATOR.powerLevel,
ban = MODERATOR.powerLevel,
@ -152,9 +153,9 @@ class ChangeRoomPermissionsPresenterTest {
val analyticsService = FakeAnalyticsService()
val presenter = createChangeRoomPermissionsPresenter(
analyticsService = analyticsService,
room = FakeMatrixRoom(
room = FakeJoinedRoom(
updatePowerLevelsResult = { Result.success(Unit) },
powerLevelsResult = { Result.success(defaultPermissions()) }
baseRoom = FakeBaseRoom(powerLevelsResult = { Result.success(defaultPermissions()) }),
),
)
moleculeFlow(RecompositionMode.Immediate) {
@ -200,8 +201,8 @@ class ChangeRoomPermissionsPresenterTest {
@Test
fun `present - Save will fail if there are not current permissions`() = runTest {
val room = FakeMatrixRoom(
powerLevelsResult = { Result.failure(IllegalStateException("Failed to load power levels")) }
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(powerLevelsResult = { Result.failure(IllegalStateException("Failed to load power levels")) }),
)
val presenter = createChangeRoomPermissionsPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -217,9 +218,9 @@ class ChangeRoomPermissionsPresenterTest {
@Test
fun `present - Save can handle failures and they can be cleared`() = runTest {
val room = FakeMatrixRoom(
powerLevelsResult = { Result.success(defaultPermissions()) },
val room = FakeJoinedRoom(
updatePowerLevelsResult = { Result.failure(IllegalStateException("Failed to update power levels")) },
baseRoom = FakeBaseRoom(powerLevelsResult = { Result.success(defaultPermissions()) }),
)
val presenter = createChangeRoomPermissionsPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) {
@ -285,8 +286,8 @@ class ChangeRoomPermissionsPresenterTest {
private fun createChangeRoomPermissionsPresenter(
section: ChangeRoomPermissionsSection = ChangeRoomPermissionsSection.RoomDetails,
room: FakeMatrixRoom = FakeMatrixRoom(
powerLevelsResult = { Result.success(defaultPermissions()) }
room: FakeJoinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(powerLevelsResult = { Result.success(defaultPermissions()) }),
),
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
) = ChangeRoomPermissionsPresenter(
@ -296,7 +297,7 @@ class ChangeRoomPermissionsPresenterTest {
)
private fun defaultPermissions() = defaultRoomPowerLevels().run {
MatrixRoomPowerLevels(
RoomPowerLevels(
invite = invite,
kick = kick,
ban = ban,

View file

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

View file

@ -10,13 +10,13 @@ package io.element.android.features.roomdetails.impl.securityandprivacy
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.room.MatrixRoom
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
import io.element.android.libraries.matrix.test.A_ROOM_ALIAS
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.room.aRoomInfo
import io.element.android.tests.testutils.lambda.assert
import io.element.android.tests.testutils.lambda.lambdaRecorder
@ -54,7 +54,8 @@ class SecurityAndPrivacyPresenterTest {
@Test
fun `present - room info change updates saved and edited settings`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canSendStateResult = { _, _ -> Result.success(true) },
initialRoomInfo = aRoomInfo(
joinRule = JoinRule.Public,
@ -62,6 +63,7 @@ class SecurityAndPrivacyPresenterTest {
canonicalAlias = A_ROOM_ALIAS,
)
)
)
val presenter = createSecurityAndPrivacyPresenter(room = room)
presenter.test {
skipItems(1)
@ -159,11 +161,13 @@ class SecurityAndPrivacyPresenterTest {
@Test
fun `present - room visibility loading and change`() = runTest {
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canSendStateResult = { _, _ -> Result.success(true) },
roomVisibilityResult = { Result.success(RoomVisibility.Private) },
getRoomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared)
)
)
val presenter = createSecurityAndPrivacyPresenter(room = room)
presenter.test {
skipItems(1)
@ -206,14 +210,16 @@ class SecurityAndPrivacyPresenterTest {
val updateJoinRuleLambda = lambdaRecorder<JoinRule, Result<Unit>> { Result.success(Unit) }
val updateRoomVisibilityLambda = lambdaRecorder<RoomVisibility, Result<Unit>> { Result.success(Unit) }
val updateRoomHistoryVisibilityLambda = lambdaRecorder<RoomHistoryVisibility, Result<Unit>> { Result.success(Unit) }
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canSendStateResult = { _, _ -> Result.success(true) },
getRoomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite, historyVisibility = RoomHistoryVisibility.Shared)
),
enableEncryptionResult = enableEncryptionLambda,
updateJoinRuleResult = updateJoinRuleLambda,
updateRoomVisibilityResult = updateRoomVisibilityLambda,
updateRoomHistoryVisibilityResult = updateRoomHistoryVisibilityLambda,
roomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite, historyVisibility = RoomHistoryVisibility.Shared)
)
val presenter = createSecurityAndPrivacyPresenter(room = room)
presenter.test {
@ -271,14 +277,16 @@ class SecurityAndPrivacyPresenterTest {
Result.failure(Exception("Failed to update room visibility"))
}
val updateRoomHistoryVisibilityLambda = lambdaRecorder<RoomHistoryVisibility, Result<Unit>> { Result.success(Unit) }
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canSendStateResult = { _, _ -> Result.success(true) },
getRoomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private)
),
enableEncryptionResult = enableEncryptionLambda,
updateJoinRuleResult = updateJoinRuleLambda,
updateRoomVisibilityResult = updateRoomVisibilityLambda,
updateRoomHistoryVisibilityResult = updateRoomHistoryVisibilityLambda,
roomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private)
)
val presenter = createSecurityAndPrivacyPresenter(room = room)
presenter.test {
@ -329,10 +337,12 @@ class SecurityAndPrivacyPresenterTest {
private fun createSecurityAndPrivacyPresenter(
serverName: String = "matrix.org",
room: MatrixRoom = FakeMatrixRoom(
canSendStateResult = { _, _ -> Result.success(true) },
roomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private)
room: FakeJoinedRoom = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canSendStateResult = { _, _ -> Result.success(true) },
getRoomVisibilityResult = { Result.success(RoomVisibility.Private) },
initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private)
),
),
navigator: SecurityAndPrivacyNavigator = FakeSecurityAndPrivacyNavigator(),
): SecurityAndPrivacyPresenter {

View file

@ -8,17 +8,17 @@
package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdetails.impl.aMatrixRoom
import io.element.android.features.roomdetails.impl.aJoinedRoom
import io.element.android.features.roomdetails.impl.securityandprivacy.FakeSecurityAndPrivacyNavigator
import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyNavigator
import io.element.android.libraries.architecture.AsyncAction
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.JoinedRoom
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
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.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.alias.FakeRoomAliasHelper
import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity
import io.element.android.tests.testutils.lambda.assert
@ -29,11 +29,11 @@ import kotlinx.coroutines.test.runTest
import org.junit.Test
import java.util.Optional
class EditRoomAddressPresenterTest {
class EditBaseRoomAddressPresenterTest {
@Test
fun `present - initial state no address`() = runTest {
val presenter = createEditRoomAddressPresenter(
room = aMatrixRoom(displayName = "")
room = aJoinedRoom(displayName = "")
)
presenter.test {
with(awaitItem()) {
@ -48,7 +48,7 @@ class EditRoomAddressPresenterTest {
@Test
fun `present - initial state address matching own homeserver`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
canonicalAlias = RoomAlias("#canonical:matrix.org"),
)
val presenter = createEditRoomAddressPresenter(room = room)
@ -65,7 +65,7 @@ class EditRoomAddressPresenterTest {
@Test
fun `present - initial state address not matching own homeserver`() = runTest {
val room = aMatrixRoom(
val room = aJoinedRoom(
displayName = "",
canonicalAlias = RoomAlias("#canonical:notmatrix.org"),
)
@ -148,7 +148,7 @@ class EditRoomAddressPresenterTest {
val navigator = FakeSecurityAndPrivacyNavigator(
closeEditRoomAddressLambda = closeEditAddressLambda
)
val room = FakeMatrixRoom(
val room = FakeJoinedRoom(
updateCanonicalAliasResult = updateCanonicalAliasResult,
publishRoomAliasInRoomDirectoryResult = publishAliasInRoomDirectoryResult
)
@ -194,7 +194,7 @@ class EditRoomAddressPresenterTest {
val navigator = FakeSecurityAndPrivacyNavigator(closeEditRoomAddressLambda = closeEditAddressLambda)
val canonicalAlias = RoomAlias("#canonical:matrix.org")
val room = aMatrixRoom(
val room = aJoinedRoom(
canonicalAlias = canonicalAlias,
updateCanonicalAliasResult = updateCanonicalAliasResult,
publishRoomAliasInRoomDirectoryResult = publishAliasInRoomDirectoryResult,
@ -244,7 +244,7 @@ class EditRoomAddressPresenterTest {
val navigator = FakeSecurityAndPrivacyNavigator(closeEditRoomAddressLambda = closeEditAddressLambda)
val canonicalAlias = RoomAlias("#canonical:notmatrix.org")
val room = aMatrixRoom(
val room = aJoinedRoom(
canonicalAlias = canonicalAlias,
updateCanonicalAliasResult = updateCanonicalAliasResult,
publishRoomAliasInRoomDirectoryResult = publishAliasInRoomDirectoryResult,
@ -343,7 +343,7 @@ class EditRoomAddressPresenterTest {
private fun createEditRoomAddressPresenter(
client: FakeMatrixClient = createMatrixClient(),
room: MatrixRoom = FakeMatrixRoom(),
room: JoinedRoom = FakeJoinedRoom(),
navigator: SecurityAndPrivacyNavigator = FakeSecurityAndPrivacyNavigator(),
roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper()
): EditRoomAddressPresenter {

View file

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