From 3cf0375bb64aa3beda1a4158b17de41294dfd39d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 21 Feb 2024 16:52:54 +0100 Subject: [PATCH] Add tests on RoomListView (e2e banner) --- .../roomlist/impl/RoomListStateProvider.kt | 65 +++++---- .../roomlist/impl/RoomListViewTest.kt | 125 ++++++++++++++++++ 2 files changed, 165 insertions(+), 25 deletions(-) create mode 100644 features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt index e35e785e70..89597fea06 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt @@ -17,10 +17,12 @@ package io.element.android.features.roomlist.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.leaveroom.api.aLeaveRoomState import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.model.aRoomListRoomSummary +import io.element.android.features.roomlist.impl.search.RoomListSearchState import io.element.android.features.roomlist.impl.search.aRoomListSearchState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -37,34 +39,47 @@ open class RoomListStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aRoomListState(), - aRoomListState().copy(securityBannerState = SecurityBannerState.SessionVerification), - aRoomListState().copy(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)), - aRoomListState().copy(hasNetworkConnection = false), - aRoomListState().copy(invitesState = InvitesState.SeenInvites), - aRoomListState().copy(invitesState = InvitesState.NewInvites), - aRoomListState().copy(contextMenu = aContextMenuShown(roomName = "A nice room name")), - aRoomListState().copy(contextMenu = aContextMenuShown(isFavorite = true)), - aRoomListState().copy(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation), - aRoomListState().copy(roomList = AsyncData.Success(persistentListOf())), - aRoomListState().copy(roomList = AsyncData.Loading(prevData = RoomListRoomSummaryFactory.createFakeList())), - aRoomListState().copy(matrixUser = null, displayMigrationStatus = true), - aRoomListState().copy(searchState = aRoomListSearchState(isSearchActive = true, query = "Test")), + aRoomListState(securityBannerState = SecurityBannerState.SessionVerification), + aRoomListState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)), + aRoomListState(hasNetworkConnection = false), + aRoomListState(invitesState = InvitesState.SeenInvites), + aRoomListState(invitesState = InvitesState.NewInvites), + aRoomListState(contextMenu = aContextMenuShown(roomName = "A nice room name")), + aRoomListState(contextMenu = aContextMenuShown(isFavorite = true)), + aRoomListState(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation), + aRoomListState(roomList = AsyncData.Success(persistentListOf())), + aRoomListState(roomList = AsyncData.Loading(prevData = RoomListRoomSummaryFactory.createFakeList())), + aRoomListState(matrixUser = null, displayMigrationStatus = true), + aRoomListState(searchState = aRoomListSearchState(isSearchActive = true, query = "Test")), ) } -internal fun aRoomListState() = RoomListState( - matrixUser = MatrixUser(userId = UserId("@id:domain"), displayName = "User#1"), - showAvatarIndicator = false, - roomList = AsyncData.Success(aRoomListRoomSummaryList()), - hasNetworkConnection = true, - snackbarMessage = null, - securityBannerState = SecurityBannerState.None, - invitesState = InvitesState.NoInvites, - contextMenu = RoomListState.ContextMenu.Hidden, - leaveRoomState = aLeaveRoomState(), - searchState = aRoomListSearchState(), - displayMigrationStatus = false, - eventSink = {} +internal fun aRoomListState( + matrixUser: MatrixUser? = MatrixUser(userId = UserId("@id:domain"), displayName = "User#1"), + showAvatarIndicator: Boolean = false, + roomList: AsyncData> = AsyncData.Success(aRoomListRoomSummaryList()), + hasNetworkConnection: Boolean = true, + snackbarMessage: SnackbarMessage? = null, + securityBannerState: SecurityBannerState = SecurityBannerState.None, + invitesState: InvitesState = InvitesState.NoInvites, + contextMenu: RoomListState.ContextMenu = RoomListState.ContextMenu.Hidden, + leaveRoomState: LeaveRoomState = aLeaveRoomState(), + searchState: RoomListSearchState = aRoomListSearchState(), + displayMigrationStatus: Boolean = false, + eventSink: (RoomListEvents) -> Unit = {} +) = RoomListState( + matrixUser = matrixUser, + showAvatarIndicator = showAvatarIndicator, + roomList = roomList, + hasNetworkConnection = hasNetworkConnection, + snackbarMessage = snackbarMessage, + securityBannerState = securityBannerState, + invitesState = invitesState, + contextMenu = contextMenu, + leaveRoomState = leaveRoomState, + searchState = searchState, + displayMigrationStatus = displayMigrationStatus, + eventSink = eventSink, ) internal fun aRoomListRoomSummaryList(): ImmutableList { diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt new file mode 100644 index 0000000000..c52a8d4614 --- /dev/null +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.roomlist.impl + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.roomlist.impl.components.RoomListMenuAction +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EnsureNeverCalled +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.ensureCalledOnce +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RoomListViewTest { + @get:Rule val rule = createAndroidComposeRule() + + @Test + fun `clicking on close verification banner emits the expected Event`() { + val eventsRecorder = EventsRecorder() + rule.setRoomListView( + state = aRoomListState( + securityBannerState = SecurityBannerState.SessionVerification, + eventSink = eventsRecorder, + ) + ) + val close = rule.activity.getString(CommonStrings.action_close) + rule.onNodeWithContentDescription(close).performClick() + eventsRecorder.assertSingle(RoomListEvents.DismissRequestVerificationPrompt) + } + + @Test + fun `clicking on continue verification banner invokes the expected callback`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setRoomListView( + state = aRoomListState( + securityBannerState = SecurityBannerState.SessionVerification, + eventSink = eventsRecorder, + ), + onVerifyClicked = callback, + ) + rule.clickOn(CommonStrings.action_continue) + } + } + + @Test + fun `clicking on close recovery key banner emits the expected Event`() { + val eventsRecorder = EventsRecorder() + rule.setRoomListView( + state = aRoomListState( + securityBannerState = SecurityBannerState.RecoveryKeyConfirmation, + eventSink = eventsRecorder, + ) + ) + val close = rule.activity.getString(CommonStrings.action_close) + rule.onNodeWithContentDescription(close).performClick() + eventsRecorder.assertSingle(RoomListEvents.DismissRecoveryKeyPrompt) + } + + @Test + fun `clicking on continue recovery key banner invokes the expected callback`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setRoomListView( + state = aRoomListState( + securityBannerState = SecurityBannerState.RecoveryKeyConfirmation, + eventSink = eventsRecorder, + ), + onConfirmRecoveryKeyClicked = callback, + ) + rule.clickOn(CommonStrings.action_continue) + } + } +} + +private fun AndroidComposeTestRule.setRoomListView( + state: RoomListState, + onRoomClicked: (RoomId) -> Unit = EnsureNeverCalledWithParam(), + onSettingsClicked: () -> Unit = EnsureNeverCalled(), + onVerifyClicked: () -> Unit = EnsureNeverCalled(), + onConfirmRecoveryKeyClicked: () -> Unit = EnsureNeverCalled(), + onCreateRoomClicked: () -> Unit = EnsureNeverCalled(), + onInvitesClicked: () -> Unit = EnsureNeverCalled(), + onRoomSettingsClicked: (RoomId) -> Unit = EnsureNeverCalledWithParam(), + onMenuActionClicked: (RoomListMenuAction) -> Unit = EnsureNeverCalledWithParam(), +) { + setContent { + RoomListView( + state = state, + onRoomClicked = onRoomClicked, + onSettingsClicked = onSettingsClicked, + onVerifyClicked = onVerifyClicked, + onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, + onCreateRoomClicked = onCreateRoomClicked, + onInvitesClicked = onInvitesClicked, + onRoomSettingsClicked = onRoomSettingsClicked, + onMenuActionClicked = onMenuActionClicked, + ) + } +}