From 0b6c5964a1dd2f0fd89e0ae9de7283d2a052d37b Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 19 May 2025 22:16:17 +0200 Subject: [PATCH] change (member moderation) : fix all existing tests --- .../messages/impl/MessagesPresenterTest.kt | 5 + .../messages/impl/MessagesViewTest.kt | 55 +-- .../pinned/list/PinnedMessagesListViewTest.kt | 3 +- .../impl/timeline/TimelineViewTest.kt | 3 +- .../impl/members/RoomMemberListNode.kt | 3 +- .../impl/members/RoomMemberListPresenter.kt | 11 +- .../members/RoomMemberListPresenterTest.kt | 74 ++-- .../RoomMembersModerationPresenterTest.kt | 351 ------------------ .../RoomMembersModerationViewTest.kt | 274 -------------- .../impl/InternalRoomMemberModerationState.kt | 3 - ...ernalRoomMemberModerationStateProvider.kt} | 6 +- .../impl/RoomMemberModerationView.kt | 2 +- 12 files changed, 64 insertions(+), 726 deletions(-) delete mode 100644 features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt delete mode 100644 features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt rename features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/{RoomMemberModerationStateProvider.kt => InternalRoomMemberModerationStateProvider.kt} (91%) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 2a3c34feee..c21431e2ea 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -35,6 +35,7 @@ import io.element.android.features.messages.impl.timeline.protection.aTimelinePr import io.element.android.features.messages.impl.voicemessages.composer.aVoiceMessageComposerState import io.element.android.features.messages.test.timeline.FakeHtmlConverterProvider import io.element.android.features.roomcall.api.aStandByCallState +import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter @@ -1182,6 +1183,9 @@ class MessagesPresenterTest { textEditorState = aTextEditorStateMarkdown(initialText = "", initialFocus = false) ) }, + roomMemberModerationPresenter: Presenter = Presenter { + aRoomMemberModerationState() + }, encryptionService: FakeEncryptionService = FakeEncryptionService(), actionListEventSink: (ActionListEvents) -> Unit = {}, ): MessagesPresenter { @@ -1199,6 +1203,7 @@ class MessagesPresenterTest { linkPresenter = { aLinkState() }, pinnedMessagesBannerPresenter = { aLoadedPinnedMessagesBannerState() }, roomCallStatePresenter = { aStandByCallState() }, + roomMemberModerationPresenter = roomMemberModerationPresenter, syncService = FakeSyncService(), snackbarDispatcher = SnackbarDispatcher(), navigator = navigator, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index 5080013d27..b0d22ad4c1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -53,6 +53,9 @@ import io.element.android.features.messages.impl.timeline.components.receipt.bot import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl +import io.element.android.libraries.matrix.api.timeline.item.event.getDisplayName +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.ui.strings.CommonStrings @@ -310,40 +313,42 @@ class MessagesViewTest { @Test @Config(qualifiers = "h1024dp") - fun `clicking on the avatar of the sender of an Event invoke expected callback`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + fun `clicking on the avatar of the sender of an Event emits the expected event`() { + val eventsRecorder = EventsRecorder() val state = aMessagesState( eventSink = eventsRecorder ) - val timelineItem = state.timelineState.timelineItems.first() - ensureCalledOnceWithParam( - param = (timelineItem as TimelineItem.Event).senderId - ) { callback -> - rule.setMessagesView( - state = state, - onUserDataClick = callback, + val timelineEvent = state.timelineState.timelineItems.filterIsInstance().first() + rule.setMessagesView(state = state) + rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick() + eventsRecorder.assertSingle( + MessagesEvents.OnUserClicked( + MatrixUser( + userId = timelineEvent.senderId, + displayName = timelineEvent.senderProfile.getDisplayName(), + avatarUrl = timelineEvent.senderProfile.getAvatarUrl() + ) ) - rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick() - } + ) } @Test @Config(qualifiers = "h1024dp") - fun `clicking on the display name of the sender of an Event invoke expected callback`() { - val eventsRecorder = EventsRecorder(expectEvents = false) - val state = aMessagesState( - eventSink = eventsRecorder - ) - val timelineItem = state.timelineState.timelineItems.first() - ensureCalledOnceWithParam( - param = (timelineItem as TimelineItem.Event).senderId - ) { callback -> - rule.setMessagesView( - state = state, - onUserDataClick = callback, + fun `clicking on the display name of the sender of an Event emits expected event`() { + val eventsRecorder = EventsRecorder() + val state = aMessagesState(eventSink = eventsRecorder) + val timelineEvent = state.timelineState.timelineItems.filterIsInstance().first() + rule.setMessagesView(state = state) + rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick() + eventsRecorder.assertSingle( + MessagesEvents.OnUserClicked( + MatrixUser( + userId = timelineEvent.senderId, + displayName = timelineEvent.senderProfile.getDisplayName(), + avatarUrl = timelineEvent.senderProfile.getAvatarUrl() + ) ) - rule.onNodeWithTag(TestTags.timelineItemSenderName.value, useUnmergedTree = true).performClick() - } + ) } @Test diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListViewTest.kt index 35ac685303..0200da24e2 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListViewTest.kt @@ -22,6 +22,7 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemList import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemFileContent import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EventsRecorder @@ -99,7 +100,7 @@ private fun AndroidComposeTestRule.setPinne state: PinnedMessagesListState, onBackClick: () -> Unit = EnsureNeverCalled(), onEventClick: (event: TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), - onUserDataClick: (UserId) -> Unit = EnsureNeverCalledWithParam(), + onUserDataClick: (MatrixUser) -> Unit = EnsureNeverCalledWithParam(), onLinkClick: (Link) -> Unit = EnsureNeverCalledWithParam(), onLinkLongClick: (Link) -> Unit = EnsureNeverCalledWithParam(), ) { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt index 208c0ab140..178523cf64 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield +import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EnsureNeverCalledWithParam @@ -175,7 +176,7 @@ class TimelineViewTest { private fun AndroidComposeTestRule.setTimelineView( state: TimelineState, timelineProtectionState: TimelineProtectionState = aTimelineProtectionState(), - onUserDataClick: (UserId) -> Unit = EnsureNeverCalledWithParam(), + onUserDataClick: (MatrixUser) -> Unit = EnsureNeverCalledWithParam(), onLinkClick: (Link) -> Unit = EnsureNeverCalledWithParam(), onMessageClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), onMessageLongClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt index cf2f89c41e..3d7fecd0ae 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt @@ -29,7 +29,7 @@ import io.element.android.services.analytics.api.AnalyticsService class RoomMemberListNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenterFactory: RoomMemberListPresenter.Factory, + private val presenter: RoomMemberListPresenter, private val analyticsService: AnalyticsService, private val roomMemberModerationRenderer: RoomMemberModerationRenderer, ) : Node(buildContext, plugins = plugins), RoomMemberListNavigator { @@ -39,7 +39,6 @@ class RoomMemberListNode @AssistedInject constructor( } private val callbacks = plugins() - private val presenter = presenterFactory.create(this) init { lifecycle.subscribe( diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index c637f338cb..4de57787c8 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -16,8 +16,6 @@ import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents @@ -53,12 +51,7 @@ class RoomMemberListPresenter @AssistedInject constructor( private val coroutineDispatchers: CoroutineDispatchers, private val roomMembersModerationPresenter: Presenter, private val encryptionService: EncryptionService, - @Assisted private val navigator: RoomMemberListNavigator, ) : Presenter { - @AssistedFactory - interface Factory { - fun create(navigator: RoomMemberListNavigator): RoomMemberListPresenter - } @Composable override fun present(): RoomMemberListState { @@ -168,10 +161,8 @@ class RoomMemberListPresenter @AssistedInject constructor( is RoomMemberListEvents.RoomMemberSelected -> if (event.roomMember.membership == RoomMembershipState.BAN) { roomModerationState.eventSink(RoomMemberModerationEvents.ProcessAction(ModerationAction.UnbanUser, event.roomMember.toMatrixUser())) - } else if (!isDm.value && (roomModerationState.canBan || roomModerationState.canKick)) { - roomModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.roomMember.toMatrixUser())) } else { - navigator.openRoomMemberDetails(event.roomMember.userId) + roomModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.roomMember.toMatrixUser())) } } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 82e5a910dc..52173f43ff 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -11,9 +11,8 @@ 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.members.moderation.RoomMembersModerationEvents -import io.element.android.features.roomdetails.impl.members.moderation.RoomMembersModerationState -import io.element.android.features.roomdetails.impl.members.moderation.aRoomMembersModerationState +import io.element.android.features.roommembermoderation.api.RoomMemberModerationState +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 @@ -24,7 +23,6 @@ import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService 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 import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -42,12 +40,12 @@ class RoomMemberListPresenterTest { fun `member loading is done automatically on start, but is async`() = runTest { 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)) - } + 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(joinedRoom = room) moleculeFlow(RecompositionMode.Immediate) { @@ -97,9 +95,9 @@ class RoomMemberListPresenterTest { val presenter = createPresenter( joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) + updateMembersResult = { Result.success(Unit) }, + canInviteResult = { Result.success(true) } + ) ) ) moleculeFlow(RecompositionMode.Immediate) { @@ -204,12 +202,12 @@ class RoomMemberListPresenterTest { } @Test - fun `present - RoomMemberSelected by default opens the room member details through the navigator`() = runTest { - val navigator = FakeRoomMemberListNavigator() - val roomMembersModerationStateLambda = { aRoomMembersModerationState(canDisplayModerationActions = false) } + fun `present - RoomMemberSelected will open the moderation options when target user is not banned`() = runTest { + val roomMemberModerationPresenter= Presenter { + aRoomMemberModerationState(canBan = true, canKick = true) + } val presenter = createPresenter( - roomMembersModerationStateLambda = roomMembersModerationStateLambda, - navigator = navigator, + roomMemberModerationPresenter = roomMemberModerationPresenter, joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( updateMembersResult = { Result.success(Unit) }, @@ -222,36 +220,6 @@ class RoomMemberListPresenterTest { }.test { skipItems(1) awaitItem().eventSink(RoomMemberListEvents.RoomMemberSelected(aVictor())) - assertThat(navigator.openRoomMemberDetailsCallCount).isEqualTo(1) - } - } - - @Test - fun `present - RoomMemberSelected will open the moderation options if the current user can use them`() = runTest { - val navigator = FakeRoomMemberListNavigator() - val eventsRecorder = EventsRecorder() - val roomMembersModerationStateLambda = { - aRoomMembersModerationState( - canDisplayModerationActions = true, - eventSink = eventsRecorder, - ) - } - val presenter = createPresenter( - roomMembersModerationStateLambda = roomMembersModerationStateLambda, - navigator = navigator, - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) - ) - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMemberListEvents.RoomMemberSelected(aVictor())) - eventsRecorder.assertSingle(RoomMembersModerationEvents.SelectRoomMember(aVictor())) } } } @@ -277,19 +245,19 @@ private fun TestScope.createDataSource( private fun TestScope.createPresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true), joinedRoom: JoinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( + baseRoom = FakeBaseRoom( updateMembersResult = { Result.success(Unit) } ) ), roomMemberListDataSource: RoomMemberListDataSource = createDataSource(coroutineDispatchers = coroutineDispatchers), - roomMembersModerationStateLambda: () -> RoomMembersModerationState = { aRoomMembersModerationState() }, encryptedService: FakeEncryptionService = FakeEncryptionService(), - navigator: RoomMemberListNavigator = object : RoomMemberListNavigator {} + roomMemberModerationPresenter: Presenter = Presenter { + aRoomMemberModerationState() + }, ) = RoomMemberListPresenter( room = joinedRoom, roomMemberListDataSource = roomMemberListDataSource, coroutineDispatchers = coroutineDispatchers, - roomMembersModerationPresenter = { roomMembersModerationStateLambda() }, + roomMembersModerationPresenter = roomMemberModerationPresenter, encryptionService = encryptedService, - navigator = navigator, ) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt deleted file mode 100644 index 00239fdf82..0000000000 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.roomdetails.impl.members.moderation - -import app.cash.molecule.RecompositionMode -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.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.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.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 -import io.element.android.tests.testutils.lambda.value -import io.element.android.tests.testutils.test -import io.element.android.tests.testutils.testCoroutineDispatchers -import kotlinx.collections.immutable.persistentListOf -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.runTest -import org.junit.Test - -class RoomMembersModerationPresenterTest { - @Test - fun `canDisplayModerationActions - when room is DM is false`() = runTest { - val room = aJoinedRoom( - isPublic = true, - activeMemberCount = 2, - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - ).apply { - givenRoomInfo(aRoomInfo(isDirect = true, activeMembersCount = 2)) - } - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - presenter.test { - assertThat(awaitItem().canDisplayModerationActions).isFalse() - } - } - - @Test - fun `canDisplayModerationActions - when user can kick other users, FF is enabled and room is not a DM returns true`() = runTest { - val room = aJoinedRoom( - activeMemberCount = 10, - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - ) - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - presenter.test { - skipItems(1) - assertThat(awaitItem().canDisplayModerationActions).isTrue() - } - } - - @Test - fun `canDisplayModerationActions - when user can ban other users, FF is enabled and room is not a DM returns true`() = runTest { - val room = aJoinedRoom( - activeMemberCount = 10, - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - ) - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - presenter.test { - skipItems(1) - assertThat(awaitItem().canDisplayModerationActions).isTrue() - } - } - - @Test - fun `present - SelectRoomMember when the current user has permissions displays member actions`() = runTest { - val room = aJoinedRoom( - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - ) - val selectedMember = aVictor() - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - with(awaitItem()) { - assertThat(this.selectedRoomMember).isNotNull() - assertThat(this.selectedRoomMember?.userId).isEqualTo(selectedMember.userId) - assertThat(actions).containsExactly( - ModerationAction.DisplayProfile(selectedMember.userId), - ModerationAction.KickUser(selectedMember.userId), - ModerationAction.BanUser(selectedMember.userId) - ) - } - } - } - - @Test - fun `present - SelectRoomMember displays only view profile if selected member has same power level as the current user`() = runTest { - 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(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - with(awaitItem()) { - assertThat(this.selectedRoomMember).isNotNull() - assertThat(this.selectedRoomMember?.userId).isEqualTo(selectedMember.userId) - assertThat(actions).containsExactly( - ModerationAction.DisplayProfile(selectedMember.userId), - ) - } - } - } - - @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 = aJoinedRoom( - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - ) - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - with(awaitItem()) { - assertThat(selectedRoomMember).isNull() - assertThat(unbanUserAsyncAction).isEqualTo(ConfirmingRoomMemberAction(selectedMember)) - } - } - } - - @Test - fun `present - Kick requires confirmation and then kicks the user`() = runTest { - val analyticsService = FakeAnalyticsService() - val kickUserResult = lambdaRecorder> { _, _ -> Result.success(Unit) } - 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(joinedRoom = room, analyticsService = analyticsService) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - awaitItem().eventSink(RoomMembersModerationEvents.KickUser) - val confirmingState = awaitItem() - assertThat(confirmingState.kickUserAsyncAction).isEqualTo(AsyncAction.ConfirmingNoParams) - // Confirm - confirmingState.eventSink(RoomMembersModerationEvents.DoKickUser(reason = A_REASON)) - skipItems(1) - val loadingState = awaitItem() - assertThat(loadingState.actions).isEmpty() - assertThat(loadingState.kickUserAsyncAction).isEqualTo(AsyncAction.Loading) - with(awaitItem()) { - assertThat(kickUserAsyncAction).isEqualTo(AsyncAction.Success(Unit)) - assertThat(selectedRoomMember).isNull() - } - assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.KickMember)) - kickUserResult.assertions().isCalledOnce().with( - value(selectedMember.userId), - value(A_REASON), - ) - } - } - - @Test - fun `present - BanUser requires confirmation and then bans the user`() = runTest { - val analyticsService = FakeAnalyticsService() - val banUserResult = lambdaRecorder> { _, _ -> Result.success(Unit) } - 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(joinedRoom = room, analyticsService = analyticsService) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - awaitItem().eventSink(RoomMembersModerationEvents.BanUser) - val confirmingState = awaitItem() - assertThat(confirmingState.banUserAsyncAction).isEqualTo(AsyncAction.ConfirmingNoParams) - // Confirm - confirmingState.eventSink(RoomMembersModerationEvents.DoBanUser(reason = A_REASON)) - skipItems(1) - val loadingItem = awaitItem() - assertThat(loadingItem.actions).isEmpty() - assertThat(loadingItem.selectedRoomMember).isNull() - assertThat(loadingItem.banUserAsyncAction).isEqualTo(AsyncAction.Loading) - with(awaitItem()) { - assertThat(banUserAsyncAction).isEqualTo(AsyncAction.Success(Unit)) - assertThat(selectedRoomMember).isNull() - } - assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.BanMember)) - banUserResult.assertions().isCalledOnce().with( - value(selectedMember.userId), - value(A_REASON), - ) - } - } - - @Test - 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 = aJoinedRoom( - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - unBanUserResult = { _, _ -> Result.success(Unit) }, - ).apply { - givenRoomMembersState(RoomMembersState.Ready(persistentListOf(selectedMember))) - } - val presenter = createRoomMembersModerationPresenter(joinedRoom = room, analyticsService = analyticsService) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - // Displays unban confirmation dialog - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - val confirmingState = awaitItem() - assertThat(confirmingState.selectedRoomMember).isNull() - assertThat(confirmingState.actions).isEmpty() - assertThat(confirmingState.unbanUserAsyncAction).isEqualTo(ConfirmingRoomMemberAction(selectedMember)) - // Confirms unban - confirmingState.eventSink(RoomMembersModerationEvents.UnbanUser(selectedMember.userId)) - assertThat(awaitItem().unbanUserAsyncAction).isEqualTo(AsyncAction.Loading) - with(awaitItem()) { - assertThat(unbanUserAsyncAction).isEqualTo(AsyncAction.Success(Unit)) - assertThat(selectedRoomMember).isNull() - } - assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.UnbanMember)) - } - } - - @Test - fun `present - Reset removes the selected user and actions`() = runTest { - val room = aJoinedRoom( - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - userRoleResult = { Result.success(RoomMember.Role.USER) }, - ) - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - // Select a user - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor())) - // Reset state - awaitItem().eventSink(RoomMembersModerationEvents.Reset) - val finalItem = awaitItem() - assertThat(finalItem.selectedRoomMember).isNull() - assertThat(finalItem.actions).isEmpty() - } - } - - @Test - fun `present - Reset resets any async actions`() = runTest { - val room = aJoinedRoom( - canKickResult = { Result.success(true) }, - canBanResult = { Result.success(true) }, - kickUserResult = { _, _ -> Result.failure(Throwable("Eek")) }, - banUserResult = { _, _ -> Result.failure(Throwable("Eek")) }, - unBanUserResult = { _, _ -> Result.failure(Throwable("Eek")) }, - userRoleResult = { Result.success(RoomMember.Role.USER) }, - ) - val presenter = createRoomMembersModerationPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialItem = awaitItem() - // Kick user and fail - awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor())) - awaitItem().eventSink(RoomMembersModerationEvents.DoKickUser(reason = "")) - skipItems(1) - assertThat(awaitItem().kickUserAsyncAction).isInstanceOf(AsyncAction.Loading::class.java) - assertThat(awaitItem().kickUserAsyncAction).isInstanceOf(AsyncAction.Failure::class.java) - // Reset it - initialItem.eventSink(RoomMembersModerationEvents.Reset) - assertThat(awaitItem().kickUserAsyncAction).isEqualTo(AsyncAction.Uninitialized) - - // Ban user and fail - initialItem.eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor())) - awaitItem().eventSink(RoomMembersModerationEvents.DoBanUser(reason = "")) - skipItems(1) - assertThat(awaitItem().banUserAsyncAction).isInstanceOf(AsyncAction.Loading::class.java) - assertThat(awaitItem().banUserAsyncAction).isInstanceOf(AsyncAction.Failure::class.java) - // Reset it - initialItem.eventSink(RoomMembersModerationEvents.Reset) - assertThat(awaitItem().banUserAsyncAction).isEqualTo(AsyncAction.Uninitialized) - - // Unban user and fail - initialItem.eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor().copy(membership = RoomMembershipState.BAN))) - val confirmingState = awaitItem() - assertThat(confirmingState.unbanUserAsyncAction).isInstanceOf(AsyncAction.Confirming::class.java) - confirmingState.eventSink(RoomMembersModerationEvents.UnbanUser(aVictor().userId)) - assertThat(awaitItem().unbanUserAsyncAction).isInstanceOf(AsyncAction.Loading::class.java) - assertThat(awaitItem().unbanUserAsyncAction).isInstanceOf(AsyncAction.Failure::class.java) - // Reset it - initialItem.eventSink(RoomMembersModerationEvents.Reset) - assertThat(awaitItem().unbanUserAsyncAction).isEqualTo(AsyncAction.Uninitialized) - } - } - - private fun TestScope.createRoomMembersModerationPresenter( - joinedRoom: FakeJoinedRoom = aJoinedRoom(), - dispatchers: CoroutineDispatchers = testCoroutineDispatchers(), - analyticsService: FakeAnalyticsService = FakeAnalyticsService(), - ): RoomMembersModerationPresenter { - return RoomMembersModerationPresenter( - room = joinedRoom, - dispatchers = dispatchers, - analyticsService = analyticsService, - ) - } -} diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt deleted file mode 100644 index b501c808c7..0000000000 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.roomdetails.impl.members.moderation - -import androidx.activity.ComponentActivity -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onNodeWithText -import androidx.compose.ui.test.performTextInput -import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.element.android.features.roomdetails.impl.R -import io.element.android.features.roomdetails.impl.members.anAlice -import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.test.A_REASON -import io.element.android.libraries.ui.strings.CommonStrings -import io.element.android.tests.testutils.EnsureNeverCalledWithParam -import io.element.android.tests.testutils.EventsRecorder -import io.element.android.tests.testutils.clickOn -import io.element.android.tests.testutils.ensureCalledOnceWithParam -import io.element.android.tests.testutils.pressBackKey -import org.junit.Ignore -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.robolectric.annotation.Config - -@RunWith(AndroidJUnit4::class) -class RoomMembersModerationViewTest { - @get:Rule val rule = createAndroidComposeRule() - - @Ignore("This test is not passing yet, need to investigate") - @Test - fun `clicking on back emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - actions = listOf( - ModerationAction.DisplayProfile(roomMember.userId), - ), - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - rule.pressBackKey() - // Give time for the bottom sheet to animate - rule.mainClock.advanceTimeBy(1_000) - eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) - } - - @Test - fun `clicking on 'See user info' invokes the expected callback`() { - val eventsRecorder = EventsRecorder(expectEvents = false) - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - actions = listOf( - ModerationAction.DisplayProfile(roomMember.userId), - ), - eventSink = eventsRecorder - ) - ensureCalledOnceWithParam(roomMember.userId) { callback -> - rule.setRoomMembersModerationView( - state = state, - onDisplayMemberProfile = callback - ) - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_member_user_info) - } - } - - @Config(qualifiers = "h1024dp") - @Test - fun `clicking on 'Remove member' emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - actions = listOf( - ModerationAction.DisplayProfile(roomMember.userId), - ModerationAction.KickUser(roomMember.userId), - ), - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_remove) - // Give time for the bottom sheet to animate - rule.mainClock.advanceTimeBy(1_000) - eventsRecorder.assertSingle(RoomMembersModerationEvents.KickUser) - } - - @Test - fun `cancelling 'Remove member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - kickUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) - } - - @Test - fun `confirming 'Remove member' reason edition then validation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - kickUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - val reason = rule.activity.getString(CommonStrings.common_reason) - rule.onNodeWithText(reason).performTextInput(A_REASON) - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_kick_member_confirmation_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.DoKickUser(reason = A_REASON)) - } - - @Test - fun `confirming 'Remove member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - kickUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_kick_member_confirmation_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.DoKickUser(reason = "")) - } - - @Config(qualifiers = "h1024dp") - @Test - fun `clicking on 'Remove and ban member' emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - actions = listOf( - ModerationAction.DisplayProfile(roomMember.userId), - ModerationAction.KickUser(roomMember.userId), - ModerationAction.BanUser(roomMember.userId), - ), - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(R.string.screen_room_member_list_manage_member_remove_confirmation_ban) - // Give time for the bottom sheet to animate - rule.mainClock.advanceTimeBy(1_000) - eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser) - } - - @Test - fun `cancelling 'Remove and ban member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - banUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) - } - - @Test - fun `confirming 'Remove and ban member' reason edition emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - banUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - val reason = rule.activity.getString(CommonStrings.common_reason) - rule.onNodeWithText(reason).performTextInput(A_REASON) - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_ban_member_confirmation_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.DoBanUser(reason = A_REASON)) - } - - @Test - fun `confirming 'Remove and ban member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - banUserAsyncAction = AsyncAction.ConfirmingNoParams, - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(CommonStrings.screen_bottom_sheet_manage_room_member_ban_member_confirmation_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.DoBanUser(reason = "")) - } - - @Test - fun `cancelling 'Unban member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - unbanUserAsyncAction = ConfirmingRoomMemberAction(roomMember), - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) - } - - @Test - fun `confirming 'Unban member' confirmation emits the expected event`() { - val eventsRecorder = EventsRecorder() - val roomMember = anAlice() - val state = aRoomMembersModerationState( - selectedRoomMember = roomMember, - unbanUserAsyncAction = ConfirmingRoomMemberAction(roomMember), - eventSink = eventsRecorder - ) - rule.setRoomMembersModerationView( - state = state, - ) - // Note: the string key semantics is not perfect here :/ - rule.clickOn(R.string.screen_room_member_list_manage_member_unban_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.UnbanUser(roomMember.userId)) - } -} - -private fun AndroidComposeTestRule.setRoomMembersModerationView( - state: RoomMembersModerationState, - onDisplayMemberProfile: (UserId) -> Unit = EnsureNeverCalledWithParam() -) { - setContent { - RoomMembersModerationView( - state = state, - onDisplayMemberProfile = onDisplayMemberProfile, - ) - } -} diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt index b4bb8a3a27..86c816970c 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt @@ -7,13 +7,10 @@ package io.element.android.features.roommembermoderation.impl -import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationStateProvider.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt similarity index 91% rename from features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationStateProvider.kt rename to features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt index cdfca792d6..44f8bdc056 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationStateProvider.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt @@ -12,15 +12,11 @@ import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.RoomMembershipState -import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.toPersistentList -class RoomMemberModerationStateProvider : PreviewParameterProvider { +class InternalRoomMemberModerationStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aRoomMembersModerationState( diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt index a2a86e4d13..7f285e1f76 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt @@ -317,7 +317,7 @@ private fun RoomMemberActionsBottomSheet( @PreviewsDayNight @Composable -internal fun RoomMembersModerationViewPreview(@PreviewParameter(RoomMemberModerationStateProvider::class) state: InternalRoomMemberModerationState) { +internal fun RoomMemberModerationViewPreview(@PreviewParameter(InternalRoomMemberModerationStateProvider::class) state: InternalRoomMemberModerationState) { ElementPreview { Box( modifier = Modifier