misc(power level) : update tests following api change

This commit is contained in:
ganfra 2025-12-09 20:50:31 +01:00
parent 541a1d29bd
commit d26f21a53b
25 changed files with 475 additions and 637 deletions

View file

@ -18,7 +18,6 @@ import io.element.android.libraries.matrix.api.room.StateEventType
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import timber.log.Timber
/**
* Provides information about the permissions of users in a room.
@ -150,7 +149,15 @@ fun <T> Result<RoomPermissions>.use(default: T, block: (RoomPermissions) -> T):
fun <T> BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flow<T> {
return roomInfoFlow
.map { info -> info.roomPowerLevels }
.map { info ->
// If the user is a privileged creator, we return a constant hashcode to avoid recomputing permissions
// each time the power levels change (as they have all permissions).
if (info.privilegedCreatorRole && info.creators.contains(sessionId)) {
Long.MAX_VALUE
} else {
info.roomPowerLevels?.hashCode() ?: 0L
}
}
.distinctUntilChanged()
.map {
roomPermissions().use(default, block)
@ -160,7 +167,6 @@ fun <T> BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flo
@Composable
fun <T> BaseRoom.permissionsAsState(default: T, block: (RoomPermissions) -> T): State<T> {
return remember(this, default, block) {
Timber.d("Computing permissionsAsState for room $roomId with default=$default")
permissionsFlow(default, block)
}.collectAsState(default)
}

View file

@ -18,12 +18,10 @@ import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues

View file

@ -15,11 +15,9 @@ import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.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.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
@ -42,6 +40,7 @@ class FakeBaseRoom(
override val sessionId: SessionId = A_SESSION_ID,
override val roomId: RoomId = A_ROOM_ID,
initialRoomInfo: RoomInfo = aRoomInfo(),
private val roomPermissions: RoomPermissions = FakeRoomPermissions(),
override val roomCoroutineScope: CoroutineScope = TestScope(),
private var roomPermalinkResult: () -> Result<String> = { lambdaError() },
private var eventPermalinkResult: (EventId) -> Result<String> = { lambdaError() },
@ -50,17 +49,6 @@ class FakeBaseRoom(
private val userRoleResult: () -> Result<RoomMember.Role> = { lambdaError() },
private val getUpdatedMemberResult: (UserId) -> Result<RoomMember> = { lambdaError() },
private val joinRoomResult: () -> Result<Unit> = { lambdaError() },
private val roomPermissionsResult: () -> Result<RoomPermissions> = { Result.success(FakeRoomPermissions()) },
private val canInviteResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canKickResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canBanResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canRedactOwnResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canRedactOtherResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canSendStateResult: (UserId, StateEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
private val canUserSendMessageResult: (UserId, MessageEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
private val canUserTriggerRoomNotificationResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canUserJoinCallResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val canUserPinUnpinResult: (UserId) -> Result<Boolean> = { lambdaError() },
private val setIsFavoriteResult: (Boolean) -> Result<Unit> = { lambdaError() },
private val markAsReadResult: (ReceiptType) -> Result<Unit> = { Result.success(Unit) },
private val powerLevelsResult: () -> Result<RoomPowerLevelsValues> = { lambdaError() },
@ -133,7 +121,7 @@ class FakeBaseRoom(
}
override suspend fun roomPermissions(): Result<RoomPermissions> {
return roomPermissionsResult()
return Result.success(roomPermissions)
}
override suspend fun getPermalink(): Result<String> {
@ -160,46 +148,6 @@ class FakeBaseRoom(
return forgetResult()
}
override suspend fun canUserBan(userId: UserId): Result<Boolean> {
return canBanResult(userId)
}
override suspend fun canUserKick(userId: UserId): Result<Boolean> {
return canKickResult(userId)
}
override suspend fun canUserInvite(userId: UserId): Result<Boolean> {
return canInviteResult(userId)
}
override suspend fun canUserRedactOwn(userId: UserId): Result<Boolean> {
return canRedactOwnResult(userId)
}
override suspend fun canUserRedactOther(userId: UserId): Result<Boolean> {
return canRedactOtherResult(userId)
}
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> {
return canSendStateResult(userId, type)
}
override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result<Boolean> {
return canUserSendMessageResult(userId, type)
}
override suspend fun canUserTriggerRoomNotification(userId: UserId): Result<Boolean> {
return canUserTriggerRoomNotificationResult(userId)
}
override suspend fun canUserJoinCall(userId: UserId): Result<Boolean> {
return canUserJoinCallResult(userId)
}
override suspend fun canUserPinUnpin(userId: UserId): Result<Boolean> {
return canUserPinUnpinResult(userId)
}
override suspend fun setIsFavorite(isFavorite: Boolean): Result<Unit> {
return setIsFavoriteResult(isFavorite)
}

View file

@ -13,44 +13,44 @@ import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
data class FakeRoomPermissions(
val ownerCanBan: Boolean = false,
val ownerCanInvite: Boolean = false,
val ownerCanKick: Boolean = false,
val ownerCanPinUnpin: Boolean = false,
val ownerCanRedactOther: Boolean = false,
val ownerCanRedactOwn: Boolean = false,
val ownerCanTriggerRoomNotification: Boolean = false,
val ownerCanSendMessage: (MessageEventType) -> Boolean = { false },
val ownerCanSendState: (StateEventType) -> Boolean = { false },
val userCanBan: (UserId) -> Boolean = { false },
val userCanInvite: (UserId) -> Boolean = { false },
val userCanKick: (UserId) -> Boolean = { false },
val userCanPinUnpin: (UserId) -> Boolean = { false },
val userCanRedactOther: (UserId) -> Boolean = { false },
val userCanRedactOwn: (UserId) -> Boolean = { false },
val userCanTriggerRoomNotification: (UserId) -> Boolean = { false },
val userCanSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false },
val userCanSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false },
private val canBan: Boolean = false,
private val canInvite: Boolean = false,
private val canKick: Boolean = false,
private val canPinUnpin: Boolean = false,
private val canRedactOther: Boolean = false,
private val canRedactOwn: Boolean = false,
private val canTriggerRoomNotification: Boolean = false,
private val canSendMessage: (MessageEventType) -> Boolean = { false },
private val canSendState: (StateEventType) -> Boolean = { false },
private val canUserBan: (UserId) -> Boolean = { false },
private val canUserInvite: (UserId) -> Boolean = { false },
private val canUserKick: (UserId) -> Boolean = { false },
private val canUserPinUnpin: (UserId) -> Boolean = { false },
private val canUserRedactOther: (UserId) -> Boolean = { false },
private val canUserRedactOwn: (UserId) -> Boolean = { false },
private val canUserTriggerRoomNotification: (UserId) -> Boolean = { false },
private val canUserSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false },
private val canUserSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false },
) : RoomPermissions {
override fun canOwnUserBan(): Boolean = canBan
override fun canOwnUserInvite(): Boolean = canInvite
override fun canOwnUserKick(): Boolean = canKick
override fun canOwnUserPinUnpin(): Boolean = canPinUnpin
override fun canOwnUserRedactOther(): Boolean = canRedactOther
override fun canOwnUserRedactOwn(): Boolean = canRedactOwn
override fun canOwnUserSendMessage(message: MessageEventType): Boolean = canSendMessage(message)
override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = canSendState(stateEvent)
override fun canOwnUserBan(): Boolean = ownerCanBan
override fun canOwnUserInvite(): Boolean = ownerCanInvite
override fun canOwnUserKick(): Boolean = ownerCanKick
override fun canOwnUserPinUnpin(): Boolean = ownerCanPinUnpin
override fun canOwnUserRedactOther(): Boolean = ownerCanRedactOther
override fun canOwnUserRedactOwn(): Boolean = ownerCanRedactOwn
override fun canOwnUserSendMessage(message: MessageEventType): Boolean = ownerCanSendMessage(message)
override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = ownerCanSendState(stateEvent)
override fun canOwnUserTriggerRoomNotification(): Boolean = ownerCanTriggerRoomNotification
override fun canUserBan(userId: UserId): Boolean = userCanBan(userId)
override fun canUserInvite(userId: UserId): Boolean = userCanInvite(userId)
override fun canUserKick(userId: UserId): Boolean = userCanKick(userId)
override fun canUserPinUnpin(userId: UserId): Boolean = userCanPinUnpin(userId)
override fun canUserRedactOther(userId: UserId): Boolean = userCanRedactOther(userId)
override fun canUserRedactOwn(userId: UserId): Boolean = userCanRedactOwn(userId)
override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = userCanSendMessage(userId, message)
override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = userCanSendState(userId, stateEvent)
override fun canUserTriggerRoomNotification(userId: UserId): Boolean = userCanTriggerRoomNotification(userId)
override fun canOwnUserTriggerRoomNotification(): Boolean = canTriggerRoomNotification
override fun canUserBan(userId: UserId): Boolean = canUserBan(userId)
override fun canUserInvite(userId: UserId): Boolean = canUserInvite(userId)
override fun canUserKick(userId: UserId): Boolean = canUserKick(userId)
override fun canUserPinUnpin(userId: UserId): Boolean = canUserPinUnpin(userId)
override fun canUserRedactOther(userId: UserId): Boolean = canUserRedactOther(userId)
override fun canUserRedactOwn(userId: UserId): Boolean = canUserRedactOwn(userId)
override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = canUserSendMessage(userId, message)
override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = canUserSendState(userId, stateEvent)
override fun canUserTriggerRoomNotification(userId: UserId): Boolean = canUserTriggerRoomNotification(userId)
override fun close() {
// no-op for the fake

View file

@ -207,7 +207,6 @@ class MediaGalleryPresenter(
CommonStrings.error_unknown
}
}
}
private fun GroupedMediaItems?.find(eventId: EventId?): MediaItem.Event? {

View file

@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediaviewer.impl.datasource.FakeMediaGalleryDataSource
import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource
@ -109,7 +110,9 @@ class MediaGalleryPresenterTest {
baseRoom = FakeBaseRoom(
sessionId = A_USER_ID,
initialRoomInfo = aRoomInfo(name = A_ROOM_NAME),
canRedactOwnResult = { Result.success(canDeleteOwn) }
roomPermissions = FakeRoomPermissions(
canRedactOwn = canDeleteOwn
),
),
)
)
@ -153,7 +156,9 @@ class MediaGalleryPresenterTest {
baseRoom = FakeBaseRoom(
sessionId = A_USER_ID,
initialRoomInfo = aRoomInfo(name = A_ROOM_NAME),
canRedactOtherResult = { Result.success(canDeleteOther) },
roomPermissions = FakeRoomPermissions(
canRedactOther = canDeleteOther
),
),
createTimelineResult = { Result.success(FakeTimeline()) }
)
@ -355,7 +360,9 @@ class MediaGalleryPresenterTest {
room = FakeJoinedRoom(
createTimelineResult = { Result.success(FakeTimeline()) },
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
),
navigator = navigator,
@ -386,7 +393,9 @@ class MediaGalleryPresenterTest {
room = FakeJoinedRoom(
createTimelineResult = { Result.success(FakeTimeline()) },
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
),
navigator = navigator,

View file

@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader
import io.element.android.libraries.matrix.test.media.aMediaSource
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.powerlevels.FakeRoomPermissions
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
@ -83,7 +84,9 @@ class MediaViewerPresenterTest {
localMediaFactory = localMediaFactory,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
)
)
)
@ -104,7 +107,9 @@ class MediaViewerPresenterTest {
canShowInfo = false,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
)
)
)
@ -125,7 +130,9 @@ class MediaViewerPresenterTest {
eventId = AN_EVENT_ID,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
)
)
)
@ -147,7 +154,9 @@ class MediaViewerPresenterTest {
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
sessionId = A_SESSION_ID_2,
canRedactOtherResult = { Result.success(false) },
roomPermissions = FakeRoomPermissions(
canRedactOther = false
),
)
)
)
@ -236,7 +245,9 @@ class MediaViewerPresenterTest {
mediaGalleryDataSource = mediaGalleryDataSource,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(
canRedactOwnResult = { Result.success(true) },
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
)
)
)
@ -460,7 +471,11 @@ class MediaViewerPresenterTest {
localMediaFactory = localMediaFactory,
room = FakeJoinedRoom(
liveTimeline = timeline,
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
baseRoom = FakeBaseRoom(
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
),
mediaGalleryDataSource = mediaGalleryDataSource,
mediaViewerNavigator = FakeMediaViewerNavigator(
@ -769,7 +784,11 @@ class MediaViewerPresenterTest {
localMediaFactory = localMediaFactory,
mediaViewerNavigator = navigator,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
baseRoom = FakeBaseRoom(
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
)
)
presenter.test {
@ -794,7 +813,11 @@ class MediaViewerPresenterTest {
localMediaFactory = localMediaFactory,
mediaViewerNavigator = navigator,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
baseRoom = FakeBaseRoom(
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
),
)
presenter.test {
@ -821,7 +844,11 @@ class MediaViewerPresenterTest {
localMediaFactory = localMediaFactory,
mediaViewerNavigator = navigator,
room = FakeJoinedRoom(
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
baseRoom = FakeBaseRoom(
roomPermissions = FakeRoomPermissions(
canRedactOwn = true
),
),
),
)
presenter.test {