fix: edit moderators not working

This commit is contained in:
ganfra
2025-12-15 15:33:03 +01:00
parent 5bb71db3b1
commit df77b61df6
2 changed files with 48 additions and 36 deletions

View File

@@ -44,7 +44,7 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@@ -81,7 +81,7 @@ class ChangeRolesPresenter(
val owners = if (role == RoomMember.Role.Admin) {
room.usersWithRole { role -> role is RoomMember.Role.Owner }
} else {
emptyFlow()
flowOf(persistentListOf())
}
combine(
owners,

View File

@@ -256,44 +256,48 @@ class ChangeRolesPresenterTest {
@Test
fun `present - UserSelectionToggle adds and removes users from the selected user list`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(room = room)
val userMember = roomMemberList.first { it.role == RoomMember.Role.User }
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.selectedUsers).hasSize(1)
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
assertThat(awaitItem().selectedUsers).hasSize(2)
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
assertThat(awaitItem().selectedUsers).hasSize(1)
}
}
@Test
fun `present - hasPendingChanges is true when the initial selected users don't match the new ones`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(room = room)
val userMember = roomMemberList.first { it.role == RoomMember.Role.User }
presenter.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.hasPendingChanges).isFalse()
assertThat(initialState.selectedUsers).hasSize(1)
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
with(awaitItem()) {
assertThat(selectedUsers).hasSize(2)
assertThat(hasPendingChanges).isTrue()
}
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
with(awaitItem()) {
assertThat(selectedUsers).hasSize(1)
assertThat(hasPendingChanges).isFalse()
@@ -303,9 +307,10 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Exit will display success false if no pending changes`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(room = room)
presenter.test {
@@ -321,9 +326,10 @@ class ChangeRolesPresenterTest {
@Test
fun `present - CloseDialog will remove exit confirmation`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(room = room)
presenter.test {
@@ -345,9 +351,10 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Exit will display a confirmation dialog if there are pending changes, calling it again will actually exit`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(room = room)
presenter.test {
@@ -371,12 +378,13 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save will display a confirmation when adding admins`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.success(Unit) },
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room)
presenter.test {
@@ -395,9 +403,10 @@ class ChangeRolesPresenterTest {
@Test
fun `present - CloseDialog will remove the confirmation dialog`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom().apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room)
presenter.test {
@@ -419,25 +428,27 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save will just save the data for moderators`() = runTest {
val analyticsService = FakeAnalyticsService()
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.success(Unit) },
baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }),
).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Moderator)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(
role = RoomMember.Role.Moderator,
room = room,
analyticsService = analyticsService
)
val userMember = roomMemberList.first { it.role == RoomMember.Role.User }
presenter.test {
skipItems(1)
skipItems(2)
val initialState = awaitItem()
assertThat(initialState.selectedUsers).isEmpty()
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
assertThat(initialState.selectedUsers).hasSize(1)
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
awaitItem().also {
assertThat(it.selectedUsers).hasSize(1)
assertThat(it.selectedUsers).hasSize(2)
it.eventSink(ChangeRolesEvent.Save)
}
assertThat(awaitItem().savingState).isInstanceOf(AsyncAction.Loading::class.java)
@@ -516,20 +527,22 @@ class ChangeRolesPresenterTest {
@Test
fun `present - Save can handle failures and CloseDialog clears them`() = runTest {
val roomMemberList = aRoomMemberList()
val room = FakeJoinedRoom(
updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) }
).apply {
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(role = RoomMember.Role.Moderator, userId = A_USER_ID)))
givenRoomMembersState(RoomMembersState.Ready(roomMemberList))
givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList)))
}
val presenter = createChangeRolesPresenter(role = RoomMember.Role.Moderator, room = room)
val userMember = roomMemberList.first { it.role == RoomMember.Role.User }
presenter.test {
skipItems(1)
skipItems(2)
val initialState = awaitItem()
assertThat(initialState.selectedUsers).isEmpty()
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2)))
assertThat(initialState.selectedUsers).hasSize(1)
initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser()))
awaitItem().also {
assertThat(it.selectedUsers).hasSize(1)
assertThat(it.selectedUsers).hasSize(2)
it.eventSink(ChangeRolesEvent.Save)
}
val loadingState = awaitItem()
@@ -553,13 +566,12 @@ class ChangeRolesPresenterTest {
}
}
private fun roomPowerLevelsWithRole(
role: RoomMember.Role,
userId: UserId = A_USER_ID,
private fun roomPowerLevelsFromRoomMemberList(
roomMemberList: List<RoomMember>,
): RoomPowerLevels {
return RoomPowerLevels(
values = defaultRoomPowerLevelValues(),
users = persistentMapOf(userId to role.powerLevel)
users = roomMemberList.associate { it.userId to it.role.powerLevel }.toImmutableMap()
)
}