Merge pull request #6693 from element-hq/renovate/compose.bom
Update dependency androidx.compose:compose-bom to v2026.04.01
This commit is contained in:
commit
4e38846342
84 changed files with 2198 additions and 2321 deletions
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.announcement.impl.fullscreen
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.announcement.api.Announcement
|
||||
import io.element.android.features.announcement.impl.AnnouncementEvent
|
||||
|
|
@ -20,43 +23,39 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FullscreenAnnouncementViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back sends a AnnouncementEvent`() {
|
||||
fun `clicking on back sends a AnnouncementEvent`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AnnouncementEvent>()
|
||||
rule.setFullscreenAnnouncementView(
|
||||
setFullscreenAnnouncementView(
|
||||
anAnnouncementState(
|
||||
announcement = Announcement.Fullscreen.Space,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Continue sends a AnnouncementEvent`() {
|
||||
fun `clicking on Continue sends a AnnouncementEvent`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AnnouncementEvent>()
|
||||
rule.setFullscreenAnnouncementView(
|
||||
setFullscreenAnnouncementView(
|
||||
anAnnouncementState(
|
||||
announcement = Announcement.Fullscreen.Space,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setFullscreenAnnouncementView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setFullscreenAnnouncementView(
|
||||
state: AnnouncementState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.call.ui
|
||||
|
||||
import android.view.KeyEvent
|
||||
|
|
@ -12,8 +14,9 @@ import android.webkit.WebView
|
|||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.call.impl.pip.PictureInPictureEvents
|
||||
import io.element.android.features.call.impl.pip.aPictureInPictureState
|
||||
|
|
@ -24,9 +27,7 @@ import io.element.android.features.call.impl.ui.aCallScreenState
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.Implementation
|
||||
|
|
@ -36,32 +37,29 @@ import org.robolectric.shadows.ShadowWebView
|
|||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CallScreenViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `pressing back key triggers hangup when no web view is available and pip is unsupported`() {
|
||||
fun `pressing back key triggers hangup when no web view is available and pip is unsupported`() = runAndroidComposeUiTest {
|
||||
val callEvents = EventsRecorder<CallScreenEvents>()
|
||||
|
||||
rule.setCallScreenView(
|
||||
setCallScreenView(
|
||||
state = aCallScreenState(eventSink = callEvents),
|
||||
useInspectionMode = true,
|
||||
)
|
||||
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
|
||||
callEvents.assertEmpty()
|
||||
}
|
||||
|
||||
@Config(shadows = [RecordingShadowWebView::class])
|
||||
@Test
|
||||
fun `pressing back key dispatches escape key events to web view when pip is unsupported`() {
|
||||
rule.setCallScreenView(
|
||||
fun `pressing back key dispatches escape key events to web view when pip is unsupported`() = runAndroidComposeUiTest {
|
||||
setCallScreenView(
|
||||
state = aCallScreenState(),
|
||||
useInspectionMode = false,
|
||||
)
|
||||
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
|
||||
val dispatchedEvents = RecordingShadowWebView.dispatchedEvents
|
||||
assertEquals(2, dispatchedEvents.size)
|
||||
|
|
@ -73,10 +71,10 @@ class CallScreenViewTest {
|
|||
|
||||
@Config(shadows = [RecordingShadowWebView::class])
|
||||
@Test
|
||||
fun `web view javascript back handler emits pip event when pip is supported`() {
|
||||
fun `web view javascript back handler emits pip event when pip is supported`() = runAndroidComposeUiTest {
|
||||
val pipEvents = EventsRecorder<PictureInPictureEvents>()
|
||||
|
||||
rule.setCallScreenView(
|
||||
setCallScreenView(
|
||||
state = aCallScreenState(),
|
||||
useInspectionMode = false,
|
||||
pipState = aPictureInPictureState(
|
||||
|
|
@ -85,7 +83,7 @@ class CallScreenViewTest {
|
|||
),
|
||||
)
|
||||
|
||||
rule.runOnIdle {
|
||||
runOnIdle {
|
||||
RecordingShadowWebView.invokeJavascriptBackHandler()
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +93,7 @@ class CallScreenViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCallScreenView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setCallScreenView(
|
||||
state: io.element.android.features.call.impl.ui.CallScreenState,
|
||||
useInspectionMode: Boolean,
|
||||
pipState: io.element.android.features.call.impl.pip.PictureInPictureState = aPictureInPictureState(supportPip = false),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.logout.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.deactivation.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -26,33 +29,29 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
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 AccountDeactivationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(eventSink = eventsRecorder),
|
||||
onBackClick = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Deactivate emits the expected Event`() {
|
||||
fun `clicking on Deactivate emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
deactivateFormState = aDeactivateFormState(
|
||||
password = A_PASSWORD,
|
||||
|
|
@ -60,14 +59,14 @@ class AccountDeactivationViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_delete)
|
||||
clickOn(CommonStrings.action_delete)
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Deactivate on the confirmation dialog emits the expected Event`() {
|
||||
fun `clicking on Deactivate on the confirmation dialog emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
deactivateFormState = aDeactivateFormState(
|
||||
password = A_PASSWORD,
|
||||
|
|
@ -76,14 +75,14 @@ class AccountDeactivationViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on retry on the confirmation dialog emits the expected Event`() {
|
||||
fun `clicking on retry on the confirmation dialog emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
deactivateFormState = aDeactivateFormState(
|
||||
password = A_PASSWORD,
|
||||
|
|
@ -92,26 +91,26 @@ class AccountDeactivationViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `switching on the erase all switch emits the expected Event`() {
|
||||
fun `switching on the erase all switch emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_deactivate_account_delete_all_messages)
|
||||
clickOn(R.string.screen_deactivate_account_delete_all_messages)
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.SetEraseData(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `switching off the erase all switch emits the expected Event`() {
|
||||
fun `switching off the erase all switch emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
deactivateFormState = aDeactivateFormState(
|
||||
eraseData = true,
|
||||
|
|
@ -119,15 +118,15 @@ class AccountDeactivationViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_deactivate_account_delete_all_messages)
|
||||
clickOn(R.string.screen_deactivate_account_delete_all_messages)
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.SetEraseData(false))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `typing text in the password field emits the expected Event`() {
|
||||
fun `typing text in the password field emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AccountDeactivationEvents>()
|
||||
rule.setAccountDeactivationView(
|
||||
setAccountDeactivationView(
|
||||
state = anAccountDeactivationState(
|
||||
deactivateFormState = aDeactivateFormState(
|
||||
password = A_PASSWORD,
|
||||
|
|
@ -135,12 +134,12 @@ class AccountDeactivationViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.loginPassword.value).performTextInput("A")
|
||||
onNodeWithTag(TestTags.loginPassword.value).performTextInput("A")
|
||||
eventsRecorder.assertSingle(AccountDeactivationEvents.SetPassword("A$A_PASSWORD"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setAccountDeactivationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAccountDeactivationView(
|
||||
state: AccountDeactivationState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.forward.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
|
@ -21,34 +24,30 @@ import io.element.android.tests.testutils.EnsureNeverCalledWithParam
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ForwardMessagesViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `cancel error emits the expected event`() {
|
||||
fun `cancel error emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ForwardMessagesEvents>()
|
||||
rule.setForwardMessagesView(
|
||||
setForwardMessagesView(
|
||||
aForwardMessagesState(
|
||||
forwardAction = AsyncAction.Failure(AN_EXCEPTION),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(ForwardMessagesEvents.ClearError)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `success invokes onForwardSuccess`() {
|
||||
fun `success invokes onForwardSuccess`() = runAndroidComposeUiTest {
|
||||
val data = listOf(A_ROOM_ID)
|
||||
val eventsRecorder = EventsRecorder<ForwardMessagesEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam<List<RoomId>?>(data) { callback ->
|
||||
rule.setForwardMessagesView(
|
||||
setForwardMessagesView(
|
||||
aForwardMessagesState(
|
||||
forwardAction = AsyncAction.Success(data),
|
||||
eventSink = eventsRecorder
|
||||
|
|
@ -59,7 +58,7 @@ class ForwardMessagesViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setForwardMessagesView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setForwardMessagesView(
|
||||
state: ForwardMessagesState,
|
||||
onForwardSuccess: (List<RoomId>) -> Unit = EnsureNeverCalledWithParam(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.ftue.impl.sessionverification.choosemode
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.ftue.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
|
|
@ -18,65 +21,61 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
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
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ChooseSessionVerificationModeViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on learn more invokes the expected callback`() {
|
||||
fun `clicking on learn more invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setChooseSelfVerificationModeView(
|
||||
setChooseSelfVerificationModeView(
|
||||
aChooseSelfVerificationModeState(),
|
||||
onLearnMoreClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_learn_more)
|
||||
clickOn(CommonStrings.action_learn_more)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on use another device calls the callback`() {
|
||||
fun `clicking on use another device calls the callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setChooseSelfVerificationModeView(
|
||||
setChooseSelfVerificationModeView(
|
||||
aChooseSelfVerificationModeState(AsyncData.Success(aButtonsState(canUseAnotherDevice = true))),
|
||||
onUseAnotherDevice = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_identity_use_another_device)
|
||||
clickOn(R.string.screen_identity_use_another_device)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on enter recovery key calls the callback`() {
|
||||
fun `clicking on enter recovery key calls the callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setChooseSelfVerificationModeView(
|
||||
setChooseSelfVerificationModeView(
|
||||
aChooseSelfVerificationModeState(AsyncData.Success(aButtonsState(canUseRecoveryKey = true))),
|
||||
onEnterRecoveryKey = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_identity_confirmation_use_recovery_key)
|
||||
clickOn(R.string.screen_identity_confirmation_use_recovery_key)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on cannot confirm calls the reset keys callback`() {
|
||||
fun `clicking on cannot confirm calls the reset keys callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setChooseSelfVerificationModeView(
|
||||
setChooseSelfVerificationModeView(
|
||||
aChooseSelfVerificationModeState(),
|
||||
onResetKey = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_identity_confirmation_cannot_confirm)
|
||||
clickOn(R.string.screen_identity_confirmation_cannot_confirm)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChooseSelfVerificationModeView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setChooseSelfVerificationModeView(
|
||||
state: ChooseSelfVerificationModeState,
|
||||
onLearnMoreClick: () -> Unit = EnsureNeverCalled(),
|
||||
onUseAnotherDevice: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.home.impl.filters
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.home.impl.R
|
||||
import io.element.android.features.home.impl.filters.selection.FilterSelectionState
|
||||
|
|
@ -17,23 +20,20 @@ import io.element.android.libraries.testtags.TestTags
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomListFiltersViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on filters generates expected Event`() {
|
||||
fun `clicking on filters generates expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListFiltersEvent>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
RoomListFiltersView(
|
||||
state = aRoomListFiltersState(eventSink = eventsRecorder),
|
||||
)
|
||||
}
|
||||
rule.clickOn(R.string.screen_roomlist_filter_rooms)
|
||||
clickOn(R.string.screen_roomlist_filter_rooms)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListFiltersEvent.ToggleFilter(RoomListFilter.Rooms),
|
||||
|
|
@ -42,9 +42,9 @@ class RoomListFiltersViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on clear filters generates expected Event`() {
|
||||
fun `clicking on clear filters generates expected Event`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||
val eventsRecorder = EventsRecorder<RoomListFiltersEvent>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
RoomListFiltersView(
|
||||
state = aRoomListFiltersState(
|
||||
filterSelectionStates = RoomListFilter.entries.map { FilterSelectionState(it, isSelected = true) },
|
||||
|
|
@ -52,7 +52,7 @@ class RoomListFiltersViewTest {
|
|||
),
|
||||
)
|
||||
}
|
||||
rule.pressTag(TestTags.homeScreenClearFilters.value)
|
||||
pressTag(TestTags.homeScreenClearFilters.value)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListFiltersEvent.ClearSelectedFilters,
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.home.impl.roomlist
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.home.impl.R
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
|
@ -20,23 +23,20 @@ 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.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomListContextMenuTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on Mark as read generates expected Events`() {
|
||||
fun `clicking on Mark as read generates expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown(hasNewContent = true)
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.clickOn(R.string.screen_roomlist_mark_as_read)
|
||||
clickOn(R.string.screen_roomlist_mark_as_read)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.HideContextMenu,
|
||||
|
|
@ -46,14 +46,14 @@ class RoomListContextMenuTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Mark as unread generates expected Events`() {
|
||||
fun `clicking on Mark as unread generates expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown(hasNewContent = false)
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.clickOn(R.string.screen_roomlist_mark_as_unread)
|
||||
clickOn(R.string.screen_roomlist_mark_as_unread)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.HideContextMenu,
|
||||
|
|
@ -63,14 +63,14 @@ class RoomListContextMenuTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Leave room generates expected Events`() {
|
||||
fun `clicking on Leave room generates expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown(isDm = false)
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_leave_room)
|
||||
clickOn(CommonStrings.action_leave_room)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.HideContextMenu,
|
||||
|
|
@ -80,48 +80,48 @@ class RoomListContextMenuTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Report room invokes the expected callback and generates expected Event`() {
|
||||
fun `clicking on Report room invokes the expected callback and generates expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown()
|
||||
val callback = EnsureCalledOnceWithParam(contextMenu.roomId, Unit)
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
canReportRoom = true,
|
||||
eventSink = eventsRecorder,
|
||||
onRoomSettingsClick = EnsureNeverCalledWithParam(),
|
||||
onReportRoomClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_report_room)
|
||||
clickOn(CommonStrings.action_report_room)
|
||||
eventsRecorder.assertSingle(RoomListEvent.HideContextMenu)
|
||||
callback.assertSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Settings invokes the expected callback and generates expected Event`() {
|
||||
fun `clicking on Settings invokes the expected callback and generates expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown()
|
||||
val callback = EnsureCalledOnceWithParam(contextMenu.roomId, Unit)
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
eventSink = eventsRecorder,
|
||||
onRoomSettingsClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_settings)
|
||||
clickOn(CommonStrings.common_settings)
|
||||
eventsRecorder.assertSingle(RoomListEvent.HideContextMenu)
|
||||
callback.assertSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Favourites generates expected Event`() {
|
||||
fun `clicking on Favourites generates expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val contextMenu = aContextMenuShown(isDm = false, isFavorite = false)
|
||||
val callback = EnsureNeverCalledWithParam<RoomId>()
|
||||
rule.setRoomListContextMenu(
|
||||
setRoomListContextMenu(
|
||||
contextMenu = contextMenu,
|
||||
eventSink = eventsRecorder,
|
||||
onRoomSettingsClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_favourite)
|
||||
clickOn(CommonStrings.common_favourite)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.SetRoomIsFavorite(contextMenu.roomId, true),
|
||||
|
|
@ -129,7 +129,7 @@ class RoomListContextMenuTest {
|
|||
)
|
||||
}
|
||||
|
||||
private fun AndroidComposeTestRule<*, *>.setRoomListContextMenu(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomListContextMenu(
|
||||
contextMenu: RoomListState.ContextMenu.Shown,
|
||||
canReportRoom: Boolean = false,
|
||||
eventSink: (RoomListEvent) -> Unit,
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.home.impl.roomlist
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.home.impl.model.aRoomListRoomSummary
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -18,19 +20,16 @@ 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.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomListDeclineInviteMenuTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on decline emits the expected Events`() {
|
||||
fun `clicking on decline emits the expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val menu = RoomListState.DeclineInviteMenu.Shown(roomSummary = aRoomListRoomSummary())
|
||||
rule.setSafeContent {
|
||||
setSafeContent {
|
||||
RoomListDeclineInviteMenu(
|
||||
menu = menu,
|
||||
canReportRoom = false,
|
||||
|
|
@ -38,7 +37,7 @@ class RoomListDeclineInviteMenuTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.HideDeclineInviteMenu,
|
||||
|
|
@ -48,10 +47,10 @@ class RoomListDeclineInviteMenuTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline and block when canReportRoom=true, it emits the expected Events and callback`() {
|
||||
fun `clicking on decline and block when canReportRoom=true, it emits the expected Events and callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val menu = RoomListState.DeclineInviteMenu.Shown(roomSummary = aRoomListRoomSummary())
|
||||
rule.setSafeContent {
|
||||
setSafeContent {
|
||||
RoomListDeclineInviteMenu(
|
||||
menu = menu,
|
||||
canReportRoom = true,
|
||||
|
|
@ -59,16 +58,16 @@ class RoomListDeclineInviteMenuTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_decline_and_block)
|
||||
clickOn(CommonStrings.action_decline_and_block)
|
||||
val expectedEvents = listOf(RoomListEvent.HideDeclineInviteMenu)
|
||||
eventsRecorder.assertList(expectedEvents)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline and block when canReportRoom=false, it emits the expected Events`() {
|
||||
fun `clicking on decline and block when canReportRoom=false, it emits the expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val menu = RoomListState.DeclineInviteMenu.Shown(roomSummary = aRoomListRoomSummary())
|
||||
rule.setSafeContent {
|
||||
setSafeContent {
|
||||
RoomListDeclineInviteMenu(
|
||||
menu = menu,
|
||||
canReportRoom = false,
|
||||
|
|
@ -76,7 +75,7 @@ class RoomListDeclineInviteMenuTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_decline_and_block)
|
||||
clickOn(CommonStrings.action_decline_and_block)
|
||||
val expectedEvents = listOf(
|
||||
RoomListEvent.HideDeclineInviteMenu,
|
||||
RoomListEvent.DeclineInvite(menu.roomSummary, blockUser = true),
|
||||
|
|
@ -85,10 +84,10 @@ class RoomListDeclineInviteMenuTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel emits the expected Event`() {
|
||||
fun `clicking on cancel emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val menu = RoomListState.DeclineInviteMenu.Shown(roomSummary = aRoomListRoomSummary())
|
||||
rule.setSafeContent {
|
||||
setSafeContent {
|
||||
RoomListDeclineInviteMenu(
|
||||
menu = menu,
|
||||
canReportRoom = false,
|
||||
|
|
@ -96,7 +95,7 @@ class RoomListDeclineInviteMenuTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertList(listOf(RoomListEvent.HideDeclineInviteMenu))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.home.impl.roomlist
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.longClick
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.home.impl.HomeView
|
||||
import io.element.android.features.home.impl.R
|
||||
|
|
@ -32,22 +35,17 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
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 RoomListViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `displaying the view automatically sends a couple of UpdateVisibleRangeEvents`() {
|
||||
fun `displaying the view automatically sends a couple of UpdateVisibleRangeEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -62,9 +60,9 @@ class RoomListViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on close recovery key banner emits the expected Event`() {
|
||||
fun `clicking on close recovery key banner emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -74,15 +72,15 @@ class RoomListViewTest {
|
|||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
val close = rule.activity.getString(CommonStrings.action_close)
|
||||
rule.onNodeWithContentDescription(close).performClick()
|
||||
val close = activity!!.getString(CommonStrings.action_close)
|
||||
onNodeWithContentDescription(close).performClick()
|
||||
eventsRecorder.assertSingle(RoomListEvent.DismissBanner)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on close setup key banner emits the expected Event`() {
|
||||
fun `clicking on close setup key banner emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -92,16 +90,16 @@ class RoomListViewTest {
|
|||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
val close = rule.activity.getString(CommonStrings.action_close)
|
||||
rule.onNodeWithContentDescription(close).performClick()
|
||||
val close = activity!!.getString(CommonStrings.action_close)
|
||||
onNodeWithContentDescription(close).performClick()
|
||||
eventsRecorder.assertSingle(RoomListEvent.DismissBanner)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on continue recovery key banner invokes the expected callback`() {
|
||||
fun `clicking on continue recovery key banner invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -112,17 +110,17 @@ class RoomListViewTest {
|
|||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on continue setup key banner invokes the expected callback`() {
|
||||
fun `clicking on continue setup key banner invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -131,28 +129,28 @@ class RoomListViewTest {
|
|||
)
|
||||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
rule.clickOn(R.string.banner_set_up_recovery_submit)
|
||||
clickOn(R.string.banner_set_up_recovery_submit)
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on start chat when the session has no room invokes the expected callback`() {
|
||||
fun `clicking on start chat when the session has no room invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
contentState = anEmptyContentState(),
|
||||
),
|
||||
onCreateRoomClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_start_chat)
|
||||
clickOn(CommonStrings.action_start_chat)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a room invokes the expected callback`() {
|
||||
fun `clicking on a room invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -161,7 +159,7 @@ class RoomListViewTest {
|
|||
it.displayType == RoomSummaryDisplayType.ROOM
|
||||
}
|
||||
ensureCalledOnceWithParam(room0.roomId) { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = state,
|
||||
onRoomClick = callback,
|
||||
)
|
||||
|
|
@ -169,14 +167,14 @@ class RoomListViewTest {
|
|||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.onNodeWithText(room0.latestEvent.content().toString()).performClick()
|
||||
onNodeWithText(room0.latestEvent.content().toString()).performClick()
|
||||
}
|
||||
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a room twice invokes the expected callback only once`() {
|
||||
fun `clicking on a room twice invokes the expected callback only once`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -185,13 +183,13 @@ class RoomListViewTest {
|
|||
it.displayType == RoomSummaryDisplayType.ROOM
|
||||
}
|
||||
ensureCalledOnceWithParam(room0.roomId) { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = state,
|
||||
onRoomClick = callback,
|
||||
)
|
||||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
rule.onNodeWithText(room0.latestEvent.content().toString())
|
||||
onNodeWithText(room0.latestEvent.content().toString())
|
||||
.performClick()
|
||||
.performClick()
|
||||
}
|
||||
|
|
@ -199,7 +197,7 @@ class RoomListViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `long clicking on a room emits the expected Event`() {
|
||||
fun `long clicking on a room emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -207,18 +205,18 @@ class RoomListViewTest {
|
|||
val room0 = state.contentAsRooms().summaries.first {
|
||||
it.displayType == RoomSummaryDisplayType.ROOM
|
||||
}
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = state,
|
||||
)
|
||||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.onNodeWithText(room0.latestEvent.content().toString()).performTouchInput { longClick() }
|
||||
onNodeWithText(room0.latestEvent.content().toString()).performTouchInput { longClick() }
|
||||
eventsRecorder.assertSingle(RoomListEvent.ShowContextMenu(room0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a room setting invokes the expected callback and emits expected Event`() {
|
||||
fun `clicking on a room setting invokes the expected callback and emits expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val state = aRoomListState(
|
||||
contextMenu = aContextMenuShown(),
|
||||
|
|
@ -226,7 +224,7 @@ class RoomListViewTest {
|
|||
)
|
||||
val room0 = (state.contextMenu as RoomListState.ContextMenu.Shown).roomId
|
||||
ensureCalledOnceWithParam(room0) { callback ->
|
||||
rule.setRoomListView(
|
||||
setRoomListView(
|
||||
state = state,
|
||||
onRoomSettingsClick = callback,
|
||||
)
|
||||
|
|
@ -234,14 +232,14 @@ class RoomListViewTest {
|
|||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.clickOn(CommonStrings.common_settings)
|
||||
clickOn(CommonStrings.common_settings)
|
||||
}
|
||||
|
||||
eventsRecorder.assertSingle(RoomListEvent.HideContextMenu)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on accept and decline invite emits the expected Events`() {
|
||||
fun `clicking on accept and decline invite emits the expected Events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvent>()
|
||||
val state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -249,13 +247,13 @@ class RoomListViewTest {
|
|||
val invitedRoom = state.contentAsRooms().summaries.first {
|
||||
it.displayType == RoomSummaryDisplayType.INVITE
|
||||
}
|
||||
rule.setRoomListView(state = state)
|
||||
setRoomListView(state = state)
|
||||
|
||||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.clickOn(CommonStrings.action_accept)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_accept)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
RoomListEvent.AcceptInvite(invitedRoom),
|
||||
|
|
@ -265,7 +263,7 @@ class RoomListViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomListView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomListView(
|
||||
state: RoomListState,
|
||||
onRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onSettingsClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -5,34 +5,32 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.home.impl.spacefilters
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ALIAS
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SpaceFiltersViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on a filter with alias shows display name and alias`() {
|
||||
fun `clicking on a filter with alias shows display name and alias`() = runAndroidComposeUiTest {
|
||||
val filter = aSpaceServiceFilter(
|
||||
displayName = "Test Space",
|
||||
canonicalAlias = A_ROOM_ALIAS,
|
||||
)
|
||||
val eventsRecorder = EventsRecorder<SpaceFiltersEvent.Selecting>()
|
||||
rule.setSpaceFiltersView(
|
||||
setSpaceFiltersView(
|
||||
state = aSelectingSpaceFiltersState(
|
||||
availableFilters = listOf(filter),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -40,20 +38,20 @@ class SpaceFiltersViewTest {
|
|||
)
|
||||
|
||||
// Both display name and alias should be visible
|
||||
rule.onNodeWithText(filter.spaceRoom.displayName).assertExists()
|
||||
rule.onNodeWithText(A_ROOM_ALIAS.value).assertExists()
|
||||
onNodeWithText(filter.spaceRoom.displayName).assertExists()
|
||||
onNodeWithText(A_ROOM_ALIAS.value).assertExists()
|
||||
|
||||
rule.onNodeWithText(filter.spaceRoom.displayName).performClick()
|
||||
onNodeWithText(filter.spaceRoom.displayName).performClick()
|
||||
|
||||
eventsRecorder.assertSingle(SpaceFiltersEvent.Selecting.SelectFilter(filter))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiple filters are displayed and clickable`() {
|
||||
fun `multiple filters are displayed and clickable`() = runAndroidComposeUiTest {
|
||||
val filter1 = aSpaceServiceFilter(displayName = "Space One")
|
||||
val filter2 = aSpaceServiceFilter(displayName = "Space Two")
|
||||
val eventsRecorder = EventsRecorder<SpaceFiltersEvent.Selecting>()
|
||||
rule.setSpaceFiltersView(
|
||||
setSpaceFiltersView(
|
||||
state = aSelectingSpaceFiltersState(
|
||||
availableFilters = listOf(filter1, filter2),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -61,17 +59,17 @@ class SpaceFiltersViewTest {
|
|||
)
|
||||
|
||||
// Both filters should be visible
|
||||
rule.onNodeWithText(filter1.spaceRoom.displayName).assertExists()
|
||||
rule.onNodeWithText(filter2.spaceRoom.displayName).assertExists()
|
||||
onNodeWithText(filter1.spaceRoom.displayName).assertExists()
|
||||
onNodeWithText(filter2.spaceRoom.displayName).assertExists()
|
||||
|
||||
// Click on second filter
|
||||
rule.onNodeWithText(filter2.spaceRoom.displayName).performClick()
|
||||
onNodeWithText(filter2.spaceRoom.displayName).performClick()
|
||||
|
||||
eventsRecorder.assertSingle(SpaceFiltersEvent.Selecting.SelectFilter(filter2))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSpaceFiltersView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setSpaceFiltersView(
|
||||
state: SpaceFiltersState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.invite.impl.declineandblock
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.invite.impl.R
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -21,98 +24,94 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DeclineAndBlockViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke the expected callback`() {
|
||||
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline when enabled emits the expected event`() {
|
||||
fun `clicking on decline when enabled emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>()
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
blockUser = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertSingle(DeclineAndBlockEvents.Decline)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline when disabled does not emit event`() {
|
||||
fun `clicking on decline when disabled does not emit event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>(expectEvents = false)
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
blockUser = false,
|
||||
reportRoom = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on block option emits the expected event`() {
|
||||
fun `clicking on block option emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>()
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
blockUser = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_decline_and_block_block_user_option_title)
|
||||
clickOn(R.string.screen_decline_and_block_block_user_option_title)
|
||||
eventsRecorder.assertSingle(DeclineAndBlockEvents.ToggleBlockUser)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on report room option emits the expected event`() {
|
||||
fun `clicking on report room option emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>()
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
reportRoom = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_report_room)
|
||||
clickOn(CommonStrings.action_report_room)
|
||||
eventsRecorder.assertSingle(DeclineAndBlockEvents.ToggleReportRoom)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `typing text in the reason field emits the expected Event`() {
|
||||
fun `typing text in the reason field emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeclineAndBlockEvents>()
|
||||
rule.setDeclineAndBlockView(
|
||||
setDeclineAndBlockView(
|
||||
aDeclineAndBlockState(
|
||||
reportRoom = true,
|
||||
reportReason = "",
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("").performTextInput("Spam!")
|
||||
onNodeWithText("").performTextInput("Spam!")
|
||||
eventsRecorder.assertSingle(DeclineAndBlockEvents.UpdateReportReason("Spam!"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setDeclineAndBlockView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setDeclineAndBlockView(
|
||||
state: DeclineAndBlockState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.joinroom.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.invite.api.InviteData
|
||||
import io.element.android.features.invite.test.anInviteData
|
||||
|
|
@ -26,116 +29,112 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class JoinRoomViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke the expected callback`() {
|
||||
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Join room on CanJoin room emits the expected Event`() {
|
||||
fun `clicking on Join room on CanJoin room emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_join_room_join_action)
|
||||
clickOn(R.string.screen_join_room_join_action)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.JoinRoom)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Knock room on CanKnock room emits the expected Event`() {
|
||||
fun `clicking on Knock room on CanKnock room emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
|
||||
knockMessage = "Knock knock",
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_join_room_knock_action)
|
||||
clickOn(R.string.screen_join_room_knock_action)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.KnockRoom)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on closing Knock error emits the expected Event`() {
|
||||
fun `clicking on closing Knock error emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
|
||||
knockAction = AsyncAction.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel knock request emit the expected Event`() {
|
||||
fun `clicking on cancel knock request emit the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_join_room_cancel_knock_action)
|
||||
clickOn(R.string.screen_join_room_cancel_knock_action)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.CancelKnock(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on closing Cancel Knock error emits the expected Event`() {
|
||||
fun `clicking on closing Cancel Knock error emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked),
|
||||
cancelKnockAction = AsyncAction.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on closing Join error emits the expected Event`() {
|
||||
fun `clicking on closing Join error emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
|
||||
joinAction = AsyncAction.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when joining room is successful, the expected callback is invoked`() {
|
||||
fun `when joining room is successful, the expected callback is invoked`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
joinAction = AsyncAction.Success(Unit),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -146,53 +145,55 @@ class JoinRoomViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Accept when JoinAuthorisationStatus is IsInvited emits the expected Event`() {
|
||||
fun `clicking on Accept when JoinAuthorisationStatus is IsInvited emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
val inviteData = anInviteData()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, null)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_accept)
|
||||
clickOn(CommonStrings.action_accept)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.AcceptInvite(inviteData))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Decline when JoinAuthorisationStatus is IsInvited emits the expected Event`() {
|
||||
fun `clicking on Decline when JoinAuthorisationStatus is IsInvited emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
val inviteData = anInviteData()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, null)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.DeclineInvite(inviteData, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Decline and block when JoinAuthorisationStatus is IsInvited and can report room, the expected callback is invoked`() {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
|
||||
val inviteData = anInviteData()
|
||||
val joinRoomState = aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, aRoomMember().toInviteSender())),
|
||||
canReportRoom = true,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
ensureCalledOnceWithParam(inviteData) {
|
||||
rule.setJoinRoomView(
|
||||
state = joinRoomState,
|
||||
onDeclineInviteAndBlockUser = it,
|
||||
runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
|
||||
val inviteData = anInviteData()
|
||||
val joinRoomState = aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, aRoomMember().toInviteSender())),
|
||||
canReportRoom = true,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.clickOn(R.string.screen_join_room_decline_and_block_button_title)
|
||||
ensureCalledOnceWithParam(inviteData) {
|
||||
setJoinRoomView(
|
||||
state = joinRoomState,
|
||||
onDeclineInviteAndBlockUser = it,
|
||||
)
|
||||
clickOn(R.string.screen_join_room_decline_and_block_button_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Decline and block when JoinAuthorisationStatus is IsInvited and cant report room, emits the expected Event`() {
|
||||
fun `clicking on Decline and block when JoinAuthorisationStatus is IsInvited and cant report room, emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
val inviteData = anInviteData()
|
||||
val joinRoomState = aJoinRoomState(
|
||||
|
|
@ -200,29 +201,29 @@ class JoinRoomViewTest {
|
|||
canReportRoom = false,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.setJoinRoomView(state = joinRoomState)
|
||||
rule.clickOn(R.string.screen_join_room_decline_and_block_button_title)
|
||||
setJoinRoomView(state = joinRoomState)
|
||||
clickOn(R.string.screen_join_room_decline_and_block_button_title)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.DeclineInvite(inviteData, true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Retry when an error occurs emits the expected Event`() {
|
||||
fun `clicking on Retry when an error occurs emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aFailureContentState(),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.RetryFetchingContent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on ok when user is unauthorized the expected callback`() {
|
||||
fun `clicking on ok when user is unauthorized the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(),
|
||||
joinAction = AsyncAction.Failure(JoinRoom.Failures.UnauthorizedJoin),
|
||||
|
|
@ -230,25 +231,25 @@ class JoinRoomViewTest {
|
|||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on forget when user is banned invokes the expected callback`() {
|
||||
fun `clicking on forget when user is banned invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomEvents>()
|
||||
rule.setJoinRoomView(
|
||||
setJoinRoomView(
|
||||
aJoinRoomState(
|
||||
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsBanned(null, null)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_join_room_forget_action)
|
||||
clickOn(R.string.screen_join_room_forget_action)
|
||||
eventsRecorder.assertSingle(JoinRoomEvents.ForgetRoom)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setJoinRoomView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setJoinRoomView(
|
||||
state: JoinRoomState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onJoinSuccess: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.knockrequests.impl.banner
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.knockrequests.impl.R
|
||||
import io.element.android.features.knockrequests.impl.data.aKnockRequestPresentable
|
||||
|
|
@ -21,35 +24,30 @@ import io.element.android.tests.testutils.EnsureNeverCalled
|
|||
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 KnockRequestsBannerViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on view on single request invoke the expected callback`() {
|
||||
fun `clicking on view on single request invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsBannerEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setKnockRequestsBannerView(
|
||||
setKnockRequestsBannerView(
|
||||
state = aKnockRequestsBannerState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onViewRequestsClick = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_single_knock_request_view_button_title)
|
||||
clickOn(R.string.screen_room_single_knock_request_view_button_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on view all when multiple requests invoke the expected callback`() {
|
||||
fun `clicking on view all when multiple requests invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsBannerEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setKnockRequestsBannerView(
|
||||
setKnockRequestsBannerView(
|
||||
state = aKnockRequestsBannerState(
|
||||
knockRequests = listOf(
|
||||
aKnockRequestPresentable(displayName = "Alice"),
|
||||
|
|
@ -60,37 +58,37 @@ class KnockRequestsBannerViewTest {
|
|||
),
|
||||
onViewRequestsClick = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_multiple_knock_requests_view_all_button_title)
|
||||
clickOn(R.string.screen_room_multiple_knock_requests_view_all_button_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on accept on a single request emit the expected event`() {
|
||||
fun `clicking on accept on a single request emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsBannerEvents>()
|
||||
rule.setKnockRequestsBannerView(
|
||||
setKnockRequestsBannerView(
|
||||
state = aKnockRequestsBannerState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_accept)
|
||||
clickOn(CommonStrings.action_accept)
|
||||
eventsRecorder.assertSingle(KnockRequestsBannerEvents.AcceptSingleRequest)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on dismiss emit the expected event`() {
|
||||
fun `clicking on dismiss emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsBannerEvents>()
|
||||
rule.setKnockRequestsBannerView(
|
||||
setKnockRequestsBannerView(
|
||||
state = aKnockRequestsBannerState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val close = rule.activity.getString(CommonStrings.action_close)
|
||||
rule.onNodeWithContentDescription(close).performClick()
|
||||
val close = activity!!.getString(CommonStrings.action_close)
|
||||
onNodeWithContentDescription(close).performClick()
|
||||
eventsRecorder.assertSingle(KnockRequestsBannerEvents.Dismiss)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setKnockRequestsBannerView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setKnockRequestsBannerView(
|
||||
state: KnockRequestsBannerState,
|
||||
onViewRequestsClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.knockrequests.impl.list
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.knockrequests.impl.R
|
||||
import io.element.android.features.knockrequests.impl.data.aKnockRequestPresentable
|
||||
|
|
@ -23,90 +26,86 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class KnockRequestsListViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke the expected callback`() {
|
||||
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on accept emit the expected event`() {
|
||||
fun `clicking on accept emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequest = aKnockRequestPresentable()
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(persistentListOf(knockRequest)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_accept)
|
||||
clickOn(CommonStrings.action_accept)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.Accept(knockRequest))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline emit the expected event`() {
|
||||
fun `clicking on decline emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequest = aKnockRequestPresentable()
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(persistentListOf(knockRequest)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.Decline(knockRequest))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline and ban emit the expected event`() {
|
||||
fun `clicking on decline and ban emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequest = aKnockRequestPresentable()
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(persistentListOf(knockRequest)),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_knock_requests_list_decline_and_ban_action_title)
|
||||
clickOn(R.string.screen_knock_requests_list_decline_and_ban_action_title)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.DeclineAndBan(knockRequest))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on accept all emit the expected event`() {
|
||||
fun `clicking on accept all emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(knockRequests),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_knock_requests_list_accept_all_button_title)
|
||||
clickOn(R.string.screen_knock_requests_list_accept_all_button_title)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.AcceptAll)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `retry on async view retry emit the expected event`() {
|
||||
fun `retry on async view retry emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(knockRequests),
|
||||
asyncAction = AsyncAction.Failure(RuntimeException("Failed to accept all")),
|
||||
|
|
@ -114,15 +113,15 @@ class KnockRequestsListViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.RetryCurrentAction)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `canceling async view emit the expected event`() {
|
||||
fun `canceling async view emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(knockRequests),
|
||||
asyncAction = AsyncAction.Failure(RuntimeException("Failed to accept all")),
|
||||
|
|
@ -130,15 +129,15 @@ class KnockRequestsListViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.ResetCurrentAction)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `confirming async view emit the expected event`() {
|
||||
fun `confirming async view emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<KnockRequestsListEvents>()
|
||||
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
|
||||
rule.setKnockRequestsListView(
|
||||
setKnockRequestsListView(
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(knockRequests),
|
||||
asyncAction = AsyncAction.ConfirmingNoParams,
|
||||
|
|
@ -146,12 +145,12 @@ class KnockRequestsListViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_knock_requests_list_accept_all_alert_confirm_button_title)
|
||||
clickOn(R.string.screen_knock_requests_list_accept_all_alert_confirm_button_title)
|
||||
eventsRecorder.assertSingle(KnockRequestsListEvents.ConfirmCurrentAction)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setKnockRequestsListView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setKnockRequestsListView(
|
||||
state: KnockRequestsListState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.desktop
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.linknewdevice.impl.R
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -18,42 +21,37 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DesktopNoticeViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aDesktopNoticeState(),
|
||||
onBackClicked = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on back button clicked - calls the expected callback`() {
|
||||
fun `on back button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aDesktopNoticeState(),
|
||||
onBackClicked = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when can continue - calls the expected callback`() {
|
||||
fun `when can continue - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aDesktopNoticeState(canContinue = true),
|
||||
onReadyToScanClick = callback,
|
||||
)
|
||||
|
|
@ -61,16 +59,16 @@ class DesktopNoticeViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `on submit button clicked - emits the Continue event`() {
|
||||
fun `on submit button clicked - emits the Continue event`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<DesktopNoticeEvent>()
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aDesktopNoticeState(eventSink = eventRecorder),
|
||||
)
|
||||
rule.clickOn(R.string.screen_link_new_device_desktop_submit)
|
||||
clickOn(R.string.screen_link_new_device_desktop_submit)
|
||||
eventRecorder.assertSingle(DesktopNoticeEvent.Continue)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setView(
|
||||
state: DesktopNoticeState,
|
||||
onBackClicked: () -> Unit = EnsureNeverCalled(),
|
||||
onReadyToScanClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -5,58 +5,56 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.error
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ErrorViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the onCancel callback`() {
|
||||
fun `on back pressed - calls the onCancel callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setErrorView(
|
||||
setErrorView(
|
||||
onCancel = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on try again button clicked - calls the expected callback`() {
|
||||
fun `on try again button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setErrorView(
|
||||
setErrorView(
|
||||
onRetry = callback
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_try_again)
|
||||
clickOn(CommonStrings.action_try_again)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on cancel button clicked - calls the expected callback`() {
|
||||
fun `on cancel button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setErrorView(
|
||||
setErrorView(
|
||||
onCancel = callback
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setErrorView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setErrorView(
|
||||
onRetry: () -> Unit = EnsureNeverCalled(),
|
||||
onCancel: () -> Unit = EnsureNeverCalled(),
|
||||
errorScreenType: ErrorScreenType = ErrorScreenType.UnknownError,
|
||||
|
|
|
|||
|
|
@ -5,13 +5,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.number
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
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.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -20,65 +23,60 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EnterNumberViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aEnterNumberState(),
|
||||
onBackClicked = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on back button clicked - calls the expected callback`() {
|
||||
fun `on back button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aEnterNumberState(),
|
||||
onBackClicked = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on continue button clicked - emits the Continue event`() {
|
||||
fun `on continue button clicked - emits the Continue event`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<EnterNumberEvent>()
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aEnterNumberState(
|
||||
number = "12",
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventRecorder.assertSingle(EnterNumberEvent.Continue)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when the number is not complete, continue button is disabled`() {
|
||||
fun `when the number is not complete, continue button is disabled`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<EnterNumberEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aEnterNumberState(
|
||||
number = "1",
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
)
|
||||
val continueStr = rule.activity.getString(CommonStrings.action_continue)
|
||||
rule.onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
val continueStr = activity!!.getString(CommonStrings.action_continue)
|
||||
onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setView(
|
||||
state: EnterNumberState,
|
||||
onBackClicked: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -5,36 +5,34 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.qrcode
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ShowQrCodeViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
onBackClick = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setView(
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.linknewdevice.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
|
|
@ -19,74 +22,69 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LinkNewDeviceRootViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the onRetry callback`() {
|
||||
fun `on back pressed - calls the onRetry callback`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<LinkNewDeviceRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLinkNewDeviceRootView(
|
||||
setLinkNewDeviceRootView(
|
||||
state = aLinkNewDeviceRootState(
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
onBackClick = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `link desktop button clicked - calls the expected callback`() {
|
||||
fun `link desktop button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<LinkNewDeviceRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLinkNewDeviceRootView(
|
||||
setLinkNewDeviceRootView(
|
||||
state = aLinkNewDeviceRootState(
|
||||
isSupported = AsyncData.Success(true),
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
onLinkDesktopDeviceClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_link_new_device_root_desktop_computer)
|
||||
clickOn(R.string.screen_link_new_device_root_desktop_computer)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `link mobile button clicked - emits the expected event`() {
|
||||
fun `link mobile button clicked - emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<LinkNewDeviceRootEvent>()
|
||||
rule.setLinkNewDeviceRootView(
|
||||
setLinkNewDeviceRootView(
|
||||
state = aLinkNewDeviceRootState(
|
||||
isSupported = AsyncData.Success(true),
|
||||
eventSink = eventRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(R.string.screen_link_new_device_root_mobile_device)
|
||||
clickOn(R.string.screen_link_new_device_root_mobile_device)
|
||||
eventRecorder.assertSingle(LinkNewDeviceRootEvent.LinkMobileDevice)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `not supported - dismiss click - invokes the expected callback`() {
|
||||
fun `not supported - dismiss click - invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<LinkNewDeviceRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLinkNewDeviceRootView(
|
||||
setLinkNewDeviceRootView(
|
||||
state = aLinkNewDeviceRootState(
|
||||
isSupported = AsyncData.Success(false),
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_dismiss)
|
||||
clickOn(CommonStrings.action_dismiss)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setLinkNewDeviceRootView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setLinkNewDeviceRootView(
|
||||
state: LinkNewDeviceRootState = aLinkNewDeviceRootState(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onLinkDesktopDeviceClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.linknewdevice.impl.screens.scan
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
|
|
@ -19,44 +22,39 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ScanQrCodeViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<ScanQrCodeEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aScanQrCodeState(
|
||||
eventSink = eventRecorder,
|
||||
),
|
||||
onBackClick = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `try again button clicked - emits the expected event`() {
|
||||
fun `try again button clicked - emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<ScanQrCodeEvent>()
|
||||
rule.setView(
|
||||
setView(
|
||||
state = aScanQrCodeState(
|
||||
scanAction = AsyncAction.Failure(AN_EXCEPTION),
|
||||
eventSink = eventRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_try_again)
|
||||
clickOn(CommonStrings.action_try_again)
|
||||
eventRecorder.assertSingle(ScanQrCodeEvent.TryAgain)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setView(
|
||||
state: ScanQrCodeState = aScanQrCodeState(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -5,15 +5,18 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.location.impl.share
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
|
|
@ -23,102 +26,98 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ShareLocationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `test back action`() {
|
||||
fun `test back action`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
state = aShareLocationState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test fab click`() {
|
||||
fun `test fab click`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.floatingActionButton.value).performClick()
|
||||
onNodeWithTag(TestTags.floatingActionButton.value).performClick()
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.StartTrackingUserLocation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission denied is displayed user can open the settings`() {
|
||||
fun `when permission denied is displayed user can open the settings`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.OpenAppSettings)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission denied is displayed user can close the dialog`() {
|
||||
fun `when permission denied is displayed user can close the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionDenied),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission rationale is displayed user can request permissions`() {
|
||||
fun `when permission rationale is displayed user can request permissions`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.RequestPermissions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission rationale is displayed user can close the dialog`() {
|
||||
fun `when permission rationale is displayed user can close the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.PermissionRationale),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when location service disabled is displayed user can open location settings`() {
|
||||
fun `when location service disabled is displayed user can open location settings`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled),
|
||||
hasLocationPermission = true,
|
||||
|
|
@ -126,14 +125,14 @@ class ShareLocationViewTest {
|
|||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.OpenLocationSettings)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when location service disabled is displayed user can close the dialog`() {
|
||||
fun `when location service disabled is displayed user can close the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShareLocationEvent>()
|
||||
rule.setShareLocationView(
|
||||
setShareLocationView(
|
||||
aShareLocationState(
|
||||
dialogState = ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.LocationServiceDisabled),
|
||||
hasLocationPermission = true,
|
||||
|
|
@ -141,12 +140,12 @@ class ShareLocationViewTest {
|
|||
),
|
||||
navigateUp = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ShareLocationEvent.DismissDialog)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setShareLocationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setShareLocationView(
|
||||
state: ShareLocationState,
|
||||
navigateUp: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.location.impl.show
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
|
||||
|
|
@ -26,115 +29,111 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ShowLocationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `test back action`() {
|
||||
fun `test back action`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
state = aShowLocationState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test share action`() {
|
||||
fun `test share action`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
val shareContentDescription = rule.activity.getString(CommonStrings.action_share)
|
||||
rule.onNodeWithContentDescription(shareContentDescription).performClick()
|
||||
val shareContentDescription = activity!!.getString(CommonStrings.action_share)
|
||||
onNodeWithContentDescription(shareContentDescription).performClick()
|
||||
// The default aStaticLocationMode uses Location(1.23, 2.34, 4f)
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.Share(Location(1.23, 2.34, 4f)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test fab click`() {
|
||||
fun `test fab click`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.floatingActionButton.value).performClick()
|
||||
onNodeWithTag(TestTags.floatingActionButton.value).performClick()
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.TrackMyLocation(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission denied is displayed user can open the settings`() {
|
||||
fun `when permission denied is displayed user can open the settings`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
constraintsDialogState = LocationConstraintsDialogState.PermissionDenied,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.OpenAppSettings)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission denied is displayed user can close the dialog`() {
|
||||
fun `when permission denied is displayed user can close the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
constraintsDialogState = LocationConstraintsDialogState.PermissionDenied,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.DismissDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission rationale is displayed user can request permissions`() {
|
||||
fun `when permission rationale is displayed user can request permissions`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
constraintsDialogState = LocationConstraintsDialogState.PermissionRationale,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.RequestPermissions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when permission rationale is displayed user can close the dialog`() {
|
||||
fun `when permission rationale is displayed user can close the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ShowLocationEvent>()
|
||||
rule.setShowLocationView(
|
||||
setShowLocationView(
|
||||
aShowLocationState(
|
||||
constraintsDialogState = LocationConstraintsDialogState.PermissionRationale,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = EnsureNeverCalled(),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ShowLocationEvent.DismissDialog)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setShowLocationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setShowLocationView(
|
||||
state: ShowLocationState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,60 +6,57 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.lockscreen.impl.unlock.keypad
|
||||
|
||||
import android.view.KeyEvent
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.hasContentDescription
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.isRoot
|
||||
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.performClick
|
||||
import androidx.compose.ui.test.performKeyInput
|
||||
import androidx.compose.ui.test.pressKey
|
||||
import androidx.compose.ui.test.requestFocus
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class PinKeypadTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on a number emits the expected event`() {
|
||||
fun `clicking on a number emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinKeypadModel>()
|
||||
rule.setPinKeyPad(onClick = eventsRecorder)
|
||||
rule.onNode(hasText("1")).performClick()
|
||||
setPinKeyPad(onClick = eventsRecorder)
|
||||
onNode(hasText("1")).performClick()
|
||||
eventsRecorder.assertSingle(PinKeypadModel.Number('1'))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the delete previous character button emits the expected event`() {
|
||||
fun `clicking on the delete previous character button emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinKeypadModel>()
|
||||
rule.setPinKeyPad(onClick = eventsRecorder)
|
||||
rule.onNode(hasContentDescription(rule.activity.getString(CommonStrings.a11y_delete))).performClick()
|
||||
setPinKeyPad(onClick = eventsRecorder)
|
||||
onNode(hasContentDescription(activity!!.getString(CommonStrings.a11y_delete))).performClick()
|
||||
eventsRecorder.assertSingle(PinKeypadModel.Back)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
@Test
|
||||
fun `typing using the hardware keyboard emits the expected events`() {
|
||||
fun `typing using the hardware keyboard emits the expected events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinKeypadModel>()
|
||||
rule.setPinKeyPad(onClick = eventsRecorder)
|
||||
rule.onNodeWithText("1").requestFocus()
|
||||
rule.onAllNodes(isRoot())[0].performKeyInput {
|
||||
setPinKeyPad(onClick = eventsRecorder)
|
||||
onNodeWithText("1").requestFocus()
|
||||
onAllNodes(isRoot())[0].performKeyInput {
|
||||
val keys = listOf(
|
||||
Key.A,
|
||||
Key.NumPad1,
|
||||
|
|
@ -118,7 +115,7 @@ class PinKeypadTest {
|
|||
)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPinKeyPad(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setPinKeyPad(
|
||||
onClick: (PinKeypadModel) -> Unit = EnsureNeverCalledWithParam(),
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.chooseaccountprovider
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.login.impl.accountprovider.anAccountProvider
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
|
|
@ -25,36 +28,31 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 ChooseAccountProviderViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<ChooseAccountProviderEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setChooseAccountProviderView(
|
||||
setChooseAccountProviderView(
|
||||
state = aChooseAccountProviderState(
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onBackClick = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `selecting an account provider emits the the expected event`() {
|
||||
fun `selecting an account provider emits the the expected event`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<ChooseAccountProviderEvents>()
|
||||
rule.setChooseAccountProviderView(
|
||||
setChooseAccountProviderView(
|
||||
state = aChooseAccountProviderState(
|
||||
accountProviders = listOf(
|
||||
ChooseAccountProviderPresenterTest.accountProvider1,
|
||||
|
|
@ -64,24 +62,24 @@ class ChooseAccountProviderViewTest {
|
|||
eventSink = eventSink,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(ChooseAccountProviderPresenterTest.accountProvider1.title).performClick()
|
||||
onNodeWithText(ChooseAccountProviderPresenterTest.accountProvider1.title).performClick()
|
||||
eventSink.assertSingle(ChooseAccountProviderEvents.SelectAccountProvider(ChooseAccountProviderPresenterTest.accountProvider1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when error is displayed - closing the dialog emits the expected event`() {
|
||||
fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<ChooseAccountProviderEvents>()
|
||||
rule.setChooseAccountProviderView(
|
||||
setChooseAccountProviderView(
|
||||
state = aChooseAccountProviderState(
|
||||
loginMode = AsyncData.Failure(AN_EXCEPTION),
|
||||
eventSink = eventSink,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventSink.assertSingle(ChooseAccountProviderEvents.ClearError)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChooseAccountProviderView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setChooseAccountProviderView(
|
||||
state: ChooseAccountProviderState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onOAuthDetails: (OAuthDetails) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,20 +6,23 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.loginpassword
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
import androidx.compose.ui.test.hasText
|
||||
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.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.test.A_PASSWORD
|
||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||
|
|
@ -30,158 +33,154 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 LoginPasswordViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke back callback`() {
|
||||
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `changing login invokes the expected event`() {
|
||||
fun `changing login invokes the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>()
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val userNameHint = rule.activity.getString(CommonStrings.common_username)
|
||||
rule.onNodeWithText(userNameHint).performTextInput(A_USER_NAME)
|
||||
val userNameHint = activity!!.getString(CommonStrings.common_username)
|
||||
onNodeWithText(userNameHint).performTextInput(A_USER_NAME)
|
||||
eventsRecorder.assertSingle(
|
||||
LoginPasswordEvents.SetLogin(A_USER_NAME)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `changing login removes new lines the expected event`() {
|
||||
fun `changing login removes new lines the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>()
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val userNameHint = rule.activity.getString(CommonStrings.common_username)
|
||||
rule.onNodeWithText(userNameHint).performTextInput("a\nb")
|
||||
val userNameHint = activity!!.getString(CommonStrings.common_username)
|
||||
onNodeWithText(userNameHint).performTextInput("a\nb")
|
||||
eventsRecorder.assertSingle(
|
||||
LoginPasswordEvents.SetLogin("ab")
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearing login invokes the expected event`() {
|
||||
fun `clearing login invokes the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>()
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
formState = aLoginFormState(A_USER_NAME),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val a11yClear = rule.activity.getString(CommonStrings.action_clear)
|
||||
rule.onNodeWithContentDescription(a11yClear).performClick()
|
||||
val a11yClear = activity!!.getString(CommonStrings.action_clear)
|
||||
onNodeWithContentDescription(a11yClear).performClick()
|
||||
eventsRecorder.assertSingle(
|
||||
LoginPasswordEvents.SetLogin("")
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `changing password invokes the expected event`() {
|
||||
fun `changing password invokes the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>()
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val userNameHint = rule.activity.getString(CommonStrings.common_password)
|
||||
rule.onNodeWithText(userNameHint).performTextInput(A_PASSWORD)
|
||||
val userNameHint = activity!!.getString(CommonStrings.common_password)
|
||||
onNodeWithText(userNameHint).performTextInput(A_PASSWORD)
|
||||
eventsRecorder.assertSingle(
|
||||
LoginPasswordEvents.SetPassword(A_PASSWORD)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reveal password makes the password visible`() {
|
||||
fun `reveal password makes the password visible`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>(expectEvents = false)
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
formState = aLoginFormState(password = A_PASSWORD),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.loginPassword.value).assert(hasText("••••••••"))
|
||||
onNodeWithTag(TestTags.loginPassword.value).assert(hasText("••••••••"))
|
||||
val resources = activity!!.resources
|
||||
// Show password
|
||||
val a11yShowPassword = rule.activity.getString(CommonStrings.a11y_show_password)
|
||||
rule.onNodeWithContentDescription(a11yShowPassword).performClick()
|
||||
rule.onNodeWithTag(TestTags.loginPassword.value).assert(hasText(A_PASSWORD))
|
||||
val a11yShowPassword = resources.getString(CommonStrings.a11y_show_password)
|
||||
onNodeWithContentDescription(a11yShowPassword).performClick()
|
||||
onNodeWithTag(TestTags.loginPassword.value).assert(hasText(A_PASSWORD))
|
||||
// Hide password
|
||||
val a11yHidePassword = rule.activity.getString(CommonStrings.a11y_hide_password)
|
||||
rule.onNodeWithContentDescription(a11yHidePassword).performClick()
|
||||
rule.onNodeWithTag(TestTags.loginPassword.value).assert(hasText("••••••••"))
|
||||
val a11yHidePassword = resources.getString(CommonStrings.a11y_hide_password)
|
||||
onNodeWithContentDescription(a11yHidePassword).performClick()
|
||||
onNodeWithTag(TestTags.loginPassword.value).assert(hasText("••••••••"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when login is empty, continue button is not enabled`() {
|
||||
fun `when login is empty, continue button is not enabled`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>(expectEvents = false)
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
formState = aLoginFormState(password = A_PASSWORD),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val continueStr = rule.activity.getString(CommonStrings.action_continue)
|
||||
rule.onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
val continueStr = activity!!.getString(CommonStrings.action_continue)
|
||||
onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when password is empty, continue button is not enabled`() {
|
||||
fun `when password is empty, continue button is not enabled`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>(expectEvents = false)
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
formState = aLoginFormState(login = A_USER_NAME),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val continueStr = rule.activity.getString(CommonStrings.action_continue)
|
||||
rule.onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
val continueStr = activity!!.getString(CommonStrings.action_continue)
|
||||
onNodeWithText(continueStr).assertIsNotEnabled()
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Continue sends expected event`() {
|
||||
fun `clicking on Continue sends expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LoginPasswordEvents>()
|
||||
rule.setLoginPasswordView(
|
||||
setLoginPasswordView(
|
||||
aLoginPasswordState(
|
||||
formState = aLoginFormState(login = A_USER_NAME, password = A_PASSWORD),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val continueStr = rule.activity.getString(CommonStrings.action_continue)
|
||||
rule.onNodeWithText(continueStr).assertIsEnabled()
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
val continueStr = activity!!.getString(CommonStrings.action_continue)
|
||||
onNodeWithText(continueStr).assertIsEnabled()
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(
|
||||
LoginPasswordEvents.Submit
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setLoginPasswordView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setLoginPasswordView(
|
||||
state: LoginPasswordState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.onboarding
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import com.google.testing.junit.testparameterinjector.KotlinTestParameters.namedTestValues
|
||||
import com.google.testing.junit.testparameterinjector.TestParameter
|
||||
import io.element.android.features.login.impl.R
|
||||
|
|
@ -29,22 +32,17 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestParameterInjector
|
||||
|
||||
@RunWith(RobolectricTestParameterInjector::class)
|
||||
class OnboardingViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `when can create account - clicking on create account calls the expected callback`() {
|
||||
fun `when can create account - clicking on create account calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canCreateAccount = true,
|
||||
showDeveloperSettings = false,
|
||||
|
|
@ -52,40 +50,40 @@ class OnboardingViewTest {
|
|||
),
|
||||
onCreateAccount = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_onboarding_sign_up)
|
||||
clickOn(R.string.screen_onboarding_sign_up)
|
||||
// Developer settings should not be shown
|
||||
val developerSettingsText = rule.activity.getString(CommonStrings.common_developer_options)
|
||||
rule.onNodeWithContentDescription(developerSettingsText).assertDoesNotExist()
|
||||
val developerSettingsText = activity!!.getString(CommonStrings.common_developer_options)
|
||||
onNodeWithContentDescription(developerSettingsText).assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when can go back - clicking on back calls the expected callback`() {
|
||||
fun `when can go back - clicking on back calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
isAddingAccount = true,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when can login with QR code - clicking on sign in with QR code calls the expected callback`() {
|
||||
fun `when can login with QR code - clicking on sign in with QR code calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canLoginWithQrCode = true,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onSignInWithQrCode = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_onboarding_sign_in_with_qr_code)
|
||||
clickOn(R.string.screen_onboarding_sign_in_with_qr_code)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,10 +93,10 @@ class OnboardingViewTest {
|
|||
"can search account provider" to false,
|
||||
"cannot search account provider" to true,
|
||||
)
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canLoginWithQrCode = true,
|
||||
mustChooseAccountProvider = mustChooseAccountProvider,
|
||||
|
|
@ -106,7 +104,7 @@ class OnboardingViewTest {
|
|||
),
|
||||
onSignIn = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_onboarding_sign_in_manually)
|
||||
clickOn(R.string.screen_onboarding_sign_in_manually)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,10 +114,10 @@ class OnboardingViewTest {
|
|||
"can search account provider" to false,
|
||||
"cannot search account provider" to true,
|
||||
)
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canLoginWithQrCode = false,
|
||||
canCreateAccount = false,
|
||||
|
|
@ -128,89 +126,89 @@ class OnboardingViewTest {
|
|||
),
|
||||
onSignIn = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when sign in to pre defined account provider - clicking on button emits the expected event`() {
|
||||
fun `when sign in to pre defined account provider - clicking on button emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>()
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
defaultAccountProvider = "element.io",
|
||||
eventSink = eventSink,
|
||||
),
|
||||
)
|
||||
val buttonText = rule.activity.getString(R.string.screen_onboarding_sign_in_to, "element.io")
|
||||
rule.onNodeWithText(buttonText).performClick()
|
||||
val buttonText = activity!!.getString(R.string.screen_onboarding_sign_in_to, "element.io")
|
||||
onNodeWithText(buttonText).performClick()
|
||||
eventSink.assertSingle(OnBoardingEvents.OnSignIn("element.io"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when error is displayed - closing the dialog emits the expected event`() {
|
||||
fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>()
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
defaultAccountProvider = "element.io",
|
||||
loginMode = AsyncData.Failure(AN_EXCEPTION),
|
||||
eventSink = eventSink,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventSink.assertSingle(OnBoardingEvents.ClearError)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on report a problem calls the sign in callback`() {
|
||||
fun `clicking on report a problem calls the sign in callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canReportBug = true,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onReportProblem = callback,
|
||||
)
|
||||
val text = rule.activity.getString(CommonStrings.common_report_a_problem)
|
||||
rule.onNodeWithText(text).assertExists()
|
||||
rule.clickOn(CommonStrings.common_report_a_problem)
|
||||
val text = activity!!.getString(CommonStrings.common_report_a_problem)
|
||||
onNodeWithText(text).assertExists()
|
||||
clickOn(CommonStrings.common_report_a_problem)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on settings calls the developer settings callback`() {
|
||||
fun `clicking on settings calls the developer settings callback`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
showDeveloperSettings = true,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onDeveloperSettingsClick = callback,
|
||||
)
|
||||
val text = rule.activity.getString(CommonStrings.common_developer_options)
|
||||
rule.onNodeWithContentDescription(text).performClick()
|
||||
val text = activity!!.getString(CommonStrings.common_developer_options)
|
||||
onNodeWithContentDescription(text).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot report a problem when the feature is disabled`() {
|
||||
fun `cannot report a problem when the feature is disabled`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canReportBug = false,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
)
|
||||
val text = rule.activity.getString(CommonStrings.common_report_a_problem)
|
||||
rule.onNodeWithText(text).assertDoesNotExist()
|
||||
val text = activity!!.getString(CommonStrings.common_report_a_problem)
|
||||
onNodeWithText(text).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when success PasswordLogin - the expected callback is invoked and the event is received`() {
|
||||
fun `when success PasswordLogin - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>()
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
loginMode = AsyncData.Success(LoginMode.PasswordLogin),
|
||||
eventSink = eventSink,
|
||||
|
|
@ -222,11 +220,11 @@ class OnboardingViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when success Oidc - the expected callback is invoked and the event is received`() {
|
||||
fun `when success Oidc - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>()
|
||||
val oAuthDetails = OAuthDetails("aUrl")
|
||||
ensureCalledOnceWithParam(oAuthDetails) { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
loginMode = AsyncData.Success(LoginMode.OAuth(oAuthDetails)),
|
||||
eventSink = eventSink,
|
||||
|
|
@ -238,11 +236,11 @@ class OnboardingViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when success AccountCreation - the expected callback is invoked and the event is received`() {
|
||||
fun `when success AccountCreation - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>()
|
||||
val oAuthDetails = OAuthDetails("aUrl")
|
||||
ensureCalledOnceWithParam(oAuthDetails.url) { callback ->
|
||||
rule.setOnboardingView(
|
||||
setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
loginMode = AsyncData.Success(LoginMode.AccountCreation("aUrl")),
|
||||
eventSink = eventSink,
|
||||
|
|
@ -253,7 +251,7 @@ class OnboardingViewTest {
|
|||
eventSink.assertSingle(OnBoardingEvents.ClearError)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setOnboardingView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setOnboardingView(
|
||||
state: OnBoardingState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onDeveloperSettingsClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,49 +6,47 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.qrcode.confirmation
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class QrCodeConfirmationViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeConfirmationView(
|
||||
setQrCodeConfirmationView(
|
||||
step = QrCodeConfirmationStep.DisplayCheckCode("12"),
|
||||
onCancel = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on Cancel button clicked - calls the expected callback`() {
|
||||
fun `on Cancel button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeConfirmationView(
|
||||
setQrCodeConfirmationView(
|
||||
step = QrCodeConfirmationStep.DisplayVerificationCode("123456"),
|
||||
onCancel = callback
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setQrCodeConfirmationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setQrCodeConfirmationView(
|
||||
step: QrCodeConfirmationStep,
|
||||
onCancel: () -> Unit
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.qrcode.error
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.login.impl.qrcode.QrCodeErrorScreenType
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -18,47 +21,42 @@ import io.element.android.tests.testutils.EnsureNeverCalled
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class QrCodeErrorViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the onCancel callback`() {
|
||||
fun `on back pressed - calls the onCancel callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeErrorView(
|
||||
setQrCodeErrorView(
|
||||
onCancel = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on try again button clicked - calls the expected callback`() {
|
||||
fun `on try again button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeErrorView(
|
||||
setQrCodeErrorView(
|
||||
onRetry = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_try_again)
|
||||
clickOn(CommonStrings.action_try_again)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on cancel button clicked - calls the expected callback`() {
|
||||
fun `on cancel button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeErrorView(
|
||||
setQrCodeErrorView(
|
||||
onCancel = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setQrCodeErrorView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setQrCodeErrorView(
|
||||
onRetry: () -> Unit = EnsureNeverCalled(),
|
||||
onCancel: () -> Unit = EnsureNeverCalled(),
|
||||
errorScreenType: QrCodeErrorScreenType = QrCodeErrorScreenType.UnknownError,
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.qrcode.intro
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.login.impl.R
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -19,42 +22,37 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class QrCodeIntroViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeIntroView(
|
||||
setQrCodeIntroView(
|
||||
state = aQrCodeIntroState(),
|
||||
onBackClicked = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on back button clicked - calls the expected callback`() {
|
||||
fun `on back button clicked - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeIntroView(
|
||||
setQrCodeIntroView(
|
||||
state = aQrCodeIntroState(),
|
||||
onBackClicked = callback
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when can continue - calls the expected callback`() {
|
||||
fun `when can continue - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeIntroView(
|
||||
setQrCodeIntroView(
|
||||
state = aQrCodeIntroState(canContinue = true),
|
||||
onContinue = callback
|
||||
)
|
||||
|
|
@ -62,16 +60,16 @@ class QrCodeIntroViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `on submit button clicked - emits the Continue event`() {
|
||||
fun `on submit button clicked - emits the Continue event`() = runAndroidComposeUiTest {
|
||||
val eventRecorder = EventsRecorder<QrCodeIntroEvents>()
|
||||
rule.setQrCodeIntroView(
|
||||
setQrCodeIntroView(
|
||||
state = aQrCodeIntroState(eventSink = eventRecorder),
|
||||
)
|
||||
rule.clickOn(R.string.screen_qr_code_login_initial_state_button_title)
|
||||
clickOn(R.string.screen_qr_code_login_initial_state_button_title)
|
||||
eventRecorder.assertSingle(QrCodeIntroEvents.Continue)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setQrCodeIntroView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setQrCodeIntroView(
|
||||
state: QrCodeIntroState,
|
||||
onBackClicked: () -> Unit = EnsureNeverCalled(),
|
||||
onContinue: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.login.impl.screens.qrcode.scan
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -24,16 +27,11 @@ import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
|||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class QrCodeScanViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
private var provider: ProcessCameraProvider? = null
|
||||
|
||||
@Before
|
||||
|
|
@ -48,28 +46,28 @@ class QrCodeScanViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `on back pressed - calls the expected callback`() {
|
||||
fun `on back pressed - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setQrCodeScanView(
|
||||
setQrCodeScanView(
|
||||
state = aQrCodeScanState(),
|
||||
onBackClick = callback
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on QR code data ready - calls the expected callback`() {
|
||||
fun `on QR code data ready - calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val data = FakeMatrixQrCodeLoginData()
|
||||
ensureCalledOnceWithParam<MatrixQrCodeLoginData>(data) { callback ->
|
||||
rule.setQrCodeScanView(
|
||||
setQrCodeScanView(
|
||||
state = aQrCodeScanState(authenticationAction = AsyncAction.Success(data)),
|
||||
onQrCodeDataReady = callback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setQrCodeScanView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setQrCodeScanView(
|
||||
state: QrCodeScanState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onQrCodeDataReady: (MatrixQrCodeLoginData) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.logout.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
|
|
@ -21,97 +24,93 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LogoutViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on logout sends a LogoutEvents`() {
|
||||
fun `clicking on logout sends a LogoutEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>()
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_signout)
|
||||
clickOn(CommonStrings.action_signout)
|
||||
eventsRecorder.assertSingle(LogoutEvents.Logout(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `confirming logout sends a LogoutEvents`() {
|
||||
fun `confirming logout sends a LogoutEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>()
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
logoutAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(LogoutEvents.Logout(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke back callback`() {
|
||||
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on confirm after error sends a LogoutEvents`() {
|
||||
fun `clicking on confirm after error sends a LogoutEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>()
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
logoutAction = AsyncAction.Failure(Exception("Failed to logout")),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_signout_anyway)
|
||||
clickOn(CommonStrings.action_signout_anyway)
|
||||
eventsRecorder.assertSingle(LogoutEvents.Logout(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel after error sends a LogoutEvents`() {
|
||||
fun `clicking on cancel after error sends a LogoutEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>()
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
logoutAction = AsyncAction.Failure(Exception("Failed to logout")),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(LogoutEvents.CloseDialogs)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `last session setting button invoke onChangeRecoveryKeyClicked`() {
|
||||
fun `last session setting button invoke onChangeRecoveryKeyClicked`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LogoutEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setLogoutView(
|
||||
setLogoutView(
|
||||
aLogoutState(
|
||||
isLastDevice = true,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onChangeRecoveryKeyClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_settings)
|
||||
clickOn(CommonStrings.common_settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setLogoutView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setLogoutView(
|
||||
state: LogoutState,
|
||||
onChangeRecoveryKeyClick: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.logout.impl.direct
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutEvents
|
||||
import io.element.android.features.logout.api.direct.DirectLogoutState
|
||||
|
|
@ -21,83 +24,79 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
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
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DefaultDirectLogoutViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on confirm logout sends expected Event`() {
|
||||
fun `clicking on confirm logout sends expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DirectLogoutEvents>()
|
||||
rule.setDefaultDirectLogoutView(
|
||||
setDefaultDirectLogoutView(
|
||||
state = aDirectLogoutState(
|
||||
logoutAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_signout)
|
||||
clickOn(CommonStrings.action_signout)
|
||||
eventsRecorder.assertSingle(DirectLogoutEvents.Logout(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel logout sends expected Event`() {
|
||||
fun `clicking on cancel logout sends expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DirectLogoutEvents>()
|
||||
rule.setDefaultDirectLogoutView(
|
||||
setDefaultDirectLogoutView(
|
||||
state = aDirectLogoutState(
|
||||
logoutAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
|
||||
}
|
||||
|
||||
@Ignore("Pressing back key should dismiss the dialog, and so generate the expected event, but it's not the case.")
|
||||
@Test
|
||||
fun `clicking on back invoke back callback`() {
|
||||
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DirectLogoutEvents>()
|
||||
rule.setDefaultDirectLogoutView(
|
||||
setDefaultDirectLogoutView(
|
||||
state = aDirectLogoutState(
|
||||
logoutAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on confirm after error sends expected Event`() {
|
||||
fun `clicking on confirm after error sends expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DirectLogoutEvents>()
|
||||
rule.setDefaultDirectLogoutView(
|
||||
setDefaultDirectLogoutView(
|
||||
state = aDirectLogoutState(
|
||||
logoutAction = AsyncAction.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_signout_anyway)
|
||||
clickOn(CommonStrings.action_signout_anyway)
|
||||
eventsRecorder.assertSingle(DirectLogoutEvents.Logout(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel after error sends expected Event`() {
|
||||
fun `clicking on cancel after error sends expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DirectLogoutEvents>()
|
||||
rule.setDefaultDirectLogoutView(
|
||||
setDefaultDirectLogoutView(
|
||||
state = aDirectLogoutState(
|
||||
logoutAction = AsyncAction.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setDefaultDirectLogoutView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setDefaultDirectLogoutView(
|
||||
state: DirectLogoutState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.longClick
|
||||
import androidx.compose.ui.test.onAllNodesWithContentDescription
|
||||
import androidx.compose.ui.test.onAllNodesWithTag
|
||||
|
|
@ -25,6 +27,7 @@ import androidx.compose.ui.test.onNodeWithText
|
|||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import androidx.compose.ui.test.swipeRight
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.emojibasebindings.Emoji
|
||||
|
|
@ -78,82 +81,78 @@ import io.element.android.tests.testutils.pressBack
|
|||
import io.element.android.tests.testutils.setSafeContent
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MessagesViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke expected callback`() {
|
||||
fun `clicking on back invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on room name invoke expected callback`() {
|
||||
fun `clicking on room name invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onRoomDetailsClick = callback,
|
||||
)
|
||||
rule.onNodeWithText(state.roomName.orEmpty(), useUnmergedTree = true).performClick()
|
||||
onNodeWithText(state.roomName.orEmpty(), useUnmergedTree = true).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on join call invoke expected callback`() {
|
||||
fun `clicking on join call invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnceWithParam(false) { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onJoinCallClick = callback,
|
||||
)
|
||||
val joinCallContentDescription = rule.activity.getString(CommonStrings.a11y_start_call)
|
||||
rule.onNodeWithContentDescription(joinCallContentDescription).performClick()
|
||||
val joinCallContentDescription = activity!!.getString(CommonStrings.a11y_start_call)
|
||||
onNodeWithContentDescription(joinCallContentDescription).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on join voice call invoke expected callback`() {
|
||||
fun `clicking on join voice call invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder,
|
||||
roomCallState = aStandByCallState(isDM = true)
|
||||
)
|
||||
ensureCalledOnceWithParam(true) { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onJoinCallClick = callback,
|
||||
)
|
||||
val joinVoiceCallContentDescription = rule.activity.getString(CommonStrings.a11y_start_voice_call)
|
||||
rule.onNodeWithContentDescription(joinVoiceCallContentDescription).performClick()
|
||||
val joinVoiceCallContentDescription = activity!!.getString(CommonStrings.a11y_start_voice_call)
|
||||
onNodeWithContentDescription(joinVoiceCallContentDescription).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on an Event invoke expected callback`() {
|
||||
fun `clicking on an Event invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -167,12 +166,12 @@ class MessagesViewTest {
|
|||
expectedParam2 = timelineItem,
|
||||
result = true,
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onEventClick = callback,
|
||||
)
|
||||
// Cannot perform click on "Text", it's not detected. Use tag instead
|
||||
rule.onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performClick()
|
||||
onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performClick()
|
||||
callback.assertSuccess()
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +201,7 @@ class MessagesViewTest {
|
|||
userHasPermissionToRedactOther: Boolean = false,
|
||||
userHasPermissionToSendReaction: Boolean = false,
|
||||
userCanPinEvent: Boolean = false,
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ActionListEvent>()
|
||||
val state = aMessagesState(
|
||||
actionListState = anActionListState(
|
||||
|
|
@ -220,11 +219,11 @@ class MessagesViewTest {
|
|||
),
|
||||
)
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
// Cannot perform click on "Text", it's not detected. Use tag instead
|
||||
rule.onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performTouchInput { longClick() }
|
||||
onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performTouchInput { longClick() }
|
||||
eventsRecorder.assertSingle(
|
||||
ActionListEvent.ComputeForMessage(
|
||||
event = timelineItem,
|
||||
|
|
@ -235,7 +234,7 @@ class MessagesViewTest {
|
|||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on a read receipt list emits the expected Event`() {
|
||||
fun `clicking on a read receipt list emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReadReceiptBottomSheetEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -255,10 +254,10 @@ class MessagesViewTest {
|
|||
),
|
||||
)
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.messageReadReceipts.value, useUnmergedTree = true).performClick()
|
||||
onNodeWithTag(TestTags.messageReadReceipts.value, useUnmergedTree = true).performClick()
|
||||
eventsRecorder.assertSingle(ReadReceiptBottomSheetEvent.EventSelected(timelineItem))
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +271,7 @@ class MessagesViewTest {
|
|||
swipeTest(userHasPermissionToSendMessage = false)
|
||||
}
|
||||
|
||||
private fun swipeTest(userHasPermissionToSendMessage: Boolean) {
|
||||
private fun swipeTest(userHasPermissionToSendMessage: Boolean) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
val canBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = true)
|
||||
val cannotBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = false)
|
||||
|
|
@ -285,10 +284,10 @@ class MessagesViewTest {
|
|||
),
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
rule.onAllNodesWithTag(TestTags.messageBubble.value).apply {
|
||||
onAllNodesWithTag(TestTags.messageBubble.value).apply {
|
||||
onFirst().performTouchInput { swipeRight(endX = 200f) }
|
||||
onLast().performTouchInput { swipeRight(endX = 200f) }
|
||||
}
|
||||
|
|
@ -300,7 +299,7 @@ class MessagesViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on send location invoke expected callback`() {
|
||||
fun `clicking on send location invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
composerState = aMessageComposerState(
|
||||
|
|
@ -309,16 +308,16 @@ class MessagesViewTest {
|
|||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onSendLocationClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_attachment_source_location)
|
||||
clickOn(R.string.screen_room_attachment_source_location)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on create poll invoke expected callback`() {
|
||||
fun `clicking on create poll invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
composerState = aMessageComposerState(
|
||||
|
|
@ -327,25 +326,25 @@ class MessagesViewTest {
|
|||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onCreatePollClick = callback,
|
||||
)
|
||||
// Then click on the poll action
|
||||
rule.clickOn(R.string.screen_room_attachment_source_poll)
|
||||
clickOn(R.string.screen_room_attachment_source_poll)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on the avatar of the sender of an Event emits the expected event`() {
|
||||
fun `clicking on the avatar of the sender of an Event emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
val timelineEvent = state.timelineState.timelineItems.filterIsInstance<TimelineItem.Event>().first()
|
||||
rule.setMessagesView(state = state)
|
||||
rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
|
||||
setMessagesView(state = state)
|
||||
onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
|
||||
eventsRecorder.assertSingle(
|
||||
MessagesEvent.OnUserClicked(
|
||||
MatrixUser(
|
||||
|
|
@ -359,12 +358,12 @@ class MessagesViewTest {
|
|||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on the display name of the sender of an Event emits expected event`() {
|
||||
fun `clicking on the display name of the sender of an Event emits expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
val state = aMessagesState(eventSink = eventsRecorder)
|
||||
val timelineEvent = state.timelineState.timelineItems.filterIsInstance<TimelineItem.Event>().first()
|
||||
rule.setMessagesView(state = state)
|
||||
rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
|
||||
setMessagesView(state = state)
|
||||
onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
|
||||
eventsRecorder.assertSingle(
|
||||
MessagesEvent.OnUserClicked(
|
||||
MatrixUser(
|
||||
|
|
@ -377,7 +376,7 @@ class MessagesViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `selecting a action on a message emits the expected Event`() {
|
||||
fun `selecting a action on a message emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
val state = aMessagesState(
|
||||
eventSink = eventsRecorder
|
||||
|
|
@ -395,17 +394,17 @@ class MessagesViewTest {
|
|||
)
|
||||
),
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = stateWithMessageAction,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_edit)
|
||||
clickOn(CommonStrings.action_edit)
|
||||
// Give time for the close animation to complete
|
||||
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
eventsRecorder.assertSingle(MessagesEvent.HandleAction(TimelineItemAction.Edit, timelineItem))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a reaction emits the expected Event`() {
|
||||
fun `clicking on a reaction emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -414,10 +413,10 @@ class MessagesViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
rule.onAllNodesWithText(
|
||||
onAllNodesWithText(
|
||||
text = "👍️",
|
||||
useUnmergedTree = true,
|
||||
).onFirst().performClick()
|
||||
|
|
@ -425,7 +424,7 @@ class MessagesViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `long clicking on a reaction emits the expected Event`() {
|
||||
fun `long clicking on a reaction emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReactionSummaryEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -437,10 +436,10 @@ class MessagesViewTest {
|
|||
),
|
||||
)
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
rule.onAllNodesWithText(
|
||||
onAllNodesWithText(
|
||||
text = "👍️",
|
||||
useUnmergedTree = true,
|
||||
).onFirst().performTouchInput { longClick() }
|
||||
|
|
@ -448,7 +447,7 @@ class MessagesViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on more reaction emits the expected Event`() {
|
||||
fun `clicking on more reaction emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<CustomReactionEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -459,16 +458,16 @@ class MessagesViewTest {
|
|||
),
|
||||
)
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
)
|
||||
val moreReactionContentDescription = rule.activity.getString(R.string.screen_room_timeline_add_reaction)
|
||||
rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
|
||||
val moreReactionContentDescription = activity!!.getString(R.string.screen_room_timeline_add_reaction)
|
||||
onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
|
||||
eventsRecorder.assertSingle(CustomReactionEvent.ShowCustomReactionSheet(timelineItem))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on more reaction from action list emits the expected Event`() {
|
||||
fun `clicking on more reaction from action list emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<CustomReactionEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(
|
||||
|
|
@ -491,18 +490,18 @@ class MessagesViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = stateWithActionListState,
|
||||
)
|
||||
val moreReactionContentDescription = rule.activity.getString(CommonStrings.a11y_react_with_other_emojis)
|
||||
rule.onNodeWithContentDescription(moreReactionContentDescription).performClick()
|
||||
val moreReactionContentDescription = activity!!.getString(CommonStrings.a11y_react_with_other_emojis)
|
||||
onNodeWithContentDescription(moreReactionContentDescription).performClick()
|
||||
// Give time for the close animation to complete
|
||||
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
eventsRecorder.assertSingle(CustomReactionEvent.ShowCustomReactionSheet(timelineItem))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on verified user send failure from action list emits the expected Event`() {
|
||||
fun `clicking on verified user send failure from action list emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
val state = aMessagesState()
|
||||
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||
|
|
@ -519,21 +518,21 @@ class MessagesViewTest {
|
|||
),
|
||||
timelineState = aTimelineState(eventSink = eventsRecorder)
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = stateWithActionListState,
|
||||
)
|
||||
// Clear initial 'LoadMore' event emitted when setting the state
|
||||
eventsRecorder.clear()
|
||||
|
||||
val verifiedUserSendFailure = rule.activity.getString(CommonStrings.screen_timeline_item_menu_send_failure_changed_identity, "Alice")
|
||||
rule.onNodeWithText(verifiedUserSendFailure).performClick()
|
||||
val verifiedUserSendFailure = activity!!.getString(CommonStrings.screen_timeline_item_menu_send_failure_changed_identity, "Alice")
|
||||
onNodeWithText(verifiedUserSendFailure).performClick()
|
||||
// Give time for the close animation to complete
|
||||
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
eventsRecorder.assertSingle(TimelineEvent.ComputeVerifiedUserSendFailure(timelineItem))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a custom emoji emits the expected Events`() {
|
||||
fun `clicking on a custom emoji emits the expected Events`() = runAndroidComposeUiTest {
|
||||
val aUnicode = "🙈"
|
||||
val customReactionStateEventsRecorder = EventsRecorder<CustomReactionEvent>()
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>()
|
||||
|
|
@ -563,18 +562,18 @@ class MessagesViewTest {
|
|||
eventSink = customReactionStateEventsRecorder
|
||||
),
|
||||
)
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = stateWithCustomReactionState,
|
||||
)
|
||||
rule.onNodeWithText(aUnicode, useUnmergedTree = true).performClick()
|
||||
onNodeWithText(aUnicode, useUnmergedTree = true).performClick()
|
||||
// Give time for the close animation to complete
|
||||
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||
customReactionStateEventsRecorder.assertSingle(CustomReactionEvent.DismissCustomReactionSheet)
|
||||
eventsRecorder.assertSingle(MessagesEvent.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on pinned messages banner emits the expected Event`() {
|
||||
fun `clicking on pinned messages banner emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
val state = aMessagesState(
|
||||
timelineState = aTimelineState(eventSink = eventsRecorder),
|
||||
|
|
@ -587,16 +586,16 @@ class MessagesViewTest {
|
|||
),
|
||||
),
|
||||
)
|
||||
rule.setMessagesView(state = state)
|
||||
setMessagesView(state = state)
|
||||
// Clear initial 'LoadMore' event emitted when setting the state
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.onNodeWithText("This is a pinned message").performClick()
|
||||
onNodeWithText("This is a pinned message").performClick()
|
||||
eventsRecorder.assertSingle(TimelineEvent.FocusOnEvent(AN_EVENT_ID, debounce = FOCUS_ON_PINNED_EVENT_DEBOUNCE_DURATION_IN_MILLIS.milliseconds))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on successor room button emits expected event`() {
|
||||
fun `clicking on successor room button emits expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
val successorRoomId = RoomId("!successor:server.org")
|
||||
val state = aMessagesState(
|
||||
|
|
@ -606,18 +605,18 @@ class MessagesViewTest {
|
|||
),
|
||||
timelineState = aTimelineState(eventSink = eventsRecorder)
|
||||
)
|
||||
rule.setMessagesView(state = state)
|
||||
setMessagesView(state = state)
|
||||
// Clear initial 'LoadMore' event emitted when setting the state
|
||||
eventsRecorder.clear()
|
||||
|
||||
val text = rule.activity.getString(R.string.screen_room_timeline_tombstoned_room_action)
|
||||
val text = activity!!.getString(R.string.screen_room_timeline_tombstoned_room_action)
|
||||
// The bottomsheet subcompose seems to make the node to appear twice
|
||||
rule.onAllNodesWithText(text).onFirst().performClick()
|
||||
onAllNodesWithText(text).onFirst().performClick()
|
||||
eventsRecorder.assertSingle(TimelineEvent.NavigateToPredecessorOrSuccessorRoom(successorRoomId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on threads list button calls the expected function`() {
|
||||
fun `clicking on threads list button calls the expected function`() = runAndroidComposeUiTest {
|
||||
val state = aMessagesState(
|
||||
threads = MessagesState.Threads(
|
||||
hasThreads = true,
|
||||
|
|
@ -625,28 +624,28 @@ class MessagesViewTest {
|
|||
)
|
||||
)
|
||||
val onThreadsListClicked = lambdaRecorder<Unit> {}
|
||||
rule.setMessagesView(
|
||||
setMessagesView(
|
||||
state = state,
|
||||
onThreadsListClicked = onThreadsListClicked,
|
||||
)
|
||||
rule.onNodeWithContentDescription("Threads").performClick()
|
||||
onNodeWithContentDescription("Threads").performClick()
|
||||
onThreadsListClicked.assertions().isCalledOnce()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no banner shown when there is no successor room`() {
|
||||
fun `no banner shown when there is no successor room`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
|
||||
val state = aMessagesState(
|
||||
successorRoom = null,
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
rule.setMessagesView(state = state)
|
||||
rule.assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_message)
|
||||
rule.assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_action)
|
||||
setMessagesView(state = state)
|
||||
assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_message)
|
||||
assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMessagesView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setMessagesView(
|
||||
state: MessagesState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onRoomDetailsClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.crypto.identity
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.designsystem.components.avatar.anAvatarData
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
|
|
@ -21,19 +24,15 @@ import io.element.android.libraries.matrix.ui.room.RoomMemberIdentityStateChange
|
|||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IdentityChangeStateViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `show and resolve pin violation`() {
|
||||
fun `show and resolve pin violation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IdentityChangeEvent>()
|
||||
rule.setIdentityChangeStateView(
|
||||
setIdentityChangeStateView(
|
||||
state = anIdentityChangeState(
|
||||
listOf(
|
||||
RoomMemberIdentityStateChange(
|
||||
|
|
@ -45,18 +44,18 @@ class IdentityChangeStateViewTest {
|
|||
),
|
||||
)
|
||||
|
||||
rule.onNodeWithText("identity was reset", substring = true).assertExists("should display pin violation warning")
|
||||
rule.onNodeWithText("@alice:localhost", substring = true).assertExists("should display user mxid")
|
||||
rule.onNodeWithText("Alice", substring = true).assertExists("should display user displayname")
|
||||
onNodeWithText("identity was reset", substring = true).assertExists("should display pin violation warning")
|
||||
onNodeWithText("@alice:localhost", substring = true).assertExists("should display user mxid")
|
||||
onNodeWithText("Alice", substring = true).assertExists("should display user displayname")
|
||||
|
||||
rule.clickOn(res = CommonStrings.action_dismiss)
|
||||
clickOn(res = CommonStrings.action_dismiss)
|
||||
eventsRecorder.assertSingle(IdentityChangeEvent.PinIdentity(UserId("@alice:localhost")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `show and resolve verification violation`() {
|
||||
fun `show and resolve verification violation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IdentityChangeEvent>()
|
||||
rule.setIdentityChangeStateView(
|
||||
setIdentityChangeStateView(
|
||||
state = anIdentityChangeState(
|
||||
listOf(
|
||||
RoomMemberIdentityStateChange(
|
||||
|
|
@ -68,17 +67,17 @@ class IdentityChangeStateViewTest {
|
|||
),
|
||||
)
|
||||
|
||||
rule.onNodeWithText("identity was reset", substring = true).assertExists("should display verification violation warning")
|
||||
rule.onNodeWithText("@alice:localhost", substring = true).assertExists("should display user mxid")
|
||||
rule.onNodeWithText("Alice", substring = true).assertExists("should display user displayname")
|
||||
onNodeWithText("identity was reset", substring = true).assertExists("should display verification violation warning")
|
||||
onNodeWithText("@alice:localhost", substring = true).assertExists("should display user mxid")
|
||||
onNodeWithText("Alice", substring = true).assertExists("should display user displayname")
|
||||
|
||||
rule.clickOn(res = CommonStrings.crypto_identity_change_withdraw_verification_action)
|
||||
clickOn(res = CommonStrings.crypto_identity_change_withdraw_verification_action)
|
||||
eventsRecorder.assertSingle(IdentityChangeEvent.WithdrawVerification(UserId("@alice:localhost")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Should not show any banner if no violations`() {
|
||||
rule.setIdentityChangeStateView(
|
||||
fun `Should not show any banner if no violations`() = runAndroidComposeUiTest {
|
||||
setIdentityChangeStateView(
|
||||
state = anIdentityChangeState(
|
||||
listOf(
|
||||
RoomMemberIdentityStateChange(
|
||||
|
|
@ -93,10 +92,10 @@ class IdentityChangeStateViewTest {
|
|||
),
|
||||
)
|
||||
|
||||
rule.onNodeWithText("identity was reset", substring = true).assertDoesNotExist()
|
||||
onNodeWithText("identity was reset", substring = true).assertDoesNotExist()
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setIdentityChangeStateView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setIdentityChangeStateView(
|
||||
state: IdentityChangeState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,54 +6,53 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.crypto.sendfailure.resolve
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ResolveVerifiedUserSendFailureViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on resolve and resend emit the expected event`() {
|
||||
fun `clicking on resolve and resend emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResolveVerifiedUserSendFailureEvent>()
|
||||
rule.setResolveVerifiedUserSendFailureView(
|
||||
setResolveVerifiedUserSendFailureView(
|
||||
state = aResolveVerifiedUserSendFailureState(
|
||||
verifiedUserSendFailure = aChangedIdentitySendFailure(),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
|
||||
rule.clickOn(res = CommonStrings.screen_resolve_send_failure_changed_identity_primary_button_title)
|
||||
clickOn(res = CommonStrings.screen_resolve_send_failure_changed_identity_primary_button_title)
|
||||
eventsRecorder.assertSingle(ResolveVerifiedUserSendFailureEvent.ResolveAndResend)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on retry emit the expected event`() {
|
||||
fun `clicking on retry emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResolveVerifiedUserSendFailureEvent>()
|
||||
rule.setResolveVerifiedUserSendFailureView(
|
||||
setResolveVerifiedUserSendFailureView(
|
||||
state = aResolveVerifiedUserSendFailureState(
|
||||
verifiedUserSendFailure = aChangedIdentitySendFailure(),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
|
||||
rule.clickOn(res = CommonStrings.action_retry)
|
||||
clickOn(res = CommonStrings.action_retry)
|
||||
eventsRecorder.assertSingle(ResolveVerifiedUserSendFailureEvent.Retry)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setResolveVerifiedUserSendFailureView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setResolveVerifiedUserSendFailureView(
|
||||
state: ResolveVerifiedUserSendFailureState,
|
||||
) {
|
||||
setSafeContent {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.link
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -19,51 +22,46 @@ 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.wysiwyg.link.Link
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LinkViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel emits the expected event`() {
|
||||
fun `clicking on cancel emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LinkEvent>()
|
||||
rule.setLinkView(
|
||||
setLinkView(
|
||||
aLinkState(
|
||||
linkClick = ConfirmingLinkClick(aLink),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(
|
||||
LinkEvent.Cancel
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on continue emits the expected event`() {
|
||||
fun `clicking on continue emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LinkEvent>()
|
||||
rule.setLinkView(
|
||||
setLinkView(
|
||||
aLinkState(
|
||||
linkClick = ConfirmingLinkClick(aLink),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(
|
||||
LinkEvent.Confirm
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `success state invokes the callback and emits the expected event`() {
|
||||
fun `success state invokes the callback and emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<LinkEvent>()
|
||||
ensureCalledOnceWithParam(aLink) { callback ->
|
||||
rule.setLinkView(
|
||||
setLinkView(
|
||||
aLinkState(
|
||||
linkClick = AsyncAction.Success(aLink),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -77,7 +75,7 @@ class LinkViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setLinkView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setLinkView(
|
||||
state: LinkState,
|
||||
onLinkValid: (Link) -> Unit = EnsureNeverCalledWithParam(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.pinned.banner
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onRoot
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -22,49 +25,45 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PinnedMessagesBannerViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on the banner invoke expected callback`() {
|
||||
fun `clicking on the banner invoke expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinnedMessagesBannerEvent>()
|
||||
val state = aLoadedPinnedMessagesBannerState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
val pinnedEventId = state.currentPinnedMessage.eventId
|
||||
ensureCalledOnceWithParam(pinnedEventId) { callback ->
|
||||
rule.setPinnedMessagesBannerView(
|
||||
setPinnedMessagesBannerView(
|
||||
state = state,
|
||||
onClick = callback
|
||||
)
|
||||
rule.onRoot().performClick()
|
||||
onRoot().performClick()
|
||||
eventsRecorder.assertSingle(PinnedMessagesBannerEvent.MoveToNextPinned)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on view all emit the expected event`() {
|
||||
fun `clicking on view all emit the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinnedMessagesBannerEvent>(expectEvents = true)
|
||||
val state = aLoadedPinnedMessagesBannerState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setPinnedMessagesBannerView(
|
||||
setPinnedMessagesBannerView(
|
||||
state = state,
|
||||
onViewAllClick = callback
|
||||
)
|
||||
rule.clickOn(CommonStrings.screen_room_pinned_banner_view_all_button_title)
|
||||
clickOn(CommonStrings.screen_room_pinned_banner_view_all_button_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPinnedMessagesBannerView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setPinnedMessagesBannerView(
|
||||
state: PinnedMessagesBannerState,
|
||||
onClick: (EventId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onViewAllClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.pinned.list
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.longClick
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onFirst
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.messages.impl.actionlist.ActionListEvent
|
||||
import io.element.android.features.messages.impl.actionlist.anActionListState
|
||||
|
|
@ -31,33 +34,28 @@ import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
|||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import io.element.android.wysiwyg.link.Link
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PinnedMessagesListViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back calls the expected callback`() {
|
||||
fun `clicking on back calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinnedMessagesListEvent>(expectEvents = false)
|
||||
val state = aLoadedPinnedMessagesListState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setPinnedMessagesListView(
|
||||
setPinnedMessagesListView(
|
||||
state = state,
|
||||
onBackClick = callback
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on an event calls the expected callback`() {
|
||||
fun `click on an event calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PinnedMessagesListEvent>(expectEvents = false)
|
||||
val content = aTimelineItemFileContent()
|
||||
val state = aLoadedPinnedMessagesListState(
|
||||
|
|
@ -67,16 +65,16 @@ class PinnedMessagesListViewTest {
|
|||
|
||||
val event = state.timelineItems.first() as TimelineItem.Event
|
||||
ensureCalledOnceWithParam(event) { callback ->
|
||||
rule.setPinnedMessagesListView(
|
||||
setPinnedMessagesListView(
|
||||
state = state,
|
||||
onEventClick = callback
|
||||
)
|
||||
rule.onAllNodesWithText(content.filename).onFirst().performClick()
|
||||
onAllNodesWithText(content.filename).onFirst().performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `long click on an event emits the expected event`() {
|
||||
fun `long click on an event emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ActionListEvent>(expectEvents = true)
|
||||
val content = aTimelineItemFileContent()
|
||||
val state = aLoadedPinnedMessagesListState(
|
||||
|
|
@ -84,10 +82,10 @@ class PinnedMessagesListViewTest {
|
|||
actionListState = anActionListState(eventSink = eventsRecorder)
|
||||
)
|
||||
|
||||
rule.setPinnedMessagesListView(
|
||||
setPinnedMessagesListView(
|
||||
state = state,
|
||||
)
|
||||
rule.onAllNodesWithText(content.filename).onFirst()
|
||||
onAllNodesWithText(content.filename).onFirst()
|
||||
.performTouchInput {
|
||||
longClick()
|
||||
}
|
||||
|
|
@ -96,7 +94,7 @@ class PinnedMessagesListViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPinnedMessagesListView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setPinnedMessagesListView(
|
||||
state: PinnedMessagesListState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onEventClick: (event: TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.timeline
|
||||
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runComposeUiTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.messages.impl.utils.FakeMentionSpanFormatter
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
|
|
@ -18,15 +21,12 @@ import io.element.android.libraries.matrix.test.A_USER_ID
|
|||
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
|
||||
import io.element.android.libraries.textcomposer.mentions.MentionSpanProvider
|
||||
import io.element.android.libraries.textcomposer.mentions.MentionSpanTheme
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class DefaultHtmlConverterProviderTest {
|
||||
@get:Rule val composeTestRule = createComposeRule()
|
||||
|
||||
private val provider = DefaultHtmlConverterProvider(
|
||||
mentionSpanProvider = MentionSpanProvider(
|
||||
permalinkParser = FakePermalinkParser(),
|
||||
|
|
@ -43,8 +43,8 @@ class DefaultHtmlConverterProviderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `calling provide after calling Update first should return an HtmlConverter`() {
|
||||
composeTestRule.setContent {
|
||||
fun `calling provide after calling Update first should return an HtmlConverter`() = runComposeUiTest {
|
||||
setContent {
|
||||
CompositionLocalProvider(LocalInspectionMode provides true) {
|
||||
provider.Update()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,18 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.timeline
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollToIndex
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.messages.impl.timeline.components.MessageShieldData
|
||||
import io.element.android.features.messages.impl.timeline.components.aCriticalShield
|
||||
|
|
@ -39,19 +42,15 @@ import io.element.android.wysiwyg.link.Link
|
|||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimelineViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `reaching the end of the timeline with more events to load emits a LoadMore event`() {
|
||||
fun `reaching the end of the timeline with more events to load emits a LoadMore event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf<TimelineItem>(
|
||||
TimelineItem.Virtual(
|
||||
|
|
@ -66,9 +65,9 @@ class TimelineViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `reaching the end of the timeline does not send a LoadMore event`() {
|
||||
fun `reaching the end of the timeline does not send a LoadMore event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -78,9 +77,9 @@ class TimelineViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `scroll to bottom on live timeline does not emit the Event`() {
|
||||
fun `scroll to bottom on live timeline does not emit the Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
|
||||
isLive = true,
|
||||
|
|
@ -92,14 +91,14 @@ class TimelineViewTest {
|
|||
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
|
||||
eventsRecorder.clear()
|
||||
|
||||
val contentDescription = rule.activity.getString(CommonStrings.a11y_jump_to_bottom)
|
||||
rule.onNodeWithContentDescription(contentDescription).performClick()
|
||||
val contentDescription = activity!!.getString(CommonStrings.a11y_jump_to_bottom)
|
||||
onNodeWithContentDescription(contentDescription).performClick()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `scroll to bottom on detached timeline emits the expected Event`() {
|
||||
fun `scroll to bottom on detached timeline emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
|
||||
isLive = false,
|
||||
|
|
@ -110,15 +109,15 @@ class TimelineViewTest {
|
|||
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
|
||||
eventsRecorder.clear()
|
||||
|
||||
val contentDescription = rule.activity.getString(CommonStrings.a11y_jump_to_bottom)
|
||||
rule.onNodeWithContentDescription(contentDescription).performClick()
|
||||
val contentDescription = activity!!.getString(CommonStrings.a11y_jump_to_bottom)
|
||||
onNodeWithContentDescription(contentDescription).performClick()
|
||||
eventsRecorder.assertSingle(TimelineEvent.JumpToLive)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `an empty timeline triggers a prefetch`() {
|
||||
fun `an empty timeline triggers a prefetch`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf(),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -129,9 +128,9 @@ class TimelineViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `show shield dialog`() {
|
||||
fun `show shield dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf<TimelineItem>(
|
||||
aTimelineItemEvent(
|
||||
|
|
@ -143,8 +142,8 @@ class TimelineViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val contentDescription = rule.activity.getString(CommonStrings.a11y_encryption_details)
|
||||
rule.onNodeWithContentDescription(contentDescription).performClick()
|
||||
val contentDescription = activity!!.getString(CommonStrings.a11y_encryption_details)
|
||||
onNodeWithContentDescription(contentDescription).performClick()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
TimelineEvent.OnScrollFinished(0),
|
||||
|
|
@ -154,9 +153,9 @@ class TimelineViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `hide shield dialog`() {
|
||||
fun `hide shield dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
|
||||
isLive = false,
|
||||
|
|
@ -167,16 +166,16 @@ class TimelineViewTest {
|
|||
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
|
||||
eventsRecorder.clear()
|
||||
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(TimelineEvent.HideShieldDialog)
|
||||
}
|
||||
|
||||
@Ignore(
|
||||
"performScrollToIndex in compose tests no longer sets LazyListState.isScrollInProgress to true, so the LoadMore event is not emitted." +
|
||||
"This needs to be reworked to use a different approach to check the LoadMore event was emitted."
|
||||
"This needs to be reworked to use a different approach to check the LoadMore event was emitted."
|
||||
)
|
||||
@Test
|
||||
fun `scrolling near to the start of the loaded items triggers a pre-fetch`() {
|
||||
fun `scrolling near to the start of the loaded items triggers a pre-fetch`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent>()
|
||||
val items = List<TimelineItem>(200) {
|
||||
aTimelineItemEvent(
|
||||
|
|
@ -185,7 +184,7 @@ class TimelineViewTest {
|
|||
)
|
||||
}.toImmutableList()
|
||||
|
||||
rule.setTimelineView(
|
||||
setTimelineView(
|
||||
state = aTimelineState(
|
||||
timelineItems = items,
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -194,9 +193,9 @@ class TimelineViewTest {
|
|||
),
|
||||
)
|
||||
|
||||
rule.onNodeWithTag("timeline").performScrollToIndex(180)
|
||||
onNodeWithTag("timeline").performScrollToIndex(180)
|
||||
|
||||
rule.mainClock.advanceTimeBy(1000)
|
||||
mainClock.advanceTimeBy(1000)
|
||||
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
|
|
@ -207,7 +206,7 @@ class TimelineViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setTimelineView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setTimelineView(
|
||||
state: TimelineState,
|
||||
timelineProtectionState: TimelineProtectionState = aTimelineProtectionState(),
|
||||
onUserDataClick: (MatrixUser) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.timeline.components.event
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.messages.impl.timeline.TimelineEvent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent
|
||||
|
|
@ -20,14 +23,11 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimelineItemPollViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `answering a poll with first answer should emit a PollAnswerSelected event`() {
|
||||
testAnswer(answerIndex = 0)
|
||||
|
|
@ -38,17 +38,17 @@ class TimelineItemPollViewTest {
|
|||
testAnswer(answerIndex = 1)
|
||||
}
|
||||
|
||||
private fun testAnswer(answerIndex: Int) {
|
||||
private fun testAnswer(answerIndex: Int) = runAndroidComposeUiTest<ComponentActivity> {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent.TimelineItemPollEvent>()
|
||||
val content = aTimelineItemPollContent()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
TimelineItemPollView(
|
||||
content = content,
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
}
|
||||
val answer = content.answerItems[answerIndex].answer
|
||||
rule.onNode(
|
||||
onNode(
|
||||
matcher = hasText(answer.text),
|
||||
useUnmergedTree = true,
|
||||
).performClick()
|
||||
|
|
@ -56,38 +56,38 @@ class TimelineItemPollViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `editing a poll should emit a PollEditClicked event`() {
|
||||
fun `editing a poll should emit a PollEditClicked event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent.TimelineItemPollEvent>()
|
||||
val content = aTimelineItemPollContent(
|
||||
isMine = true,
|
||||
isEditable = true,
|
||||
)
|
||||
rule.setContent {
|
||||
setContent {
|
||||
TimelineItemPollView(
|
||||
content = content,
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_edit_poll)
|
||||
clickOn(CommonStrings.action_edit_poll)
|
||||
eventsRecorder.assertSingle(TimelineEvent.EditPoll(content.eventId!!))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `closing a poll should emit a PollEndClicked event`() {
|
||||
fun `closing a poll should emit a PollEndClicked event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TimelineEvent.TimelineItemPollEvent>()
|
||||
val content = aTimelineItemPollContent(
|
||||
isMine = true,
|
||||
)
|
||||
rule.setContent {
|
||||
setContent {
|
||||
TimelineItemPollView(
|
||||
content = content,
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_end_poll)
|
||||
clickOn(CommonStrings.action_end_poll)
|
||||
// A confirmation dialog should be shown
|
||||
eventsRecorder.assertEmpty()
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(TimelineEvent.EndPoll(content.eventId!!))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.timeline.components.event
|
||||
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannedString
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.core.text.buildSpannedString
|
||||
import androidx.core.text.inSpans
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
|
@ -38,45 +41,40 @@ import io.element.android.tests.testutils.lambda.assert
|
|||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.wysiwyg.view.spans.CustomMentionSpan
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimelineTextViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
private val mentionSpanTheme = MentionSpanTheme(currentUserId = A_USER_ID)
|
||||
private val formatLambda = lambdaRecorder<MentionType, CharSequence> { mentionType -> mentionType.toString() }
|
||||
private val mentionSpanFormatter = FakeMentionSpanFormatter(formatLambda)
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - does nothing for a non spannable CharSequence`() = runTest {
|
||||
fun `getTextWithResolvedMentions - does nothing for a non spannable CharSequence`() = runAndroidComposeUiTest {
|
||||
val charSequence = "Hello <a href=\"https://matrix.to/#/@alice:example.com\">@alice:example.com</a>"
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
|
||||
assertThat(result.getMentionSpans()).isEmpty()
|
||||
assert(formatLambda).isNeverCalled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - does nothing if there are no mentions`() = runTest {
|
||||
fun `getTextWithResolvedMentions - does nothing if there are no mentions`() = runAndroidComposeUiTest {
|
||||
val charSequence = SpannableString("Hello <a href=\"https://matrix.to/#/@alice:example.com\">@alice:example.com</a>")
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
|
||||
assertThat(result.getMentionSpans()).isEmpty()
|
||||
assert(formatLambda).isNeverCalled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - just returns the body if there is no formattedBody`() = runTest {
|
||||
fun `getTextWithResolvedMentions - just returns the body if there is no formattedBody`() = runAndroidComposeUiTest {
|
||||
val charSequence = "Hello <a href=\"https://matrix.to/#/@alice:example.com\">@alice:example.com</a>"
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(body = charSequence, formattedBody = null))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(body = charSequence, formattedBody = null))
|
||||
|
||||
assertThat(result.getMentionSpans()).isEmpty()
|
||||
assertThat(result.toString()).isEqualTo(charSequence)
|
||||
|
|
@ -84,7 +82,7 @@ class TimelineTextViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - with Room mention format correctly`() = runTest {
|
||||
fun `getTextWithResolvedMentions - with Room mention format correctly`() = runAndroidComposeUiTest {
|
||||
val mentionType = MentionType.Room(roomIdOrAlias = A_ROOM_ID_2.toRoomIdOrAlias())
|
||||
val charSequence = buildSpannedString {
|
||||
append("Hello ")
|
||||
|
|
@ -93,7 +91,7 @@ class TimelineTextViewTest {
|
|||
}
|
||||
}
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
|
||||
val expectedDisplayText = mentionType.toString()
|
||||
assertThat(result.getMentionSpans().firstOrNull()?.displayText.toString()).isEqualTo(expectedDisplayText)
|
||||
|
|
@ -102,7 +100,7 @@ class TimelineTextViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - replaces MentionSpan's text`() = runTest {
|
||||
fun `getTextWithResolvedMentions - replaces MentionSpan's text`() = runAndroidComposeUiTest {
|
||||
val mentionType = MentionType.User(userId = A_USER_ID)
|
||||
val charSequence = buildSpannedString {
|
||||
append("Hello ")
|
||||
|
|
@ -111,7 +109,7 @@ class TimelineTextViewTest {
|
|||
}
|
||||
}
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
|
||||
val expectedDisplayText = mentionType.toString()
|
||||
assertThat(result.getMentionSpans().firstOrNull()?.displayText.toString()).isEqualTo(expectedDisplayText)
|
||||
|
|
@ -119,7 +117,7 @@ class TimelineTextViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `getTextWithResolvedMentions - replaces MentionSpan's text inside CustomMentionSpan`() = runTest {
|
||||
fun `getTextWithResolvedMentions - replaces MentionSpan's text inside CustomMentionSpan`() = runAndroidComposeUiTest {
|
||||
val mentionType = MentionType.User(userId = A_USER_ID)
|
||||
val charSequence = buildSpannedString {
|
||||
append("Hello ")
|
||||
|
|
@ -129,12 +127,12 @@ class TimelineTextViewTest {
|
|||
}
|
||||
val mentionSpanUpdater = aMentionSpanUpdater()
|
||||
val expectedDisplayText = mentionType.toString()
|
||||
val result = rule.getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
val result = getText(mentionSpanUpdater, aTextContentWithFormattedBody(charSequence))
|
||||
assertThat(result.getMentionSpans().firstOrNull()?.displayText.toString()).isEqualTo(expectedDisplayText)
|
||||
assert(formatLambda).isCalledOnce()
|
||||
}
|
||||
|
||||
private suspend fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.getText(
|
||||
private suspend fun AndroidComposeUiTest<ComponentActivity>.getText(
|
||||
mentionSpanUpdater: MentionSpanUpdater,
|
||||
content: TimelineItemTextBasedContent,
|
||||
): CharSequence {
|
||||
|
|
|
|||
|
|
@ -6,56 +6,55 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.messages.impl.timeline.protection
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ProtectedViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `when hideContent is false, the content is rendered`() {
|
||||
rule.setProtectedView(
|
||||
fun `when hideContent is false, the content is rendered`() = runAndroidComposeUiTest {
|
||||
setProtectedView(
|
||||
hideContent = false,
|
||||
content = {
|
||||
Text("Hello")
|
||||
}
|
||||
)
|
||||
rule.onNodeWithText("Hello").assertExists()
|
||||
onNodeWithText("Hello").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when hideContent is true, the content is not rendered, and user can reveal it`() {
|
||||
fun `when hideContent is true, the content is not rendered, and user can reveal it`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setProtectedView(
|
||||
setProtectedView(
|
||||
hideContent = true,
|
||||
onShowClick = it,
|
||||
content = {
|
||||
Text("Hello")
|
||||
}
|
||||
)
|
||||
rule.onNodeWithText("Hello").assertDoesNotExist()
|
||||
rule.clickOn(CommonStrings.action_show)
|
||||
onNodeWithText("Hello").assertDoesNotExist()
|
||||
clickOn(CommonStrings.action_show)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setProtectedView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setProtectedView(
|
||||
hideContent: Boolean = false,
|
||||
onShowClick: () -> Unit = { lambdaError() },
|
||||
content: @Composable () -> Unit = {},
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.poll.impl.history
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.poll.api.pollcontent.aPollContentState
|
||||
import io.element.android.features.poll.impl.R
|
||||
|
|
@ -26,34 +29,29 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 PollHistoryViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
aPollHistoryState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
goBack = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on edit poll invokes the expected callback`() {
|
||||
fun `clicking on edit poll invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>(expectEvents = false)
|
||||
val eventId = EventId("\$anEventId")
|
||||
val state = aPollHistoryState(
|
||||
|
|
@ -69,17 +67,17 @@ class PollHistoryViewTest {
|
|||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnceWithParam(eventId) {
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
state = state,
|
||||
onEditPoll = it
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_edit_poll)
|
||||
clickOn(CommonStrings.action_edit_poll)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on poll end emits the expected Event`() {
|
||||
fun `clicking on poll end emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
|
||||
val eventId = EventId("\$anEventId")
|
||||
val state = aPollHistoryState(
|
||||
|
|
@ -95,16 +93,16 @@ class PollHistoryViewTest {
|
|||
),
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
state = state,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_end_poll)
|
||||
clickOn(CommonStrings.action_end_poll)
|
||||
// Cancel the dialog
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
// Do it again, and confirm the dialog
|
||||
rule.clickOn(CommonStrings.action_end_poll)
|
||||
clickOn(CommonStrings.action_end_poll)
|
||||
eventsRecorder.assertEmpty()
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(
|
||||
PollHistoryEvents.EndPoll(eventId)
|
||||
)
|
||||
|
|
@ -112,7 +110,7 @@ class PollHistoryViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on poll answer emits the expected Event`() {
|
||||
fun `clicking on poll answer emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
|
||||
val eventId = EventId("\$anEventId")
|
||||
val state = aPollHistoryState(
|
||||
|
|
@ -129,10 +127,10 @@ class PollHistoryViewTest {
|
|||
eventSink = eventsRecorder
|
||||
)
|
||||
val answer = state.pollHistoryItems.ongoing.first().state.answerItems.first().answer
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
state = state,
|
||||
)
|
||||
rule.onNodeWithText(
|
||||
onNodeWithText(
|
||||
text = answer.text,
|
||||
useUnmergedTree = true,
|
||||
).performClick()
|
||||
|
|
@ -142,14 +140,14 @@ class PollHistoryViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on past tab emits the expected Event`() {
|
||||
fun `clicking on past tab emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
aPollHistoryState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_polls_history_filter_past)
|
||||
clickOn(R.string.screen_polls_history_filter_past)
|
||||
eventsRecorder.assertSingle(
|
||||
PollHistoryEvents.SelectFilter(filter = PollHistoryFilter.PAST)
|
||||
)
|
||||
|
|
@ -157,22 +155,22 @@ class PollHistoryViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on load more emits the expected Event`() {
|
||||
fun `clicking on load more emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
|
||||
rule.setPollHistoryViewView(
|
||||
setPollHistoryViewView(
|
||||
aPollHistoryState(
|
||||
hasMoreToLoad = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_load_more)
|
||||
clickOn(CommonStrings.action_load_more)
|
||||
eventsRecorder.assertSingle(
|
||||
PollHistoryEvents.LoadMore
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPollHistoryViewView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setPollHistoryViewView(
|
||||
state: PollHistoryState,
|
||||
onEditPoll: (EventId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
goBack: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.about
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -19,51 +22,47 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AboutViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes back callback`() {
|
||||
fun `clicking on back invokes back callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setAboutView(
|
||||
setAboutView(
|
||||
anAboutState(),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on an item invokes the expected callback`() {
|
||||
fun `clicking on an item invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val state = anAboutState()
|
||||
ensureCalledOnceWithParam(state.elementLegals.first()) { callback ->
|
||||
rule.setAboutView(
|
||||
setAboutView(
|
||||
state,
|
||||
onElementLegalClick = callback,
|
||||
)
|
||||
rule.clickOn(state.elementLegals.first().titleRes)
|
||||
clickOn(state.elementLegals.first().titleRes)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the open source licenses invokes the expected callback`() {
|
||||
fun `clicking on the open source licenses invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setAboutView(
|
||||
setAboutView(
|
||||
anAboutState(),
|
||||
onOpenSourceLicensesClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_open_source_licenses)
|
||||
clickOn(CommonStrings.common_open_source_licenses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setAboutView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAboutView(
|
||||
state: AboutState,
|
||||
onElementLegalClick: (ElementLegal) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onOpenSourceLicensesClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.advanced
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import im.vector.app.features.analytics.plan.Interaction
|
||||
|
|
@ -30,104 +33,99 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
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 AdvancedSettingsViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on other theme emits the expected event`() {
|
||||
fun `clicking on other theme emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_appearance)
|
||||
rule.clickOn(CommonStrings.common_dark)
|
||||
clickOn(CommonStrings.common_appearance)
|
||||
clickOn(CommonStrings.common_dark)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTheme(ThemeOption.Dark))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `black theme is shown when available`() {
|
||||
rule.setAdvancedSettingsView(
|
||||
fun `black theme is shown when available`() = runAndroidComposeUiTest {
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
availableThemeOptions = ThemeOption.entries.toImmutableList(),
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_appearance)
|
||||
rule.run {
|
||||
val text = activity.getString(CommonStrings.common_black)
|
||||
clickOn(CommonStrings.common_appearance)
|
||||
run {
|
||||
val text = activity!!.getString(CommonStrings.common_black)
|
||||
onNodeWithText(text).assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `black theme is hidden when unavailable`() {
|
||||
rule.setAdvancedSettingsView(
|
||||
fun `black theme is hidden when unavailable`() = runAndroidComposeUiTest {
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
availableThemeOptions = ThemeOption.entries.filterNot { it == ThemeOption.Black }.toImmutableList(),
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_appearance)
|
||||
rule.assertNoNodeWithText(CommonStrings.common_black)
|
||||
clickOn(CommonStrings.common_appearance)
|
||||
assertNoNodeWithText(CommonStrings.common_black)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on View source emits the expected event`() {
|
||||
fun `clicking on View source emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_view_source)
|
||||
clickOn(CommonStrings.action_view_source)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetDeveloperModeEnabled(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Share presence emits the expected event`() {
|
||||
fun `clicking on Share presence emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_share_presence)
|
||||
clickOn(R.string.screen_advanced_settings_share_presence)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetSharePresenceEnabled(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on media to enable compression emits the expected event`() {
|
||||
fun `clicking on media to enable compression emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
val analyticsService = FakeAnalyticsService()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
analyticsService = analyticsService
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_media_compression_description)
|
||||
clickOn(R.string.screen_advanced_settings_media_compression_description)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetCompressMedia(true))
|
||||
assertThat(analyticsService.capturedEvents).isEqualTo(
|
||||
listOf(
|
||||
|
|
@ -139,17 +137,17 @@ class AdvancedSettingsViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on media to disable compression emits the expected event`() {
|
||||
fun `clicking on media to disable compression emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
val analyticsService = FakeAnalyticsService()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
mediaOptimizationState = MediaOptimizationState.AllMedia(isEnabled = true),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
analyticsService = analyticsService
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_media_compression_description)
|
||||
clickOn(R.string.screen_advanced_settings_media_compression_description)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetCompressMedia(false))
|
||||
assertThat(analyticsService.capturedEvents).isEqualTo(
|
||||
listOf(
|
||||
|
|
@ -162,65 +160,65 @@ class AdvancedSettingsViewTest {
|
|||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `clicking on hide invite avatars emits the expected event`() {
|
||||
fun `clicking on hide invite avatars emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
hideInviteAvatars = false
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_hide_invite_avatars_toggle_title)
|
||||
clickOn(R.string.screen_advanced_settings_hide_invite_avatars_toggle_title)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetHideInviteAvatars(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `clicking on timeline media preview always hide emits the expected event`() {
|
||||
fun `clicking on timeline media preview always hide emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
timelineMediaPreviewValue = MediaPreviewValue.On
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_always_hide)
|
||||
clickOn(R.string.screen_advanced_settings_show_media_timeline_always_hide)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.Off))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `clicking on timeline media preview private rooms emits the expected event`() {
|
||||
fun `clicking on timeline media preview private rooms emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
timelineMediaPreviewValue = MediaPreviewValue.On
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_private_rooms)
|
||||
clickOn(R.string.screen_advanced_settings_show_media_timeline_private_rooms)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.Private))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `clicking on timeline media preview always show emits the expected event`() {
|
||||
fun `clicking on timeline media preview always show emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>()
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
timelineMediaPreviewValue = MediaPreviewValue.Off
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_always_show)
|
||||
clickOn(R.string.screen_advanced_settings_show_media_timeline_always_show)
|
||||
eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.On))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `hide invite avatars toggle is disabled when action is loading`() {
|
||||
fun `hide invite avatars toggle is disabled when action is loading`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>(expectEvents = false)
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
hideInviteAvatars = false,
|
||||
|
|
@ -228,14 +226,14 @@ class AdvancedSettingsViewTest {
|
|||
),
|
||||
)
|
||||
// The toggle should be disabled, so clicking should not emit any events
|
||||
rule.clickOn(R.string.screen_advanced_settings_hide_invite_avatars_toggle_title)
|
||||
clickOn(R.string.screen_advanced_settings_hide_invite_avatars_toggle_title)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1080dp")
|
||||
fun `timeline media preview options are disabled when action is loading`() {
|
||||
fun `timeline media preview options are disabled when action is loading`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AdvancedSettingsEvents>(expectEvents = false)
|
||||
rule.setAdvancedSettingsView(
|
||||
setAdvancedSettingsView(
|
||||
state = aAdvancedSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
timelineMediaPreviewValue = MediaPreviewValue.On,
|
||||
|
|
@ -243,12 +241,12 @@ class AdvancedSettingsViewTest {
|
|||
),
|
||||
)
|
||||
// The options should be disabled, so clicking should not emit any events
|
||||
rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_always_hide)
|
||||
rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_private_rooms)
|
||||
clickOn(R.string.screen_advanced_settings_show_media_timeline_always_hide)
|
||||
clickOn(R.string.screen_advanced_settings_show_media_timeline_private_rooms)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setAdvancedSettingsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAdvancedSettingsView(
|
||||
state: AdvancedSettingsState,
|
||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.blockedusers
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -23,72 +26,67 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class BlockedUserViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes back callback`() {
|
||||
fun `clicking on back invokes back callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<BlockedUsersEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setBlockedUsersView(
|
||||
setBlockedUsersView(
|
||||
aBlockedUsersState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a user emits the expected Event`() {
|
||||
fun `clicking on a user emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<BlockedUsersEvents>()
|
||||
val userList = aMatrixUserList()
|
||||
rule.setBlockedUsersView(
|
||||
setBlockedUsersView(
|
||||
aBlockedUsersState(
|
||||
blockedUsers = userList,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(userList.first().displayName.orEmpty()).performClick()
|
||||
onNodeWithText(userList.first().displayName.orEmpty()).performClick()
|
||||
eventsRecorder.assertSingle(BlockedUsersEvents.Unblock(userList.first().userId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on cancel sends a BlockedUsersEvents`() {
|
||||
fun `clicking on cancel sends a BlockedUsersEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<BlockedUsersEvents>()
|
||||
rule.setBlockedUsersView(
|
||||
setBlockedUsersView(
|
||||
aBlockedUsersState(
|
||||
unblockUserAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(BlockedUsersEvents.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on confirm sends a BlockedUsersEvents`() {
|
||||
fun `clicking on confirm sends a BlockedUsersEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<BlockedUsersEvents>()
|
||||
rule.setBlockedUsersView(
|
||||
setBlockedUsersView(
|
||||
aBlockedUsersState(
|
||||
unblockUserAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_blocked_users_unblock_alert_action)
|
||||
clickOn(R.string.screen_blocked_users_unblock_alert_action)
|
||||
eventsRecorder.assertSingle(BlockedUsersEvents.ConfirmUnblock)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setBlockedUsersView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setBlockedUsersView(
|
||||
state: BlockedUsersState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.developer
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -20,76 +23,71 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 DeveloperSettingsViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeveloperSettingsEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setDeveloperSettingsView(
|
||||
setDeveloperSettingsView(
|
||||
state = aDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2000dp")
|
||||
@Test
|
||||
fun `clicking on push history notification invokes the expected callback`() {
|
||||
fun `clicking on push history notification invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeveloperSettingsEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setDeveloperSettingsView(
|
||||
setDeveloperSettingsView(
|
||||
state = aDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onPushHistoryClick = it
|
||||
)
|
||||
rule.clickOn(R.string.troubleshoot_notifications_entry_point_push_history_title)
|
||||
clickOn(R.string.troubleshoot_notifications_entry_point_push_history_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2000dp")
|
||||
@Test
|
||||
fun `clicking on open showkase invokes the expected callback`() {
|
||||
fun `clicking on open showkase invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeveloperSettingsEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setDeveloperSettingsView(
|
||||
setDeveloperSettingsView(
|
||||
state = aDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenShowkase = it
|
||||
)
|
||||
rule.onNodeWithText("Open Showkase browser").performClick()
|
||||
onNodeWithText("Open Showkase browser").performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2200dp")
|
||||
@Test
|
||||
fun `clicking on clear cache emits the expected event`() {
|
||||
fun `clicking on clear cache emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeveloperSettingsEvents>()
|
||||
rule.setDeveloperSettingsView(
|
||||
setDeveloperSettingsView(
|
||||
state = aDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Clear cache").performClick()
|
||||
onNodeWithText("Clear cache").performClick()
|
||||
eventsRecorder.assertSingle(DeveloperSettingsEvents.ClearCache)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setDeveloperSettingsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setDeveloperSettingsView(
|
||||
state: DeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit = EnsureNeverCalled(),
|
||||
onPushHistoryClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -5,19 +5,22 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.developer.appsettings
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.isEditable
|
||||
import androidx.compose.ui.test.isFocusable
|
||||
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.performClick
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem
|
||||
|
|
@ -27,78 +30,73 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 AppDeveloperSettingsPageTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AppDeveloperSettingsEvent>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setAppDeveloperSettingsView(
|
||||
setAppDeveloperSettingsView(
|
||||
state = anAppDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1500dp")
|
||||
@Test
|
||||
fun `clicking on element call url open the dialogs and submit emits the expected event`() {
|
||||
fun `clicking on element call url open the dialogs and submit emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AppDeveloperSettingsEvent>()
|
||||
rule.setAppDeveloperSettingsView(
|
||||
setAppDeveloperSettingsView(
|
||||
state = anAppDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_element_call_base_url)
|
||||
val textInputNode = rule.onAllNodes(isEditable().and(isFocusable())).filterToOne(hasAnyAncestor(isDialog()))
|
||||
clickOn(R.string.screen_advanced_settings_element_call_base_url)
|
||||
val textInputNode = onAllNodes(isEditable().and(isFocusable())).filterToOne(hasAnyAncestor(isDialog()))
|
||||
textInputNode.performTextInput("https://call.element.dev")
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(AppDeveloperSettingsEvent.SetCustomElementCallBaseUrl("https://call.element.dev"))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2000dp")
|
||||
@Test
|
||||
fun `clicking on open showkase invokes the expected callback`() {
|
||||
fun `clicking on open showkase invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AppDeveloperSettingsEvent>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setAppDeveloperSettingsView(
|
||||
setAppDeveloperSettingsView(
|
||||
state = anAppDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenShowkase = it
|
||||
)
|
||||
rule.onNodeWithText("Open Showkase browser").performClick()
|
||||
onNodeWithText("Open Showkase browser").performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on log level emits the expected event`() {
|
||||
fun `clicking on log level emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AppDeveloperSettingsEvent>()
|
||||
rule.setAppDeveloperSettingsView(
|
||||
setAppDeveloperSettingsView(
|
||||
state = anAppDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Tracing log level").performClick()
|
||||
rule.onNodeWithText("Debug").performClick()
|
||||
onNodeWithText("Tracing log level").performClick()
|
||||
onNodeWithText("Debug").performClick()
|
||||
eventsRecorder.assertSingle(AppDeveloperSettingsEvent.SetTracingLogLevel(LogLevelItem.DEBUG))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setAppDeveloperSettingsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAppDeveloperSettingsView(
|
||||
state: AppDeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.notifications
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -25,76 +28,71 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 NotificationSettingsViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
ensureCalledOnce {
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
eventsRecorder.assertSingle(NotificationSettingsEvents.RefreshSystemNotificationsEnabled)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on troubleshoot notification invokes the expected callback`() {
|
||||
fun `clicking on troubleshoot notification invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
ensureCalledOnce {
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onTroubleshootNotificationsClick = it
|
||||
)
|
||||
rule.clickOn(R.string.troubleshoot_notifications_entry_point_title)
|
||||
clickOn(R.string.troubleshoot_notifications_entry_point_title)
|
||||
}
|
||||
eventsRecorder.assertSingle(NotificationSettingsEvents.RefreshSystemNotificationsEnabled)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on group chats invokes the expected callback`() {
|
||||
fun `clicking on group chats invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
ensureCalledOnceWithParam(false) {
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenEditDefault = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_group_chats)
|
||||
clickOn(R.string.screen_notification_settings_group_chats)
|
||||
}
|
||||
eventsRecorder.assertSingle(NotificationSettingsEvents.RefreshSystemNotificationsEnabled)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on direct chats invokes the expected callback`() {
|
||||
fun `clicking on direct chats invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
ensureCalledOnceWithParam(true) {
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenEditDefault = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_direct_chats)
|
||||
clickOn(R.string.screen_notification_settings_direct_chats)
|
||||
}
|
||||
eventsRecorder.assertSingle(NotificationSettingsEvents.RefreshSystemNotificationsEnabled)
|
||||
}
|
||||
|
|
@ -111,15 +109,15 @@ class NotificationSettingsViewTest {
|
|||
testNotificationToggle(false)
|
||||
}
|
||||
|
||||
private fun testNotificationToggle(initialState: Boolean) {
|
||||
private fun testNotificationToggle(initialState: Boolean) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
appNotificationEnabled = initialState,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_enable_notifications)
|
||||
clickOn(R.string.screen_notification_settings_enable_notifications)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -140,15 +138,15 @@ class NotificationSettingsViewTest {
|
|||
testAtRoomToggle(false)
|
||||
}
|
||||
|
||||
private fun testAtRoomToggle(initialState: Boolean) {
|
||||
private fun testAtRoomToggle(initialState: Boolean) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
atRoomNotificationsEnabled = initialState,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_room_mention_label)
|
||||
clickOn(R.string.screen_notification_settings_room_mention_label)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -169,15 +167,15 @@ class NotificationSettingsViewTest {
|
|||
testInvitationToggle(false)
|
||||
}
|
||||
|
||||
private fun testInvitationToggle(initialState: Boolean) {
|
||||
private fun testInvitationToggle(initialState: Boolean) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
inviteForMeNotificationsEnabled = initialState,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_invite_for_me_label)
|
||||
clickOn(R.string.screen_notification_settings_invite_for_me_label)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -188,15 +186,15 @@ class NotificationSettingsViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `with an error configuration, clicking on continue emits the expected events`() {
|
||||
fun `with an error configuration, clicking on continue emits the expected events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
changeNotificationSettingAction = AsyncAction.Failure(AN_EXCEPTION),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -207,15 +205,15 @@ class NotificationSettingsViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `with invalid configuration, clicking on continue emits the expected events`() {
|
||||
fun `with invalid configuration, clicking on continue emits the expected events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aInvalidNotificationSettingsState(
|
||||
fixFailed = false,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -226,15 +224,15 @@ class NotificationSettingsViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `with invalid configuration and error, clicking on OK emits the expected events`() {
|
||||
fun `with invalid configuration and error, clicking on OK emits the expected events`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aInvalidNotificationSettingsState(
|
||||
fixFailed = true,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -245,14 +243,14 @@ class NotificationSettingsViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Push notification provider emits the expected event`() {
|
||||
fun `clicking on Push notification provider emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_advanced_settings_push_provider_android)
|
||||
clickOn(R.string.screen_advanced_settings_push_provider_android)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -262,16 +260,16 @@ class NotificationSettingsViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a push provider emits the expected event`() {
|
||||
fun `clicking on a push provider emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<NotificationSettingsEvents>()
|
||||
rule.setNotificationSettingsView(
|
||||
setNotificationSettingsView(
|
||||
state = aValidNotificationSettingsState(
|
||||
eventSink = eventsRecorder,
|
||||
showChangePushProviderDialog = true,
|
||||
availablePushDistributors = listOf(aDistributor("P1"), aDistributor("P2"))
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("P2").performClick()
|
||||
onNodeWithText("P2").performClick()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
NotificationSettingsEvents.RefreshSystemNotificationsEnabled,
|
||||
|
|
@ -281,7 +279,7 @@ class NotificationSettingsViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setNotificationSettingsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setNotificationSettingsView(
|
||||
state: NotificationSettingsState,
|
||||
onOpenEditDefault: (isOneToOne: Boolean) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onTroubleshootNotificationsClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -5,13 +5,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.preferences.impl.R
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
|
@ -25,49 +28,45 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PreferencesRootViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes back callback`() {
|
||||
fun `clicking on back invokes back callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on User profile invokes the expected callback`() {
|
||||
fun `click on User profile invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
val user = aMatrixUser()
|
||||
ensureCalledOnceWithParam(user) { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
myUser = user,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenUserProfile = callback,
|
||||
)
|
||||
rule.onNodeWithText("Alice").performClick()
|
||||
onNodeWithText("Alice").performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on other session sends a SwitchToSession`() {
|
||||
fun `clicking on other session sends a SwitchToSession`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>()
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
isMultiAccountEnabled = true,
|
||||
otherSessions = listOf(
|
||||
|
|
@ -79,366 +78,366 @@ class PreferencesRootViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Bob").performClick()
|
||||
onNodeWithText("Bob").performClick()
|
||||
eventsRecorder.assertSingle(PreferencesRootEvent.SwitchToSession(A_USER_ID_2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Add account invokes the expected callback`() {
|
||||
fun `click on Add account invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
isMultiAccountEnabled = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onAddAccountClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_add_another_account)
|
||||
clickOn(CommonStrings.common_add_another_account)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when multi account is not enabled, item is not shown`() {
|
||||
fun `when multi account is not enabled, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
isMultiAccountEnabled = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_add_another_account)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_add_another_account)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Encryption invokes the expected callback`() {
|
||||
fun `click on Encryption invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showSecureBackup = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onSecureBackupClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_encryption)
|
||||
clickOn(CommonStrings.common_encryption)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when showSecureBackup is false, item is not shown`() {
|
||||
fun `when showSecureBackup is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showSecureBackup = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_encryption)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_encryption)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Manage account invokes the expected callback`() {
|
||||
fun `click on Manage account invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnceWithParam("aUrl") { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
accountManagementUrl = "aUrl",
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onManageAccountClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_manage_account_and_devices)
|
||||
clickOn(CommonStrings.action_manage_account_and_devices)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when accountManagementUrl is null, item is not shown`() {
|
||||
fun `when accountManagementUrl is null, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
accountManagementUrl = null,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_manage_account_and_devices)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_manage_account_and_devices)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Link new devices invokes the expected callback`() {
|
||||
fun `click on Link new devices invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showLinkNewDevice = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onLinkNewDeviceClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_link_new_device)
|
||||
clickOn(CommonStrings.common_link_new_device)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when showLinkNewDevice is false, item is not shown`() {
|
||||
fun `when showLinkNewDevice is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showLinkNewDevice = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_link_new_device)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_link_new_device)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Analytics invokes the expected callback`() {
|
||||
fun `click on Analytics invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showAnalyticsSettings = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenAnalytics = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_analytics)
|
||||
clickOn(CommonStrings.common_analytics)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when showAnalyticsSettings is false, item is not shown`() {
|
||||
fun `when showAnalyticsSettings is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showAnalyticsSettings = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_analytics)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_analytics)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Report a problem invokes the expected callback`() {
|
||||
fun `click on Report a problem invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
canReportBug = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenRageShake = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_report_a_problem)
|
||||
clickOn(CommonStrings.common_report_a_problem)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when canReportBug is false, item is not shown`() {
|
||||
fun `when canReportBug is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
canReportBug = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_report_a_problem)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_report_a_problem)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Screen lock invokes the expected callback`() {
|
||||
fun `click on Screen lock invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenLockScreenSettings = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_screen_lock)
|
||||
clickOn(CommonStrings.common_screen_lock)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on About invokes the expected callback`() {
|
||||
fun `click on About invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenAbout = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_about)
|
||||
clickOn(CommonStrings.common_about)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Developer settings invokes the expected callback`() {
|
||||
fun `click on Developer settings invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showDeveloperSettings = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenDeveloperSettings = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_developer_options)
|
||||
clickOn(CommonStrings.common_developer_options)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when showDeveloperSettings is false, item is not shown`() {
|
||||
fun `when showDeveloperSettings is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showDeveloperSettings = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_developer_options)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_developer_options)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Advanced settings invokes the expected callback`() {
|
||||
fun `click on Advanced settings invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenAdvancedSettings = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_advanced_settings)
|
||||
clickOn(CommonStrings.common_advanced_settings)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Labs invokes the expected callback`() {
|
||||
fun `click on Labs invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showLabsItem = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenLabs = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_labs_title)
|
||||
clickOn(R.string.screen_labs_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when showLabsItem is false, item is not shown`() {
|
||||
fun `when showLabsItem is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
showLabsItem = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(R.string.screen_labs_title)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(R.string.screen_labs_title)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Notification invokes the expected callback`() {
|
||||
fun `click on Notification invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenNotificationSettings = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_notification_settings_title)
|
||||
clickOn(R.string.screen_notification_settings_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Blocked users invokes the expected callback`() {
|
||||
fun `click on Blocked users invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
nbOfBlockedUsers = 1,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onOpenBlockedUsers = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_blocked_users)
|
||||
clickOn(CommonStrings.common_blocked_users)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when nbOfBlockedUsers is 0, item is not shown`() {
|
||||
fun `when nbOfBlockedUsers is 0, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
nbOfBlockedUsers = 0,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.common_blocked_users)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.common_blocked_users)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Remove this device invokes the expected callback`() {
|
||||
fun `click on Remove this device invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onSignOutClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_signout)
|
||||
clickOn(CommonStrings.action_signout)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on Deactivate invokes the expected callback`() {
|
||||
fun `click on Deactivate invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
canDeactivateAccount = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onDeactivateClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_delete_account)
|
||||
clickOn(CommonStrings.action_delete_account)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when canDeactivateAccount is false, item is not shown`() {
|
||||
fun `when canDeactivateAccount is false, item is not shown`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>(expectEvents = false)
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
canDeactivateAccount = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_delete_account)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_delete_account)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on version sends a PreferencesRootEvents`() {
|
||||
fun `clicking on version sends a PreferencesRootEvents`() = runAndroidComposeUiTest {
|
||||
val version = "VERSION"
|
||||
val eventsRecorder = EventsRecorder<PreferencesRootEvent>()
|
||||
rule.setView(
|
||||
setView(
|
||||
aPreferencesRootState(
|
||||
version = version,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(version).performClick()
|
||||
onNodeWithText(version).performClick()
|
||||
eventsRecorder.assertSingle(PreferencesRootEvent.OnVersionInfoClick)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setView(
|
||||
state: PreferencesRootState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onAddAccountClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.preferences.impl.user.editprofile
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||
|
|
@ -23,96 +26,93 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EditUserProfileViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back emits the expected event`() {
|
||||
fun `clicking on back emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>()
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
eventsRecorder.assertSingle(EditUserProfileEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on save from the exit confirmation dialog emits the expected event`() {
|
||||
fun `clicking on save from the exit confirmation dialog emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>()
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save, inDialog = true)
|
||||
clickOn(CommonStrings.action_save, inDialog = true)
|
||||
eventsRecorder.assertSingle(EditUserProfileEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on discard exit emits the expected event`() {
|
||||
fun `clicking on discard exit emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>()
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_discard)
|
||||
clickOn(CommonStrings.action_discard)
|
||||
eventsRecorder.assertSingle(EditUserProfileEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on save emits the expected event`() {
|
||||
fun `clicking on save emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>()
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
saveButtonEnabled = true,
|
||||
saveAction = AsyncAction.Uninitialized,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertSingle(EditUserProfileEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on avatar opens the bottom sheet dialog`() {
|
||||
fun `clicking on avatar opens the bottom sheet dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>()
|
||||
val actions = listOf(
|
||||
AvatarAction.TakePhoto,
|
||||
AvatarAction.ChoosePhoto,
|
||||
AvatarAction.Remove,
|
||||
)
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
saveAction = AsyncAction.Uninitialized,
|
||||
avatarActions = actions,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val contentDescription = rule.activity.getString(CommonStrings.a11y_avatar)
|
||||
rule.onNodeWithContentDescription(contentDescription).performClick()
|
||||
val resources = activity!!.resources
|
||||
val contentDescription = resources.getString(CommonStrings.a11y_avatar)
|
||||
onNodeWithContentDescription(contentDescription).performClick()
|
||||
// Assert that the actions are displayed
|
||||
actions.forEach { action ->
|
||||
val text = rule.activity.getString(action.titleResId)
|
||||
rule.onNodeWithText(text).assertExists()
|
||||
val text = resources.getString(action.titleResId)
|
||||
onNodeWithText(text).assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `success invokes the expected callback`() {
|
||||
fun `success invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<EditUserProfileEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setEditUserProfileView(
|
||||
setEditUserProfileView(
|
||||
aEditUserProfileState(
|
||||
saveAction = AsyncAction.Success(Unit),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -123,7 +123,7 @@ class EditUserProfileViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setEditUserProfileView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setEditUserProfileView(
|
||||
state: EditUserProfileState,
|
||||
onEditProfileSuccess: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.reportroom.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
|
|
@ -20,76 +23,72 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ReportRoomViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invoke the expected callback`() {
|
||||
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReportRoomEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setReportRoomView(
|
||||
setReportRoomView(
|
||||
aReportRoomState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on report when enabled emits the expected event`() {
|
||||
fun `clicking on report when enabled emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReportRoomEvents>()
|
||||
rule.setReportRoomView(
|
||||
setReportRoomView(
|
||||
aReportRoomState(
|
||||
reason = "Spam",
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_report)
|
||||
clickOn(CommonStrings.action_report)
|
||||
eventsRecorder.assertSingle(ReportRoomEvents.Report)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on decline when disabled does not emit event`() {
|
||||
fun `clicking on decline when disabled does not emit event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReportRoomEvents>(expectEvents = false)
|
||||
rule.setReportRoomView(
|
||||
setReportRoomView(
|
||||
aReportRoomState(eventSink = eventsRecorder),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_report)
|
||||
clickOn(CommonStrings.action_report)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on leave room option emits the expected event`() {
|
||||
fun `clicking on leave room option emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReportRoomEvents>()
|
||||
rule.setReportRoomView(
|
||||
setReportRoomView(
|
||||
aReportRoomState(eventSink = eventsRecorder),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_leave_room)
|
||||
clickOn(CommonStrings.action_leave_room)
|
||||
eventsRecorder.assertSingle(ReportRoomEvents.ToggleLeaveRoom)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `typing text in the reason field emits the expected Event`() {
|
||||
fun `typing text in the reason field emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ReportRoomEvents>()
|
||||
rule.setReportRoomView(
|
||||
setReportRoomView(
|
||||
aReportRoomState(
|
||||
eventSink = eventsRecorder,
|
||||
reason = ""
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("").performTextInput("Spam!")
|
||||
onNodeWithText("").performTextInput("Spam!")
|
||||
eventsRecorder.assertSingle(ReportRoomEvents.UpdateReason("Spam!"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setReportRoomView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setReportRoomView(
|
||||
state: ReportRoomState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.permissions
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.rolesandpermissions.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -23,84 +26,80 @@ import io.element.android.tests.testutils.pressBack
|
|||
import io.element.android.tests.testutils.pressBackKey
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ChangeRoomPermissionsViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `click on back icon invokes Exit`() {
|
||||
fun `click on back icon invokes Exit`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
eventSink = recorder
|
||||
)
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on back key invokes Exit`() {
|
||||
fun `click on back key invokes Exit`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
eventSink = recorder
|
||||
)
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when confirming exit with pending changes, using the back key actually exits`() {
|
||||
fun `when confirming exit with pending changes, using the back key actually exits`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when confirming exit with pending changes, clicking on 'discard' button in the dialog actually exits`() {
|
||||
fun `when confirming exit with pending changes, clicking on 'discard' button in the dialog actually exits`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_discard)
|
||||
clickOn(CommonStrings.action_discard)
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when confirming exit with pending changes, clicking on 'save' button in the dialog saves the changes`() {
|
||||
fun `when confirming exit with pending changes, clicking on 'save' button in the dialog saves the changes`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save, inDialog = true)
|
||||
clickOn(CommonStrings.action_save, inDialog = true)
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on a role item triggers ChangeRole event`() {
|
||||
fun `click on a role item triggers ChangeRole event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
itemsBySection = persistentMapOf(
|
||||
// Makes sure there is only one item to click on
|
||||
|
|
@ -109,70 +108,70 @@ class ChangeRoomPermissionsViewTest {
|
|||
eventSink = recorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_change_permissions_room_name)
|
||||
rule.clickOn(R.string.screen_room_change_permissions_everyone)
|
||||
clickOn(R.string.screen_room_change_permissions_room_name)
|
||||
clickOn(R.string.screen_room_change_permissions_everyone)
|
||||
recorder.assertSingle(
|
||||
ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Everyone),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on the Save menu item triggers Save event`() {
|
||||
fun `click on the Save menu item triggers Save event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a successful save exits the screen`() {
|
||||
fun `a successful save exits the screen`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(true) { callback ->
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.Success(true),
|
||||
),
|
||||
onComplete = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a cancellation exits the screen`() {
|
||||
fun `a cancellation exits the screen`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(false) { callback ->
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.Success(false),
|
||||
),
|
||||
onComplete = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on the Ok option in save error dialog triggers ResetPendingAction event`() {
|
||||
fun `click on the Ok option in save error dialog triggers ResetPendingAction event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ChangeRoomPermissionsEvent>()
|
||||
rule.setChangeRoomPermissionsRule(
|
||||
setChangeRoomPermissionsRule(
|
||||
state = aChangeRoomPermissionsState(
|
||||
hasChanges = true,
|
||||
saveAction = AsyncAction.Failure(IllegalStateException("Failed to set room power levels")),
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
recorder.assertSingle(ChangeRoomPermissionsEvent.ResetPendingActions)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChangeRoomPermissionsRule(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setChangeRoomPermissionsRule(
|
||||
state: ChangeRoomPermissionsState = aChangeRoomPermissionsState(),
|
||||
onComplete: (Boolean) -> Unit = EnsureNeverCalledWithParam(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,15 +6,18 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.roles
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -30,20 +33,16 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
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 ChangeRolesViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `passing a 'User' role throws an exception`() {
|
||||
fun `passing a 'User' role throws an exception`() = runAndroidComposeUiTest {
|
||||
val exception = runCatchingExceptions {
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
role = RoomMember.Role.User,
|
||||
eventSink = EnsureNeverCalledWithParam(),
|
||||
|
|
@ -54,106 +53,106 @@ class ChangeRolesViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `back key - with search active toggles the search`() {
|
||||
fun `back key - with search active toggles the search`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
|
||||
// Advance time to let the event be processed, as the search toggle might have some delay (e.g. for the animation)
|
||||
rule.mainClock.advanceTimeBy(1)
|
||||
mainClock.advanceTimeBy(1)
|
||||
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.ToggleSearchActive)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key - with search inactive exits the screen`() {
|
||||
fun `back key - with search inactive exits the screen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back button - exits the screen`() {
|
||||
fun `back button - exits the screen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save button - with changes, it saves them`() {
|
||||
fun `save button - with changes, it saves them`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
hasPendingChanges = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save button - with no changes, does nothing`() {
|
||||
fun `save button - with no changes, does nothing`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
hasPendingChanges = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exit confirmation dialog - discard exits the screen`() {
|
||||
fun `exit confirmation dialog - discard exits the screen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = true,
|
||||
savingState = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_discard)
|
||||
clickOn(CommonStrings.action_discard)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exit confirmation dialog - save emits the save event`() {
|
||||
fun `exit confirmation dialog - save emits the save event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = true,
|
||||
savingState = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save admins confirmation dialog - submit saves the changes`() {
|
||||
fun `save admins confirmation dialog - submit saves the changes`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
role = RoomMember.Role.Admin,
|
||||
isSearchActive = true,
|
||||
|
|
@ -161,14 +160,14 @@ class ChangeRolesViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save owners confirmation dialog - continue saves the changes`() {
|
||||
fun `save owners confirmation dialog - continue saves the changes`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
role = RoomMember.Role.Owner(isCreator = false),
|
||||
isSearchActive = true,
|
||||
|
|
@ -176,14 +175,14 @@ class ChangeRolesViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save admins confirmation dialog - cancel removes the dialog`() {
|
||||
fun `save admins confirmation dialog - cancel removes the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
role = RoomMember.Role.Admin,
|
||||
isSearchActive = true,
|
||||
|
|
@ -191,14 +190,14 @@ class ChangeRolesViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save owners confirmation dialog - cancel removes the dialog`() {
|
||||
fun `save owners confirmation dialog - cancel removes the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
role = RoomMember.Role.Owner(isCreator = false),
|
||||
isSearchActive = true,
|
||||
|
|
@ -206,39 +205,39 @@ class ChangeRolesViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `error dialog - dismissing removes the dialog`() {
|
||||
fun `error dialog - dismissing removes the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesState(
|
||||
isSearchActive = true,
|
||||
savingState = AsyncAction.Failure(IllegalStateException("boom")),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `testing removing user from selected list emits the expected event`() {
|
||||
fun `testing removing user from selected list emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
val selectedUsers = aMatrixUserList().take(2)
|
||||
val userToDeselect = selectedUsers[1]
|
||||
assertThat(userToDeselect.displayName).isEqualTo("Bob")
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = aChangeRolesStateWithSelectedUsers().copy(
|
||||
selectedUsers = selectedUsers.toImmutableList(),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
// Unselect the user from the row list
|
||||
val contentDescription = rule.activity.getString(CommonStrings.action_remove)
|
||||
rule.onNodeWithContentDescription(
|
||||
val contentDescription = activity!!.getString(CommonStrings.action_remove)
|
||||
onNodeWithContentDescription(
|
||||
label = contentDescription,
|
||||
useUnmergedTree = true,
|
||||
).performClick()
|
||||
|
|
@ -247,7 +246,7 @@ class ChangeRolesViewTest {
|
|||
|
||||
@Test
|
||||
@Config(qualifiers = "h1000dp")
|
||||
fun `testing adding user to the selected list emits the expected event`() {
|
||||
fun `testing adding user to the selected list emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
val selectedUsers = aMatrixUserList().take(2)
|
||||
val state = aChangeRolesStateWithSelectedUsers().copy(
|
||||
|
|
@ -256,16 +255,16 @@ class ChangeRolesViewTest {
|
|||
)
|
||||
val userToSelect = (state.searchResults as SearchBarResultState.Results).results.members.first().toMatrixUser()
|
||||
assertThat(userToSelect.displayName).isEqualTo("Carol")
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = state,
|
||||
)
|
||||
// Select the user from the user list
|
||||
rule.onNodeWithText("Carol").performClick()
|
||||
onNodeWithText("Carol").performClick()
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.UserSelectionToggled(userToSelect))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `testing removing user to the selected list emits the expected event`() {
|
||||
fun `testing removing user to the selected list emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
|
||||
val selectedUsers = aMatrixUserList().take(2)
|
||||
val state = aChangeRolesStateWithSelectedUsers().copy(
|
||||
|
|
@ -274,18 +273,18 @@ class ChangeRolesViewTest {
|
|||
)
|
||||
val userToSelect = (state.searchResults as SearchBarResultState.Results).results.moderators.first().toMatrixUser()
|
||||
assertThat(userToSelect.displayName).isEqualTo("Bob")
|
||||
rule.setChangeRolesContent(
|
||||
setChangeRolesContent(
|
||||
state = state,
|
||||
)
|
||||
// Unselect the user from the user list
|
||||
rule.onAllNodesWithText(
|
||||
onAllNodesWithText(
|
||||
text = "Bob",
|
||||
useUnmergedTree = true,
|
||||
)[1].performClick()
|
||||
eventsRecorder.assertSingle(ChangeRolesEvent.UserSelectionToggled(userToSelect))
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChangeRolesContent(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setChangeRolesContent(
|
||||
state: ChangeRolesState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.rolesandpermissions.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.rolesandpermissions.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -23,159 +26,154 @@ import io.element.android.tests.testutils.ensureCalledOnce
|
|||
import io.element.android.tests.testutils.ensureCalledTimes
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
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 RolesAndPermissionsViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `click on back invokes expected callback`() {
|
||||
fun `click on back invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
goBack = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on Admins opens admin list`() {
|
||||
fun `tapping on Admins opens admin list`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
aRolesAndPermissionsState(
|
||||
roomSupportsOwners = false,
|
||||
eventSink = EventsRecorder(expectEvents = false)
|
||||
),
|
||||
openAdminList = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_admins)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_admins)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on Admins and Owners opens admin list`() {
|
||||
fun `tapping on Admins and Owners opens admin list`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
aRolesAndPermissionsState(
|
||||
roomSupportsOwners = true,
|
||||
eventSink = EventsRecorder(expectEvents = false)
|
||||
),
|
||||
openAdminList = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_admins_and_owners)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_admins_and_owners)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on Moderators opens moderators list`() {
|
||||
fun `tapping on Moderators opens moderators list`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
openModeratorList = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_moderators)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_moderators)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h640dp")
|
||||
fun `tapping permission item open the change permissions screen`() {
|
||||
fun `tapping permission item open the change permissions screen`() = runAndroidComposeUiTest {
|
||||
ensureCalledTimes(1) { callback ->
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
openEditPermissions = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_permissions_header)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_permissions_header)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h640dp")
|
||||
fun `tapping on reset permissions triggers ResetPermissions event`() {
|
||||
fun `tapping on reset permissions triggers ResetPermissions event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_reset)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_reset)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.ResetPermissions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on Reset in the reset permissions confirmation dialog triggers ResetPermissions event`() {
|
||||
fun `tapping on Reset in the reset permissions confirmation dialog triggers ResetPermissions event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
resetPermissionsAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_reset)
|
||||
clickOn(CommonStrings.action_reset)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.ResetPermissions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on Cancel in the reset permissions confirmation dialog triggers CancelPendingAction event`() {
|
||||
fun `tapping on Cancel in the reset permissions confirmation dialog triggers CancelPendingAction event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
resetPermissionsAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.CancelPendingAction)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on 'Demote to moderator' in the demote self bottom sheet triggers the right event`() {
|
||||
fun `tapping on 'Demote to moderator' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator)
|
||||
rule.mainClock.advanceTimeBy(1_000L)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator)
|
||||
mainClock.advanceTimeBy(1_000L)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on 'Demote to member' in the demote self bottom sheet triggers the right event`() = runTest {
|
||||
fun `tapping on 'Demote to member' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_member)
|
||||
rule.mainClock.advanceTimeBy(1_000L)
|
||||
clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_member)
|
||||
mainClock.advanceTimeBy(1_000L)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.User))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tapping on 'Cancel' in the demote self bottom sheet triggers the right event`() {
|
||||
fun `tapping on 'Cancel' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
|
||||
rule.setRolesAndPermissionsView(
|
||||
setRolesAndPermissionsView(
|
||||
state = aRolesAndPermissionsState(
|
||||
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = recorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
rule.mainClock.advanceTimeBy(1_000L)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
mainClock.advanceTimeBy(1_000L)
|
||||
recorder.assertSingle(RolesAndPermissionsEvents.CancelPendingAction)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRolesAndPermissionsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRolesAndPermissionsView(
|
||||
state: RolesAndPermissionsState = aRolesAndPermissionsState(
|
||||
roomSupportsOwners = false,
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.roomaliasresolver.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||
|
|
@ -22,48 +25,44 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomAliasHelperViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomAliasResolverEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setRoomAliasResolverView(
|
||||
setRoomAliasResolverView(
|
||||
aRoomAliasResolverState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Retry emits the expected Event`() {
|
||||
fun `clicking on Retry emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomAliasResolverEvents>()
|
||||
rule.setRoomAliasResolverView(
|
||||
setRoomAliasResolverView(
|
||||
aRoomAliasResolverState(
|
||||
resolveState = AsyncData.Failure(Exception("Error")),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
eventsRecorder.assertSingle(RoomAliasResolverEvents.Retry)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `success state invokes the expected Callback`() {
|
||||
fun `success state invokes the expected Callback`() = runAndroidComposeUiTest {
|
||||
val result = aResolvedRoomAlias()
|
||||
val eventsRecorder = EventsRecorder<RoomAliasResolverEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam(result) {
|
||||
rule.setRoomAliasResolverView(
|
||||
setRoomAliasResolverView(
|
||||
aRoomAliasResolverState(
|
||||
resolveState = AsyncData.Success(result),
|
||||
eventSink = eventsRecorder,
|
||||
|
|
@ -74,7 +73,7 @@ class RoomAliasHelperViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomAliasResolverView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomAliasResolverView(
|
||||
state: RoomAliasResolverState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onAliasResolved: (ResolvedRoomAlias) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.roomdetails.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.roomdetails.impl.members.aRoomMember
|
||||
import io.element.android.features.userprofile.shared.aUserProfileState
|
||||
|
|
@ -32,98 +35,94 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 RoomDetailsViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `click on back invokes expected callback`() {
|
||||
fun `click on back invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
goBack = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on share invokes expected callback`() {
|
||||
fun `click on share invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
onShareRoom = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_share)
|
||||
clickOn(CommonStrings.action_share)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on room members invokes expected callback`() {
|
||||
fun `click on room members invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
openRoomMemberList = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_people)
|
||||
clickOn(CommonStrings.common_people)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on polls invokes expected callback`() {
|
||||
fun `click on polls invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
openPollHistory = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_polls_history_title)
|
||||
clickOn(R.string.screen_polls_history_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on media gallery invokes expected callback`() {
|
||||
fun `click on media gallery invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
openMediaGallery = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_media_gallery_title)
|
||||
clickOn(R.string.screen_room_details_media_gallery_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on notification invokes expected callback`() {
|
||||
fun `click on notification invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
openRoomNotificationSettings = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_notification_title)
|
||||
clickOn(R.string.screen_room_details_notification_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on invite invokes expected callback`() {
|
||||
fun `click on invite invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canInvite = true,
|
||||
),
|
||||
invitePeople = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_invite)
|
||||
clickOn(CommonStrings.action_invite)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on call invokes expected callback`() {
|
||||
fun `click on call invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(CallIntent.AUDIO) { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canInvite = true,
|
||||
|
|
@ -134,103 +133,103 @@ class RoomDetailsViewTest {
|
|||
),
|
||||
onJoinCallClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_call)
|
||||
clickOn(CommonStrings.action_call)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on video call invokes expected callback`() {
|
||||
fun `click on video call invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(CallIntent.VIDEO) { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canInvite = true,
|
||||
),
|
||||
onJoinCallClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_video)
|
||||
clickOn(CommonStrings.common_video)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on pinned messages invokes expected callback`() {
|
||||
fun `click on pinned messages invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canInvite = true,
|
||||
),
|
||||
onPinnedMessagesClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_pinned_events_row_title)
|
||||
clickOn(R.string.screen_room_details_pinned_events_row_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on security and privacy invokes expected callback`() {
|
||||
fun `click on security and privacy invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canShowSecurityAndPrivacy = true,
|
||||
),
|
||||
onSecurityAndPrivacyClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_security_and_privacy_title)
|
||||
clickOn(R.string.screen_room_details_security_and_privacy_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on add topic emit expected event`() {
|
||||
fun `click on add topic emit expected event`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam<RoomDetailsAction>(RoomDetailsAction.AddTopic) { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
roomTopic = RoomTopicState.CanAddTopic,
|
||||
),
|
||||
onActionClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_add_topic_title)
|
||||
clickOn(R.string.screen_room_details_add_topic_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on menu edit emit expected event`() {
|
||||
fun `click on menu edit emit expected event`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam<RoomDetailsAction>(RoomDetailsAction.Edit) { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canEdit = true,
|
||||
),
|
||||
onActionClick = callback,
|
||||
)
|
||||
val menuContentDescription = rule.activity.getString(CommonStrings.a11y_user_menu)
|
||||
rule.onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
rule.clickOn(CommonStrings.action_edit)
|
||||
val menuContentDescription = activity!!.getString(CommonStrings.a11y_user_menu)
|
||||
onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
clickOn(CommonStrings.action_edit)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on avatar test`() {
|
||||
fun `click on avatar test`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>(expectEvents = false)
|
||||
val state = aRoomDetailsState(
|
||||
eventSink = eventsRecorder,
|
||||
roomAvatarUrl = "an_avatar_url",
|
||||
)
|
||||
val callback = EnsureCalledOnceWithTwoParams(state.roomName, "an_avatar_url")
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = state,
|
||||
openAvatarPreview = callback,
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.roomDetailAvatar.value).performClick()
|
||||
onNodeWithTag(TestTags.roomDetailAvatar.value).performClick()
|
||||
callback.assertSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on avatar test on DM`() {
|
||||
fun `click on avatar test on DM`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>(expectEvents = false)
|
||||
val state = aRoomDetailsState(
|
||||
roomType = RoomDetailsType.Dm(
|
||||
|
|
@ -241,114 +240,114 @@ class RoomDetailsViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
val callback = EnsureCalledOnceWithTwoParams("Daniel", "an_avatar_url")
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = state,
|
||||
openAvatarPreview = callback,
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.memberDetailAvatar.value).performClick()
|
||||
onNodeWithTag(TestTags.memberDetailAvatar.value).performClick()
|
||||
callback.assertSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on mute emit expected event`() {
|
||||
fun `click on mute emit expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>()
|
||||
val state = aRoomDetailsState(
|
||||
eventSink = eventsRecorder,
|
||||
roomNotificationSettings = aRoomNotificationSettings(mode = RoomNotificationMode.ALL_MESSAGES),
|
||||
)
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = state,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_mute)
|
||||
clickOn(CommonStrings.common_mute)
|
||||
eventsRecorder.assertSingle(RoomDetailsEvent.MuteNotification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on unmute emit expected event`() {
|
||||
fun `click on unmute emit expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>()
|
||||
val state = aRoomDetailsState(
|
||||
eventSink = eventsRecorder,
|
||||
roomNotificationSettings = aRoomNotificationSettings(mode = RoomNotificationMode.MUTE),
|
||||
)
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = state,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_unmute)
|
||||
clickOn(CommonStrings.common_unmute)
|
||||
eventsRecorder.assertSingle(RoomDetailsEvent.UnmuteNotification)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on favorite emit expected Event`() {
|
||||
fun `click on favorite emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>()
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_favourite)
|
||||
clickOn(CommonStrings.common_favourite)
|
||||
eventsRecorder.assertSingle(RoomDetailsEvent.SetFavorite(true))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1500dp")
|
||||
@Test
|
||||
fun `click on leave emit expected Event`() {
|
||||
fun `click on leave emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEvent>()
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_leave_room_title)
|
||||
clickOn(R.string.screen_room_details_leave_room_title)
|
||||
eventsRecorder.assertSingle(RoomDetailsEvent.LeaveRoom(needsConfirmation = true))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1500dp")
|
||||
@Test
|
||||
fun `click on report room invokes expected callback`() {
|
||||
fun `click on report room invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
),
|
||||
onReportRoomClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_report_room)
|
||||
clickOn(CommonStrings.action_report_room)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on knock requests invokes expected callback`() {
|
||||
fun `click on knock requests invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
canShowKnockRequests = true,
|
||||
),
|
||||
onKnockRequestsClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_requests_to_join_title)
|
||||
clickOn(R.string.screen_room_details_requests_to_join_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on profile invokes the expected callback`() {
|
||||
fun `click on profile invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(A_USER_ID) { callback ->
|
||||
rule.setRoomDetailView(
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
roomMemberDetailsState = aUserProfileState(userId = A_USER_ID),
|
||||
),
|
||||
onProfileClick = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_details_profile_row_title)
|
||||
clickOn(R.string.screen_room_details_profile_row_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomDetailView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomDetailView(
|
||||
state: RoomDetailsState = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,18 +5,21 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.roomdetailsedit.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.hasTestTag
|
||||
import androidx.compose.ui.test.isEditable
|
||||
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.performClick
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||
|
|
@ -28,58 +31,54 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomDetailsEditViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back emits the expected Event`() {
|
||||
fun `clicking on back emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on discard when confirming exit emits the expected Event`() {
|
||||
fun `clicking on discard when confirming exit emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_discard)
|
||||
clickOn(CommonStrings.action_discard)
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on save when confirming exit emits the expected Event`() {
|
||||
fun `clicking on save when confirming exit emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save, inDialog = true)
|
||||
clickOn(CommonStrings.action_save, inDialog = true)
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when edition is successful, the expected callback is invoked`() {
|
||||
fun `when edition is successful, the expected callback is invoked`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
saveAction = AsyncAction.Success(Unit)
|
||||
|
|
@ -90,55 +89,55 @@ class RoomDetailsEditViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when name is changed, the expected Event is emitted`() {
|
||||
fun `when name is changed, the expected Event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
roomRawName = "Marketing",
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Marketing").performTextInput("A")
|
||||
onNodeWithText("Marketing").performTextInput("A")
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomName("AMarketing"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user cannot change name, nothing happen`() {
|
||||
fun `when user cannot change name, nothing happen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
roomRawName = "Marketing",
|
||||
canChangeName = false,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Marketing").assert(!isEditable())
|
||||
onNodeWithText("Marketing").assert(!isEditable())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when topic is changed, the expected Event is emitted`() {
|
||||
fun `when topic is changed, the expected Event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
roomTopic = "My Topic",
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("My Topic").performTextInput("A")
|
||||
onNodeWithText("My Topic").performTextInput("A")
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomTopic("AMy Topic"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user cannot change topic, nothing happen`() {
|
||||
fun `when user cannot change topic, nothing happen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
roomTopic = "My Topic",
|
||||
canChangeTopic = false,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("My Topic").assert(!isEditable())
|
||||
onNodeWithText("My Topic").assert(!isEditable())
|
||||
}
|
||||
|
||||
@Ignore("This test is failing because the bottom sheet does not open")
|
||||
|
|
@ -171,73 +170,73 @@ class RoomDetailsEditViewTest {
|
|||
private fun testAvatarChange(
|
||||
@StringRes stringActionRes: Int,
|
||||
expectedEvent: RoomDetailsEditEvent.HandleAvatarAction,
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
// Open the bottom sheet
|
||||
rule.onNode(hasTestTag(TestTags.editAvatar.value)).performClick()
|
||||
rule.onNodeWithText(rule.activity.getString(stringActionRes)).assertExists()
|
||||
rule.clickOn(stringActionRes)
|
||||
onNode(hasTestTag(TestTags.editAvatar.value)).performClick()
|
||||
onNodeWithText(activity!!.getString(stringActionRes)).assertExists()
|
||||
clickOn(stringActionRes)
|
||||
eventsRecorder.assertSingle(expectedEvent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user cannot change avatar, nothing happen`() {
|
||||
fun `when user cannot change avatar, nothing happen`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
canChangeAvatar = false,
|
||||
),
|
||||
)
|
||||
rule.onNode(hasTestTag(TestTags.editAvatar.value)).performClick()
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_take_photo)).assertDoesNotExist()
|
||||
onNode(hasTestTag(TestTags.editAvatar.value)).performClick()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_take_photo)).assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when save is clicked, the expected Event is emitted`() {
|
||||
fun `when save is clicked, the expected Event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
saveButtonEnabled = true,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when save is clicked, but nothing need to be saved, nothing happens`() {
|
||||
fun `when save is clicked, but nothing need to be saved, nothing happens`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
saveButtonEnabled = false,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when error is shown, closing the dialog emit the expected Event`() {
|
||||
fun `when error is shown, closing the dialog emit the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
|
||||
rule.setRoomDetailsEditView(
|
||||
setRoomDetailsEditView(
|
||||
aRoomDetailsEditState(
|
||||
eventSink = eventsRecorder,
|
||||
saveAction = AsyncAction.Failure(RuntimeException("Whelp")),
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ok)
|
||||
clickOn(CommonStrings.action_ok)
|
||||
eventsRecorder.assertSingle(RoomDetailsEditEvent.CloseDialog)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomDetailsEditView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomDetailsEditView(
|
||||
state: RoomDetailsEditState,
|
||||
onDone: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,15 +6,18 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.roomdirectory.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.roomdirectory.api.RoomDescription
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
|
|
@ -22,31 +25,27 @@ 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.ensureCalledOnceWithParam
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomDirectoryViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `typing text in search field emits the expected Event`() {
|
||||
fun `typing text in search field emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDirectoryEvents>()
|
||||
rule.setRoomDirectoryView(
|
||||
setRoomDirectoryView(
|
||||
state = aRoomDirectoryState(
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.onNodeWithTag(TestTags.searchTextField.value).performTextInput(
|
||||
onNodeWithTag(TestTags.searchTextField.value).performTextInput(
|
||||
text = "Test"
|
||||
)
|
||||
eventsRecorder.assertSingle(RoomDirectoryEvents.Search("Test"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on room item then onResultClick lambda is called once`() {
|
||||
fun `clicking on room item then onResultClick lambda is called once`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDirectoryEvents>()
|
||||
val state = aRoomDirectoryState(
|
||||
roomDescriptions = aRoomDescriptionList(),
|
||||
|
|
@ -54,27 +53,27 @@ class RoomDirectoryViewTest {
|
|||
)
|
||||
val clickedRoom = state.roomDescriptions.first()
|
||||
ensureCalledOnceWithParam(clickedRoom) { callback ->
|
||||
rule.setRoomDirectoryView(
|
||||
setRoomDirectoryView(
|
||||
state = state,
|
||||
onResultClick = callback,
|
||||
)
|
||||
rule.onNodeWithText(clickedRoom.computedName).performClick()
|
||||
onNodeWithText(clickedRoom.computedName).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `composing load more indicator emits expected Event`() {
|
||||
fun `composing load more indicator emits expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomDirectoryEvents>()
|
||||
val state = aRoomDirectoryState(
|
||||
displayLoadMoreIndicator = true,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
rule.setRoomDirectoryView(state = state)
|
||||
setRoomDirectoryView(state = state)
|
||||
eventsRecorder.assertSingle(RoomDirectoryEvents.LoadMore)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomDirectoryView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomDirectoryView(
|
||||
state: RoomDirectoryState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onResultClick: (RoomDescription) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.roommembermoderation.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.roommembermoderation.api.ModerationAction
|
||||
import io.element.android.features.roommembermoderation.api.ModerationActionState
|
||||
|
|
@ -24,21 +27,17 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnceWithTwoParams
|
||||
import io.element.android.tests.testutils.pressTag
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RoomMemberModerationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on display profile action calls onSelectAction`() {
|
||||
fun `clicking on display profile action calls onSelectAction`() = runAndroidComposeUiTest {
|
||||
val user = anAlice()
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithTwoParams<ModerationAction, MatrixUser>(ModerationAction.DisplayProfile, user) { callback ->
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = user,
|
||||
actions = listOf(
|
||||
|
|
@ -48,16 +47,16 @@ class RoomMemberModerationViewTest {
|
|||
),
|
||||
onSelectAction = callback
|
||||
)
|
||||
rule.clickOn(R.string.screen_bottom_sheet_manage_room_member_member_user_info)
|
||||
clickOn(R.string.screen_bottom_sheet_manage_room_member_member_user_info)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on kick user action calls onSelectAction`() {
|
||||
fun `clicking on kick user action calls onSelectAction`() = runAndroidComposeUiTest {
|
||||
val user = anAlice()
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithTwoParams<ModerationAction, MatrixUser>(ModerationAction.KickUser, user) { callback ->
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = user,
|
||||
actions = listOf(
|
||||
|
|
@ -67,18 +66,18 @@ class RoomMemberModerationViewTest {
|
|||
),
|
||||
onSelectAction = callback
|
||||
)
|
||||
rule.clickOn(R.string.screen_bottom_sheet_manage_room_member_remove)
|
||||
clickOn(R.string.screen_bottom_sheet_manage_room_member_remove)
|
||||
// Gives time for bottomsheet to hide
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
mainClock.advanceTimeBy(1_000)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on ban user action calls onSelectAction`() {
|
||||
fun `clicking on ban user action calls onSelectAction`() = runAndroidComposeUiTest {
|
||||
val user = anAlice()
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithTwoParams<ModerationAction, MatrixUser>(ModerationAction.BanUser, user) { callback ->
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = user,
|
||||
actions = listOf(
|
||||
|
|
@ -88,18 +87,18 @@ class RoomMemberModerationViewTest {
|
|||
),
|
||||
onSelectAction = callback
|
||||
)
|
||||
rule.clickOn(R.string.screen_bottom_sheet_manage_room_member_ban)
|
||||
clickOn(R.string.screen_bottom_sheet_manage_room_member_ban)
|
||||
// Gives time for bottomsheet to hide
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
mainClock.advanceTimeBy(1_000)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on unban user action calls onSelectAction`() {
|
||||
fun `clicking on unban user action calls onSelectAction`() = runAndroidComposeUiTest {
|
||||
val user = anAlice()
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithTwoParams<ModerationAction, MatrixUser>(ModerationAction.UnbanUser, user) { callback ->
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = user,
|
||||
actions = listOf(
|
||||
|
|
@ -109,100 +108,100 @@ class RoomMemberModerationViewTest {
|
|||
),
|
||||
onSelectAction = callback
|
||||
)
|
||||
rule.clickOn(R.string.screen_bottom_sheet_manage_room_member_unban)
|
||||
clickOn(R.string.screen_bottom_sheet_manage_room_member_unban)
|
||||
// Gives time for bottomsheet to hide
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
mainClock.advanceTimeBy(1_000)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking submit on kick confirmation dialog sends DoKickUser event`() {
|
||||
fun `clicking submit on kick confirmation dialog sends DoKickUser event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
kickUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.DoKickUser(reason = ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking dismiss on kick confirmation dialog sends Reset event`() {
|
||||
fun `clicking dismiss on kick confirmation dialog sends Reset event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
kickUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogNegative.value)
|
||||
pressTag(TestTags.dialogNegative.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.Reset)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking submit on ban confirmation dialog sends DoBanUser event`() {
|
||||
fun `clicking submit on ban confirmation dialog sends DoBanUser event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
banUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.DoBanUser(reason = ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking dismiss on ban confirmation dialog sends Reset event`() {
|
||||
fun `clicking dismiss on ban confirmation dialog sends Reset event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
banUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogNegative.value)
|
||||
pressTag(TestTags.dialogNegative.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.Reset)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking confirm on unban confirmation dialog sends DoUnbanUser event`() {
|
||||
fun `clicking confirm on unban confirmation dialog sends DoUnbanUser event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
unbanUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogPositive.value)
|
||||
pressTag(TestTags.dialogPositive.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.DoUnbanUser(""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking dismiss on unban confirmation dialog sends Reset event`() {
|
||||
fun `clicking dismiss on unban confirmation dialog sends Reset event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>()
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
unbanUserAsyncAction = AsyncAction.ConfirmingNoParams,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressTag(TestTags.dialogNegative.value)
|
||||
pressTag(TestTags.dialogNegative.value)
|
||||
eventsRecorder.assertSingle(InternalRoomMemberModerationEvents.Reset)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `disabled actions are not clickable`() {
|
||||
fun `disabled actions are not clickable`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<RoomMemberModerationEvents>(expectEvents = false)
|
||||
rule.setRoomMemberModerationView(
|
||||
setRoomMemberModerationView(
|
||||
aRoomMembersModerationState(
|
||||
selectedUser = anAlice(),
|
||||
actions = listOf(
|
||||
|
|
@ -211,11 +210,11 @@ class RoomMemberModerationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_bottom_sheet_manage_room_member_remove)
|
||||
clickOn(R.string.screen_bottom_sheet_manage_room_member_remove)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomMemberModerationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomMemberModerationView(
|
||||
state: InternalRoomMemberModerationState,
|
||||
onSelectAction: (ModerationAction, MatrixUser) -> Unit = EnsureNeverCalledWithTwoParams(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performImeAction
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -26,58 +29,54 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
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 SecureBackupEnterRecoveryKeyViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `back key pressed - calls onBackClick`() {
|
||||
fun `back key pressed - calls onBackClick`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back button clicked - calls onBackClick`() {
|
||||
fun `back button clicked - calls onBackClick`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `tapping on Continue when key is valid - calls expected action`() {
|
||||
fun `tapping on Continue when key is valid - calls expected action`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `entering a char emits the expected event`() {
|
||||
fun `entering a char emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.onNodeWithText(keyValue).performTextInput("X")
|
||||
onNodeWithText(keyValue).performTextInput("X")
|
||||
recorder.assertSingle(
|
||||
SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("X$keyValue")
|
||||
)
|
||||
|
|
@ -85,43 +84,43 @@ class SecureBackupEnterRecoveryKeyViewTest {
|
|||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `toggling the visibility of the textfield changes it`() {
|
||||
fun `toggling the visibility of the textfield changes it`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder))
|
||||
setSecureBackupEnterRecoveryKeyView(aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder))
|
||||
|
||||
// Initially, the text field should be visible
|
||||
rule.onNodeWithText(keyValue).assertExists()
|
||||
onNodeWithText(keyValue).assertExists()
|
||||
|
||||
rule.onNodeWithContentDescription(rule.activity.getString(CommonStrings.a11y_hide_password)).performClick()
|
||||
onNodeWithContentDescription(activity!!.getString(CommonStrings.a11y_hide_password)).performClick()
|
||||
|
||||
rule.waitForIdle()
|
||||
waitForIdle()
|
||||
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validating from keyboard emits the expected event`() {
|
||||
fun `validating from keyboard emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.onNodeWithText(keyValue).performImeAction()
|
||||
onNodeWithText(keyValue).performImeAction()
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when submit action succeeds - calls onDone`() {
|
||||
fun `when submit action succeeds - calls onDone`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Success(Unit)),
|
||||
onDone = callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSecureBackupEnterRecoveryKeyView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setSecureBackupEnterRecoveryKeyView(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onDone: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -22,64 +25,59 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ResetIdentityPasswordViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `pressing the back HW button invokes the expected callback`() {
|
||||
fun `pressing the back HW button invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setResetPasswordView(
|
||||
setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the back navigation button invokes the expected callback`() {
|
||||
fun `clicking on the back navigation button invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setResetPasswordView(
|
||||
setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking 'Reset identity' confirms the reset`() {
|
||||
fun `clicking 'Reset identity' confirms the reset`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityPasswordEvent>()
|
||||
rule.setResetPasswordView(
|
||||
setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = eventsRecorder),
|
||||
)
|
||||
rule.onNodeWithText("Password").performTextInput("A password")
|
||||
onNodeWithText("Password").performTextInput("A password")
|
||||
|
||||
rule.clickOn(CommonStrings.action_reset_identity)
|
||||
clickOn(CommonStrings.action_reset_identity)
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityPasswordEvent.Reset("A password"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `modifying the password dismisses the error state`() {
|
||||
fun `modifying the password dismisses the error state`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityPasswordEvent>()
|
||||
rule.setResetPasswordView(
|
||||
setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Failure(IllegalStateException("A failure")), eventSink = eventsRecorder),
|
||||
)
|
||||
rule.onNodeWithText("Password").performTextInput("A password")
|
||||
onNodeWithText("Password").performTextInput("A password")
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityPasswordEvent.DismissError)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setResetPasswordView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setResetPasswordView(
|
||||
state: ResetIdentityPasswordState,
|
||||
onBack: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -20,76 +23,71 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
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 ResetIdentityRootViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `pressing the back HW button invokes the expected callback`() {
|
||||
fun `pressing the back HW button invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the back navigation button invokes the expected callback`() {
|
||||
fun `clicking on the back navigation button invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h720dp")
|
||||
fun `clicking Continue displays the confirmation dialog`() {
|
||||
fun `clicking Continue displays the confirmation dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityRootEvent>()
|
||||
rule.setResetRootView(
|
||||
setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = eventsRecorder),
|
||||
)
|
||||
|
||||
rule.clickOn(R.string.screen_encryption_reset_action_continue_reset)
|
||||
clickOn(R.string.screen_encryption_reset_action_continue_reset)
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityRootEvent.Continue)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking 'Yes, reset now' confirms the reset`() {
|
||||
fun `clicking 'Yes, reset now' confirms the reset`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = true, eventSink = {}),
|
||||
onContinue = it,
|
||||
)
|
||||
rule.clickOn(R.string.screen_reset_encryption_confirmation_alert_action)
|
||||
clickOn(R.string.screen_reset_encryption_confirmation_alert_action)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking Cancel dismisses the dialog`() {
|
||||
fun `clicking Cancel dismisses the dialog`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityRootEvent>()
|
||||
rule.setResetRootView(
|
||||
setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = true, eventSink = eventsRecorder),
|
||||
)
|
||||
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ResetIdentityRootEvent.DismissDialog)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setResetRootView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setResetRootView(
|
||||
state: ResetIdentityRootState,
|
||||
onBack: () -> Unit = EnsureNeverCalled(),
|
||||
onContinue: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securityandprivacy.impl.editroomaddress
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity
|
||||
|
|
@ -23,86 +26,82 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EditRoomAddressViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `click on back invokes expected callback`() {
|
||||
fun `click on back invokes expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setEditRoomAddressView(onBackClick = callback)
|
||||
rule.pressBack()
|
||||
setEditRoomAddressView(onBackClick = callback)
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on disabled save doesn't emit event`() {
|
||||
fun `click on disabled save doesn't emit event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<EditRoomAddressEvents>(expectEvents = false)
|
||||
val state = anEditRoomAddressState(eventSink = recorder)
|
||||
rule.setEditRoomAddressView(state)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
setEditRoomAddressView(state)
|
||||
clickOn(CommonStrings.action_save)
|
||||
recorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on enabled save emits the expected event`() {
|
||||
fun `click on enabled save emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<EditRoomAddressEvents>()
|
||||
val state = anEditRoomAddressState(
|
||||
roomAddress = "room",
|
||||
roomAddressValidity = RoomAddressValidity.Valid,
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setEditRoomAddressView(state)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
setEditRoomAddressView(state)
|
||||
clickOn(CommonStrings.action_save)
|
||||
recorder.assertSingle(EditRoomAddressEvents.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `text changes on text field emits the expected event`() {
|
||||
fun `text changes on text field emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<EditRoomAddressEvents>()
|
||||
val state = anEditRoomAddressState(
|
||||
roomAddress = "",
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setEditRoomAddressView(state)
|
||||
setEditRoomAddressView(state)
|
||||
|
||||
rule.onNodeWithTag(TestTags.roomAddressField.value).performTextInput("alias")
|
||||
onNodeWithTag(TestTags.roomAddressField.value).performTextInput("alias")
|
||||
recorder.assertSingle(EditRoomAddressEvents.RoomAddressChanged("alias"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on dismiss error emits the expected event`() {
|
||||
fun `click on dismiss error emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<EditRoomAddressEvents>()
|
||||
val state = anEditRoomAddressState(
|
||||
roomAddress = "",
|
||||
saveAction = AsyncAction.Failure(IllegalStateException()),
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setEditRoomAddressView(state)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
setEditRoomAddressView(state)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
recorder.assertSingle(EditRoomAddressEvents.DismissError)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on retry error emits the expected event`() {
|
||||
fun `click on retry error emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<EditRoomAddressEvents>()
|
||||
val state = anEditRoomAddressState(
|
||||
roomAddress = "",
|
||||
saveAction = AsyncAction.Failure(IllegalStateException()),
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setEditRoomAddressView(state)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
setEditRoomAddressView(state)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
recorder.assertSingle(EditRoomAddressEvents.Save)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setEditRoomAddressView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setEditRoomAddressView(
|
||||
state: EditRoomAddressState = anEditRoomAddressState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
|
||||
|
|
@ -24,26 +27,22 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ManageAuthorizedSpacesViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking back emits Cancel event`() {
|
||||
fun `clicking back emits Cancel event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ManageAuthorizedSpacesEvent>()
|
||||
val state = aManageAuthorizedSpacesState(eventSink = recorder)
|
||||
rule.setManageAuthorizedSpacesView(state)
|
||||
rule.pressBack()
|
||||
setManageAuthorizedSpacesView(state)
|
||||
pressBack()
|
||||
recorder.assertSingle(ManageAuthorizedSpacesEvent.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking space checkbox emits ToggleSpace event`() {
|
||||
fun `clicking space checkbox emits ToggleSpace event`() = runAndroidComposeUiTest {
|
||||
val roomId = A_ROOM_ID
|
||||
val space = aSpaceRoom(roomId = roomId, displayName = "Test Space")
|
||||
val recorder = EventsRecorder<ManageAuthorizedSpacesEvent>()
|
||||
|
|
@ -51,37 +50,37 @@ class ManageAuthorizedSpacesViewTest {
|
|||
selectableSpaces = listOf(space),
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setManageAuthorizedSpacesView(state)
|
||||
rule.onNodeWithText("Test Space").performClick()
|
||||
setManageAuthorizedSpacesView(state)
|
||||
onNodeWithText("Test Space").performClick()
|
||||
recorder.assertSingle(ManageAuthorizedSpacesEvent.ToggleSpace(roomId))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking done button emits Done event`() {
|
||||
fun `clicking done button emits Done event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ManageAuthorizedSpacesEvent>()
|
||||
val state = aManageAuthorizedSpacesState(
|
||||
selectedIds = listOf(A_ROOM_ID),
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setManageAuthorizedSpacesView(state)
|
||||
rule.clickOn(CommonStrings.action_done)
|
||||
setManageAuthorizedSpacesView(state)
|
||||
clickOn(CommonStrings.action_done)
|
||||
recorder.assertSingle(ManageAuthorizedSpacesEvent.Done)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `done button is disabled when no spaces selected`() {
|
||||
fun `done button is disabled when no spaces selected`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<ManageAuthorizedSpacesEvent>(expectEvents = false)
|
||||
val state = aManageAuthorizedSpacesState(
|
||||
selectedIds = emptyList(),
|
||||
eventSink = recorder
|
||||
)
|
||||
rule.setManageAuthorizedSpacesView(state)
|
||||
rule.clickOn(CommonStrings.action_done)
|
||||
setManageAuthorizedSpacesView(state)
|
||||
clickOn(CommonStrings.action_done)
|
||||
recorder.assertEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setManageAuthorizedSpacesView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setManageAuthorizedSpacesView(
|
||||
state: ManageAuthorizedSpacesState = aManageAuthorizedSpacesState(
|
||||
eventSink = EventsRecorder(expectEvents = false)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,13 +5,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.securityandprivacy.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.securityandprivacy.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
|
@ -23,73 +26,69 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
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 SecurityAndPrivacyViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `click on back invokes emits the expected event`() {
|
||||
fun `click on back invokes emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.pressBack()
|
||||
setSecurityAndPrivacyView(state)
|
||||
pressBack()
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `discard cancellation emits the expected event`() {
|
||||
fun `discard cancellation emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = recorder,
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(CommonStrings.action_discard)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(CommonStrings.action_discard)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.Exit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `save cancellation confirmation emits the expected event`() {
|
||||
fun `save cancellation confirmation emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
saveAction = AsyncAction.ConfirmingCancellation,
|
||||
eventSink = recorder,
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(CommonStrings.action_save, inDialog = true)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(CommonStrings.action_save, inDialog = true)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on room access item emits the expected event`() {
|
||||
fun `click on room access item emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_room_access_invite_only_option_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_room_access_invite_only_option_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.InviteOnly))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on disabled save doesn't emit event`() {
|
||||
fun `click on disabled save doesn't emit event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>(expectEvents = false)
|
||||
val state = aSecurityAndPrivacyState(eventSink = recorder)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(CommonStrings.action_save)
|
||||
recorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on enabled save emits the expected event`() {
|
||||
fun `click on enabled save emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
|
|
@ -97,14 +96,14 @@ class SecurityAndPrivacyViewTest {
|
|||
roomAccess = SecurityAndPrivacyRoomAccess.Anyone,
|
||||
)
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(CommonStrings.action_save)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.Save)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h640dp")
|
||||
fun `click on room address item emits the expected event`() {
|
||||
fun `click on room address item emits the expected event`() = runAndroidComposeUiTest {
|
||||
val address = "@alias:matrix.org"
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
|
|
@ -114,14 +113,14 @@ class SecurityAndPrivacyViewTest {
|
|||
roomAccess = SecurityAndPrivacyRoomAccess.Anyone,
|
||||
),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.onNodeWithText(address).performClick()
|
||||
setSecurityAndPrivacyView(state)
|
||||
onNodeWithText(address).performClick()
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.EditRoomAddress)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `click on room visibility item emits the expected event`() {
|
||||
fun `click on room visibility item emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
|
|
@ -130,14 +129,14 @@ class SecurityAndPrivacyViewTest {
|
|||
isVisibleInRoomDirectory = AsyncData.Success(false),
|
||||
),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_room_directory_visibility_toggle_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_room_directory_visibility_toggle_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.ToggleRoomVisibility)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `click on history visibility item emits the expected event`() {
|
||||
fun `click on history visibility item emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
|
|
@ -145,65 +144,65 @@ class SecurityAndPrivacyViewTest {
|
|||
historyVisibility = SecurityAndPrivacyHistoryVisibility.Invited,
|
||||
),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_room_history_since_invite_option_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_room_history_since_invite_option_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Invited))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `click on encryption item emits the expected event`() {
|
||||
fun `click on encryption item emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
savedSettings = aSecurityAndPrivacySettings(isEncrypted = false),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_encryption_toggle_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_encryption_toggle_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.ToggleEncryptionState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on encryption confirm emits the expected event`() {
|
||||
fun `click on encryption confirm emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
showEncryptionConfirmation = true,
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_enable_encryption_alert_confirm_button_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_enable_encryption_alert_confirm_button_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.ConfirmEnableEncryption)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `click on space member access emits the expected event`() {
|
||||
fun `click on space member access emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
spaceSelectionMode = SpaceSelectionMode.Single(A_ROOM_ID, null),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_room_access_space_members_option_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_room_access_space_members_option_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.SelectSpaceMemberAccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `click on ask to join with space members emits the expected event`() {
|
||||
fun `click on ask to join with space members emits the expected event`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>()
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
spaceSelectionMode = SpaceSelectionMode.Single(A_ROOM_ID, null),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
rule.clickOn(R.string.screen_security_and_privacy_ask_to_join_option_title)
|
||||
setSecurityAndPrivacyView(state)
|
||||
clickOn(R.string.screen_security_and_privacy_ask_to_join_option_title)
|
||||
recorder.assertSingle(SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `manage spaces footer is shown when space member access is selected`() {
|
||||
fun `manage spaces footer is shown when space member access is selected`() = runAndroidComposeUiTest {
|
||||
val recorder = EventsRecorder<SecurityAndPrivacyEvent>(expectEvents = false)
|
||||
val state = aSecurityAndPrivacyState(
|
||||
eventSink = recorder,
|
||||
|
|
@ -212,15 +211,16 @@ class SecurityAndPrivacyViewTest {
|
|||
roomAccess = SecurityAndPrivacyRoomAccess.SpaceMember(persistentListOf(A_ROOM_ID)),
|
||||
),
|
||||
)
|
||||
rule.setSecurityAndPrivacyView(state)
|
||||
setSecurityAndPrivacyView(state)
|
||||
// The footer text uses AnnotatedString with a link. Verify the footer text is displayed.
|
||||
val actionFooterText = rule.activity.getString(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action)
|
||||
val footerText = rule.activity.getString(R.string.screen_security_and_privacy_room_access_footer, actionFooterText)
|
||||
rule.onNodeWithText(footerText).assertExists()
|
||||
val resources = activity!!.resources
|
||||
val actionFooterText = resources.getString(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action)
|
||||
val footerText = resources.getString(R.string.screen_security_and_privacy_room_access_footer, actionFooterText)
|
||||
onNodeWithText(footerText).assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSecurityAndPrivacyView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setSecurityAndPrivacyView(
|
||||
state: SecurityAndPrivacyState = aSecurityAndPrivacyState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,13 +5,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.space.impl.addroom
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
||||
|
|
@ -22,77 +25,73 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
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 AddRoomToSpaceViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking back when search inactive emits Dismiss and invokes onBackClick`() {
|
||||
fun `clicking back when search inactive emits Dismiss and invokes onBackClick`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AddRoomToSpaceEvent>()
|
||||
ensureCalledOnce {
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
isSearchActive = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
eventsRecorder.assertSingle(AddRoomToSpaceEvent.Dismiss)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking back when search active emits CloseSearch event`() {
|
||||
fun `clicking back when search active emits CloseSearch event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AddRoomToSpaceEvent>()
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
isSearchActive = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
eventsRecorder.assertSingle(AddRoomToSpaceEvent.OnSearchActiveChanged(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking save emits Save event`() {
|
||||
fun `clicking save emits Save event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AddRoomToSpaceEvent>()
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
selectedRooms = aSelectRoomInfoList().take(1).toImmutableList(),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_save)
|
||||
clickOn(CommonStrings.action_save)
|
||||
eventsRecorder.assertSingle(AddRoomToSpaceEvent.Save)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking room in suggestions emits ToggleRoom event`() {
|
||||
fun `clicking room in suggestions emits ToggleRoom event`() = runAndroidComposeUiTest {
|
||||
val suggestions = aSelectRoomInfoList()
|
||||
val eventsRecorder = EventsRecorder<AddRoomToSpaceEvent>()
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
suggestions = suggestions,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(suggestions.first().name!!).performClick()
|
||||
onNodeWithText(suggestions.first().name!!).performClick()
|
||||
eventsRecorder.assertSingle(AddRoomToSpaceEvent.ToggleRoom(suggestions.first()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onRoomsAdded called when saveAction is Success`() {
|
||||
fun `onRoomsAdded called when saveAction is Success`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce {
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
saveAction = AsyncAction.Success(Unit),
|
||||
),
|
||||
|
|
@ -103,10 +102,10 @@ class AddRoomToSpaceViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `displaying search results sends UpdateSearchVisibleRange event`() {
|
||||
fun `displaying search results sends UpdateSearchVisibleRange event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AddRoomToSpaceEvent>()
|
||||
val rooms = aSelectRoomInfoList()
|
||||
rule.setAddRoomToSpaceView(
|
||||
setAddRoomToSpaceView(
|
||||
anAddRoomToSpaceState(
|
||||
isSearchActive = true,
|
||||
searchResults = SearchBarResultState.Results(rooms),
|
||||
|
|
@ -117,7 +116,7 @@ class AddRoomToSpaceViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setAddRoomToSpaceView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAddRoomToSpaceView(
|
||||
state: AddRoomToSpaceState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onRoomsAdded: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.space.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||
|
|
@ -33,37 +36,33 @@ import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
|||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
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 SpaceViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onBackClick = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a room name invokes the expected callback`() {
|
||||
fun `clicking on a room name invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, displayName = A_ROOM_NAME)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam(aSpaceRoom) {
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -71,91 +70,91 @@ class SpaceViewTest {
|
|||
),
|
||||
onRoomClick = it,
|
||||
)
|
||||
rule.onNodeWithText(A_ROOM_NAME).performClick()
|
||||
onNodeWithText(A_ROOM_NAME).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Join room emits the expected Event`() {
|
||||
fun `clicking on Join room emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, state = null)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom),
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_join)
|
||||
clickOn(CommonStrings.action_join)
|
||||
eventsRecorder.assertSingle(SpaceEvents.Join(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on accept invite emits the expected Event`() {
|
||||
fun `clicking on accept invite emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, state = CurrentUserMembership.INVITED)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
children = listOf(aSpaceRoom),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_accept)
|
||||
clickOn(CommonStrings.action_accept)
|
||||
eventsRecorder.assertSingle(SpaceEvents.AcceptInvite(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on decline invite emits the expected Event`() {
|
||||
fun `clicking on decline invite emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, state = CurrentUserMembership.INVITED)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
children = listOf(aSpaceRoom),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_decline)
|
||||
clickOn(CommonStrings.action_decline)
|
||||
eventsRecorder.assertSingle(SpaceEvents.DeclineInvite(aSpaceRoom))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on topic emits the expected Event`() {
|
||||
fun `clicking on topic emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
spaceInfo = aRoomInfo(topic = A_ROOM_TOPIC),
|
||||
hasMoreToLoad = false,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.onNodeWithText(A_ROOM_TOPIC).performClick()
|
||||
onNodeWithText(A_ROOM_TOPIC).performClick()
|
||||
eventsRecorder.assertSingle(SpaceEvents.ShowTopicViewer(A_ROOM_TOPIC))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking back in manage mode emits ExitManageMode event`() {
|
||||
fun `clicking back in manage mode emits ExitManageMode event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
hasMoreToLoad = false,
|
||||
isManageMode = true,
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(SpaceEvents.ExitManageMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on room in manage mode emits ToggleRoomSelection event`() {
|
||||
fun `clicking on room in manage mode emits ToggleRoomSelection event`() = runAndroidComposeUiTest {
|
||||
val aSpaceRoom = aSpaceRoom(roomId = A_ROOM_ID, displayName = A_ROOM_NAME)
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -163,14 +162,14 @@ class SpaceViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.onNodeWithText(A_ROOM_NAME).performClick()
|
||||
onNodeWithText(A_ROOM_NAME).performClick()
|
||||
eventsRecorder.assertSingle(SpaceEvents.ToggleRoomSelection(A_ROOM_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking remove button emits RemoveSelectedRooms event`() {
|
||||
fun `clicking remove button emits RemoveSelectedRooms event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom(roomId = A_ROOM_ID)),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -179,15 +178,15 @@ class SpaceViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_remove)
|
||||
clickOn(CommonStrings.action_remove)
|
||||
eventsRecorder.assertSingle(SpaceEvents.RemoveSelectedRooms)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking confirm in removal dialog emits ConfirmRoomRemoval event`() {
|
||||
fun `clicking confirm in removal dialog emits ConfirmRoomRemoval event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<SpaceEvents>()
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = listOf(aSpaceRoom(roomId = A_ROOM_ID)),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -198,14 +197,14 @@ class SpaceViewTest {
|
|||
)
|
||||
)
|
||||
// Click on the Remove button in the confirmation dialog
|
||||
rule.clickOn(CommonStrings.action_remove, inDialog = true)
|
||||
clickOn(CommonStrings.action_remove, inDialog = true)
|
||||
eventsRecorder.assertSingle(SpaceEvents.ConfirmRoomRemoval)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking create room button calls the expected callback`() {
|
||||
fun `clicking create room button calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val onCreateRoomClick = lambdaRecorder<Unit> { }
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = emptyList(),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -214,14 +213,14 @@ class SpaceViewTest {
|
|||
),
|
||||
onCreateRoomClick = onCreateRoomClick,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_create_room)
|
||||
clickOn(CommonStrings.action_create_room)
|
||||
onCreateRoomClick.assertions().isCalledOnce()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking add existing room button calls the expected callback`() {
|
||||
fun `clicking add existing room button calls the expected callback`() = runAndroidComposeUiTest {
|
||||
val onAddRoomClick = lambdaRecorder<Unit> { }
|
||||
rule.setSpaceView(
|
||||
setSpaceView(
|
||||
aSpaceState(
|
||||
children = emptyList(),
|
||||
hasMoreToLoad = false,
|
||||
|
|
@ -230,12 +229,12 @@ class SpaceViewTest {
|
|||
),
|
||||
onAddRoomClick = onAddRoomClick,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_add_existing_rooms)
|
||||
clickOn(CommonStrings.action_add_existing_rooms)
|
||||
onAddRoomClick.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSpaceView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setSpaceView(
|
||||
state: SpaceState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onRoomClick: (SpaceRoom) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,56 +6,54 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.startchat.impl.joinbyaddress
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.startchat.impl.R
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class JoinBaseRoomByAddressViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `entering text emits the expected event`() {
|
||||
fun `entering text emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomByAddressEvent>()
|
||||
rule.setJoinRoomByAddressView(
|
||||
setJoinRoomByAddressView(
|
||||
aJoinRoomByAddressState(
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
val text = rule.activity.getString(R.string.screen_start_chat_join_room_by_address_action)
|
||||
rule.onNodeWithText(text).performTextInput("#address:matrix.org")
|
||||
val text = activity!!.getString(R.string.screen_start_chat_join_room_by_address_action)
|
||||
onNodeWithText(text).performTextInput("#address:matrix.org")
|
||||
eventsRecorder.assertSingle(JoinRoomByAddressEvent.UpdateAddress("#address:matrix.org"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on continue emits the expected event`() {
|
||||
fun `clicking on continue emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<JoinRoomByAddressEvent>()
|
||||
rule.setJoinRoomByAddressView(
|
||||
setJoinRoomByAddressView(
|
||||
aJoinRoomByAddressState(
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
eventsRecorder.assertSingle(JoinRoomByAddressEvent.Continue)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setJoinRoomByAddressView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setJoinRoomByAddressView(
|
||||
state: JoinRoomByAddressState,
|
||||
) {
|
||||
setSafeContent {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.startchat.impl.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.startchat.impl.R
|
||||
import io.element.android.features.startchat.impl.userlist.aRecentDirectRoomList
|
||||
|
|
@ -27,70 +30,65 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 StartChatViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes the expected callback`() {
|
||||
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onCloseClick = it
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on New room invokes the expected callback`() {
|
||||
fun `clicking on New room invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onNewRoomClick = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_create_room_action_create_room)
|
||||
clickOn(R.string.screen_create_room_action_create_room)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Invite people invokes the expected callback`() {
|
||||
fun `clicking on Invite people invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
applicationName = "test",
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onInviteFriendsClick = it
|
||||
)
|
||||
val text = rule.activity.getString(CommonStrings.action_invite_friends_to_app, "test")
|
||||
rule.onNodeWithText(text).performClick()
|
||||
val text = activity!!.getString(CommonStrings.action_invite_friends_to_app, "test")
|
||||
onNodeWithText(text).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on a user suggestion invokes the expected callback`() {
|
||||
fun `clicking on a user suggestion invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val recentDirectRoomList = aRecentDirectRoomList()
|
||||
val firstRoom = recentDirectRoomList[0]
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnceWithParam(firstRoom.roomId) {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
userListState = aUserListState(
|
||||
recentDirectRooms = recentDirectRoomList
|
||||
|
|
@ -99,42 +97,42 @@ class StartChatViewTest {
|
|||
),
|
||||
onOpenDM = it
|
||||
)
|
||||
rule.onNodeWithText(firstRoom.matrixUser.getBestName()).performClick()
|
||||
onNodeWithText(firstRoom.matrixUser.getBestName()).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Join room by address invokes the expected callback`() {
|
||||
fun `clicking on Join room by address invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
onJoinRoomByAddressClick = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_start_chat_join_room_by_address_action)
|
||||
clickOn(R.string.screen_start_chat_join_room_by_address_action)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on room directory invokes the expected callback`() {
|
||||
fun `clicking on room directory invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<StartChatEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setStartChatView(
|
||||
setStartChatView(
|
||||
aCreateRoomRootState(
|
||||
eventSink = eventsRecorder,
|
||||
isRoomDirectorySearchEnabled = true
|
||||
),
|
||||
onRoomDirectorySearchClick = it
|
||||
)
|
||||
rule.clickOn(R.string.screen_room_directory_search_title)
|
||||
clickOn(R.string.screen_room_directory_search_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setStartChatView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setStartChatView(
|
||||
state: StartChatState,
|
||||
onCloseClick: () -> Unit = EnsureNeverCalled(),
|
||||
onNewRoomClick: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.userprofile
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.hasTestTag
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.userprofile.api.UserProfileEvents
|
||||
import io.element.android.features.userprofile.api.UserProfileState
|
||||
|
|
@ -39,193 +42,188 @@ import io.element.android.tests.testutils.ensureCalledOnce
|
|||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithTwoParams
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import kotlinx.coroutines.test.runTest
|
||||
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 UserProfileViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `on back button click - the expected callback is called`() = runTest {
|
||||
fun `on back button click - the expected callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
goBack = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on avatar clicked - the expected callback is called`() = runTest {
|
||||
fun `on avatar clicked - the expected callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithTwoParams(A_USER_NAME, AN_AVATAR_URL) { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(userName = A_USER_NAME, avatarUrl = AN_AVATAR_URL),
|
||||
openAvatarPreview = callback,
|
||||
)
|
||||
rule.onNode(hasTestTag(TestTags.memberDetailAvatar.value)).performClick()
|
||||
onNode(hasTestTag(TestTags.memberDetailAvatar.value)).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on avatar clicked with no avatar - nothing happens`() = runTest {
|
||||
fun `on avatar clicked with no avatar - nothing happens`() = runAndroidComposeUiTest {
|
||||
val callback = EnsureNeverCalledWithTwoParams<String, String>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(userName = A_USER_NAME, avatarUrl = null),
|
||||
openAvatarPreview = callback,
|
||||
)
|
||||
rule.onNode(hasTestTag(TestTags.memberDetailAvatar.value)).performClick()
|
||||
onNode(hasTestTag(TestTags.memberDetailAvatar.value)).performClick()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on Share clicked - the expected callback is called`() = runTest {
|
||||
fun `on Share clicked - the expected callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
onShareUser = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_share)
|
||||
clickOn(CommonStrings.action_share)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on Message clicked - the StartDm event is emitted`() = runTest {
|
||||
fun `on Message clicked - the StartDm event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
dmRoomId = A_ROOM_ID,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_message)
|
||||
clickOn(CommonStrings.action_message)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.StartDM)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on Call clicked - the expected callback is called`() = runTest {
|
||||
fun `on Call clicked - the expected callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithTwoParams(A_ROOM_ID, CallIntent.AUDIO) { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
dmRoomId = A_ROOM_ID,
|
||||
canCall = true,
|
||||
),
|
||||
onStartCall = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_call)
|
||||
clickOn(CommonStrings.action_call)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on Video Call clicked - the expected callback is called`() = runTest {
|
||||
fun `on Video Call clicked - the expected callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithTwoParams(A_ROOM_ID, CallIntent.VIDEO) { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
dmRoomId = A_ROOM_ID,
|
||||
canCall = true,
|
||||
),
|
||||
onStartCall = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_video)
|
||||
clickOn(CommonStrings.common_video)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `on Block user clicked - a BlockUser event is emitted with needsConfirmation`() = runTest {
|
||||
fun `on Block user clicked - a BlockUser event is emitted with needsConfirmation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_dm_details_block_user)
|
||||
clickOn(R.string.screen_dm_details_block_user)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.BlockUser(needsConfirmation = true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on confirming block user - a BlockUser event is emitted without needsConfirmation`() = runTest {
|
||||
fun `on confirming block user - a BlockUser event is emitted without needsConfirmation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Block,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_dm_details_block_alert_action)
|
||||
clickOn(R.string.screen_dm_details_block_alert_action)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.BlockUser(needsConfirmation = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on canceling blocking a user - a ClearConfirmationDialog event is emitted`() = runTest {
|
||||
fun `on canceling blocking a user - a ClearConfirmationDialog event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Block,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.ClearConfirmationDialog)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `on Unblock user clicked - an UnblockUser event is emitted with needsConfirmation`() = runTest {
|
||||
fun `on Unblock user clicked - an UnblockUser event is emitted with needsConfirmation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
isBlocked = AsyncData.Success(true),
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_dm_details_unblock_user)
|
||||
clickOn(R.string.screen_dm_details_unblock_user)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.UnblockUser(needsConfirmation = true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on confirming Unblock user - an UnblockUser event is emitted without needsConfirmation`() = runTest {
|
||||
fun `on confirming Unblock user - an UnblockUser event is emitted without needsConfirmation`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
isBlocked = AsyncData.Success(true),
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Unblock,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_dm_details_unblock_alert_action)
|
||||
clickOn(R.string.screen_dm_details_unblock_alert_action)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.UnblockUser(needsConfirmation = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on canceling unblocking a user - a ClearConfirmationDialog event is emitted`() = runTest {
|
||||
fun `on canceling unblocking a user - a ClearConfirmationDialog event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(
|
||||
isBlocked = AsyncData.Success(true),
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Unblock,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.ClearConfirmationDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on verify user clicked - the right callback is called`() = runTest {
|
||||
fun `on verify user clicked - the right callback is called`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnceWithParam(A_USER_ID) { callback ->
|
||||
rule.setUserProfileView(
|
||||
setUserProfileView(
|
||||
state = aUserProfileState(userId = A_USER_ID, verificationState = UserProfileVerificationState.UNVERIFIED),
|
||||
onVerifyClick = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.common_verify_user)
|
||||
clickOn(CommonStrings.common_verify_user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setUserProfileView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setUserProfileView(
|
||||
state: UserProfileState = aUserProfileState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.userprofile.shared.blockuser
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.userprofile.api.UserProfileEvents
|
||||
import io.element.android.features.userprofile.api.UserProfileState
|
||||
|
|
@ -18,18 +20,15 @@ import io.element.android.features.userprofile.shared.aUserProfileState
|
|||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class BlockUserDialogsTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `confirm block user emit expected Event`() {
|
||||
fun `confirm block user emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
BlockUserDialogs(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Block,
|
||||
|
|
@ -37,14 +36,14 @@ class BlockUserDialogsTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
rule.clickOn(R.string.screen_dm_details_block_alert_action)
|
||||
clickOn(R.string.screen_dm_details_block_alert_action)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.BlockUser(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cancel block user emit expected Event`() {
|
||||
fun `cancel block user emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
BlockUserDialogs(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Block,
|
||||
|
|
@ -52,14 +51,14 @@ class BlockUserDialogsTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.ClearConfirmationDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `confirm unblock user emit expected Event`() {
|
||||
fun `confirm unblock user emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
BlockUserDialogs(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Unblock,
|
||||
|
|
@ -67,14 +66,14 @@ class BlockUserDialogsTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
rule.clickOn(R.string.screen_dm_details_unblock_alert_action)
|
||||
clickOn(R.string.screen_dm_details_unblock_alert_action)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.UnblockUser(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cancel unblock user emit expected Event`() {
|
||||
fun `cancel unblock user emit expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<UserProfileEvents>()
|
||||
rule.setContent {
|
||||
setContent {
|
||||
BlockUserDialogs(
|
||||
state = aUserProfileState(
|
||||
displayConfirmationDialog = UserProfileState.ConfirmationDialog.Unblock,
|
||||
|
|
@ -82,7 +81,7 @@ class BlockUserDialogsTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(UserProfileEvents.ClearConfirmationDialog)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.verifysession.impl.incoming
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.verifysession.impl.R
|
||||
import io.element.android.features.verifysession.impl.ui.aEmojisSessionVerificationData
|
||||
|
|
@ -18,59 +21,55 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IncomingVerificationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
// region step Initial
|
||||
@Test
|
||||
fun `back key pressed - ignore the verification`() {
|
||||
fun `back key pressed - ignore the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = aStepInitial(),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ignore incoming verification emits the expected event`() {
|
||||
fun `ignore incoming verification emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = aStepInitial(),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_ignore)
|
||||
clickOn(CommonStrings.action_ignore)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.IgnoreVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `start incoming verification emits the expected event`() {
|
||||
fun `start incoming verification emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = aStepInitial(),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_start_verification)
|
||||
clickOn(CommonStrings.action_start_verification)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.StartVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when awaiting response cancels the verification`() {
|
||||
fun `back key pressed - when awaiting response cancels the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = aStepInitial(
|
||||
isWaiting = true,
|
||||
|
|
@ -78,16 +77,16 @@ class IncomingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
// endregion step Initial
|
||||
|
||||
// region step Verifying
|
||||
@Test
|
||||
fun `back key pressed - when ready to verify cancels the verification`() {
|
||||
fun `back key pressed - when ready to verify cancels the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -96,14 +95,14 @@ class IncomingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when verifying and loading emits the expected event`() {
|
||||
fun `back key pressed - when verifying and loading emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -112,14 +111,14 @@ class IncomingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on they do not match emits the expected event`() {
|
||||
fun `clicking on they do not match emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -128,14 +127,14 @@ class IncomingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_dont_match)
|
||||
clickOn(R.string.screen_session_verification_they_dont_match)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on they match emits the expected event`() {
|
||||
fun `clicking on they match emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -144,35 +143,35 @@ class IncomingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_match)
|
||||
clickOn(R.string.screen_session_verification_they_match)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.ConfirmVerification)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region step Failure
|
||||
@Test
|
||||
fun `back key pressed - when failure resets the flow`() {
|
||||
fun `back key pressed - when failure resets the flow`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Failure,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `click on done - when failure resets the flow`() {
|
||||
fun `click on done - when failure resets the flow`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Failure,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_done)
|
||||
clickOn(CommonStrings.action_done)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
|
|
@ -180,33 +179,33 @@ class IncomingVerificationViewTest {
|
|||
|
||||
// region step Completed
|
||||
@Test
|
||||
fun `back key pressed - on Completed step emits the expected event`() {
|
||||
fun `back key pressed - on Completed step emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Completed,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow is completed and the user clicks on the done button, the expected event is emitted`() {
|
||||
fun `when flow is completed and the user clicks on the done button, the expected event is emitted`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<IncomingVerificationViewEvents>()
|
||||
rule.setIncomingVerificationView(
|
||||
setIncomingVerificationView(
|
||||
anIncomingVerificationState(
|
||||
step = IncomingVerificationState.Step.Completed,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_done)
|
||||
clickOn(CommonStrings.action_done)
|
||||
eventsRecorder.assertSingle(IncomingVerificationViewEvents.GoBack)
|
||||
}
|
||||
// endregion
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setIncomingVerificationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setIncomingVerificationView(
|
||||
state: IncomingVerificationState,
|
||||
) {
|
||||
setContent {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.verifysession.impl.R
|
||||
import io.element.android.features.verifysession.impl.ui.aEmojisSessionVerificationData
|
||||
|
|
@ -21,58 +24,54 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class OutgoingVerificationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when canceled resets the flow`() {
|
||||
fun `back key pressed - when canceled resets the flow`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Canceled,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Reset)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when awaiting response cancels the verification`() {
|
||||
fun `back key pressed - when awaiting response cancels the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.AwaitingOtherDeviceResponse,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when ready to verify cancels the verification`() {
|
||||
fun `back key pressed - when ready to verify cancels the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Ready,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when verifying and not loading declines the verification`() {
|
||||
fun `back key pressed - when verifying and not loading declines the verification`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -81,14 +80,14 @@ class OutgoingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when verifying and loading does nothing`() {
|
||||
fun `back key pressed - when verifying and loading does nothing`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -97,42 +96,42 @@ class OutgoingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - on Completed exits the flow`() {
|
||||
fun `back key pressed - on Completed exits the flow`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
onBack = callback,
|
||||
state = anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Completed,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow is completed and the user clicks on the continue button, the expected callback is invoked`() {
|
||||
fun `when flow is completed and the user clicks on the continue button, the expected callback is invoked`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Completed,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onFinished = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
clickOn(CommonStrings.action_continue)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on they match emits the expected event`() {
|
||||
fun `clicking on they match emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -141,14 +140,14 @@ class OutgoingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_match)
|
||||
clickOn(R.string.screen_session_verification_they_match)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on they do not match emits the expected event`() {
|
||||
fun `clicking on they do not match emits the expected event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
|
|
@ -157,11 +156,11 @@ class OutgoingVerificationViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_dont_match)
|
||||
clickOn(R.string.screen_session_verification_they_dont_match)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setOutgoingVerificationView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setOutgoingVerificationView(
|
||||
state: OutgoingVerificationState,
|
||||
onLearnMoreClick: () -> Unit = EnsureNeverCalled(),
|
||||
onFinished: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ camera = "1.6.0"
|
|||
work = "2.11.2"
|
||||
|
||||
# Compose
|
||||
compose_bom = "2026.03.01"
|
||||
compose_bom = "2026.04.01"
|
||||
|
||||
# Coroutines
|
||||
coroutines = "1.10.2"
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.mediaviewer.impl.details
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -21,43 +24,38 @@ import io.element.android.tests.testutils.clickOn
|
|||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MediaDeleteConfirmationBottomSheetTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on Cancel invokes expected callback`() {
|
||||
fun `clicking on Cancel invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDeleteConfirmation()
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMediaDeleteConfirmationBottomSheet(
|
||||
setMediaDeleteConfirmationBottomSheet(
|
||||
state = state,
|
||||
onDismiss = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on Remove invokes expected callback`() {
|
||||
fun `clicking on Remove invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDeleteConfirmation()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDeleteConfirmationBottomSheet(
|
||||
setMediaDeleteConfirmationBottomSheet(
|
||||
state = state,
|
||||
onDelete = callback,
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_remove)).assertExists()
|
||||
rule.clickOn(CommonStrings.action_remove)
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_remove)).assertExists()
|
||||
clickOn(CommonStrings.action_remove)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMediaDeleteConfirmationBottomSheet(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setMediaDeleteConfirmationBottomSheet(
|
||||
state: MediaBottomSheetState.DeleteConfirmation,
|
||||
onDelete: (EventId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onDismiss: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.mediaviewer.impl.details
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
|
@ -20,97 +23,92 @@ import io.element.android.tests.testutils.EnsureNeverCalledWithParam
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
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 MediaDetailsBottomSheetTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on View in timeline invokes expected callback`() {
|
||||
fun `clicking on View in timeline invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
onViewInTimeline = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_view_in_timeline)
|
||||
clickOn(CommonStrings.action_view_in_timeline)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on Share invokes expected callback`() {
|
||||
fun `clicking on Share invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
onShare = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_share)
|
||||
clickOn(CommonStrings.action_share)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on Forward invokes expected callback`() {
|
||||
fun `clicking on Forward invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
onForward = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_forward)
|
||||
clickOn(CommonStrings.action_forward)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `clicking on Download invokes expected callback`() {
|
||||
fun `clicking on Download invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
onDownload = callback,
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_download)
|
||||
clickOn(CommonStrings.action_download)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on Delete invokes expected callback`() {
|
||||
fun `clicking on Delete invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails()
|
||||
ensureCalledOnceWithParam(state.eventId) { callback ->
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
onDelete = callback,
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_delete)).assertExists()
|
||||
rule.clickOn(CommonStrings.action_delete)
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_delete)).assertExists()
|
||||
clickOn(CommonStrings.action_delete)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `Remove is not present if canDelete is false`() {
|
||||
fun `Remove is not present if canDelete is false`() = runAndroidComposeUiTest {
|
||||
val state = aMediaBottomSheetStateDetails(
|
||||
canDelete = false,
|
||||
)
|
||||
rule.setMediaDetailsBottomSheet(
|
||||
setMediaDetailsBottomSheet(
|
||||
state = state,
|
||||
)
|
||||
rule.onNodeWithText(rule.activity.getString(CommonStrings.action_remove)).assertDoesNotExist()
|
||||
onNodeWithText(activity!!.getString(CommonStrings.action_remove)).assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMediaDetailsBottomSheet(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setMediaDetailsBottomSheet(
|
||||
state: MediaBottomSheetState.Details,
|
||||
onViewInTimeline: (EventId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onShare: (EventId) -> Unit = EnsureNeverCalledWithParam(),
|
||||
|
|
|
|||
|
|
@ -6,18 +6,21 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.mediaviewer.impl.viewer
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertHasClickAction
|
||||
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.compose.ui.test.performTouchInput
|
||||
import androidx.compose.ui.test.swipeDown
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.mediaviewer.impl.details.aMediaBottomSheetStateDetails
|
||||
|
|
@ -30,30 +33,26 @@ import io.element.android.tests.testutils.ensureCalledOnce
|
|||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.setSafeContent
|
||||
import io.mockk.mockk
|
||||
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 MediaViewerViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
private val mockMediaUrl: Uri = mockk("localMediaUri")
|
||||
|
||||
@Test
|
||||
fun `clicking on back invokes expected callback`() {
|
||||
fun `clicking on back invokes expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
val state = aMediaViewerState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
state = state,
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
|
|
@ -103,16 +102,16 @@ class MediaViewerViewTest {
|
|||
data: MediaViewerPageData.MediaViewerData,
|
||||
@StringRes contentDescriptionRes: Int,
|
||||
expectedEvent: MediaViewerEvent,
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
aMediaViewerState(
|
||||
listData = listOf(data),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
val contentDescription = rule.activity.getString(contentDescriptionRes)
|
||||
rule.onNodeWithContentDescription(contentDescription).performClick()
|
||||
val contentDescription = activity!!.getString(contentDescriptionRes)
|
||||
onNodeWithContentDescription(contentDescription).performClick()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
MediaViewerEvent.OnNavigateTo(0),
|
||||
|
|
@ -159,16 +158,16 @@ class MediaViewerViewTest {
|
|||
data: MediaViewerPageData.MediaViewerData,
|
||||
@StringRes textRes: Int,
|
||||
expectedEvent: MediaViewerEvent,
|
||||
) {
|
||||
) = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
aMediaViewerState(
|
||||
listData = listOf(data),
|
||||
mediaBottomSheetState = aMediaBottomSheetStateDetails(),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(textRes)
|
||||
clickOn(textRes)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
MediaViewerEvent.OnNavigateTo(0),
|
||||
|
|
@ -179,24 +178,25 @@ class MediaViewerViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on image hides the overlay`() {
|
||||
fun `clicking on image hides the overlay`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
val state = aMediaViewerState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
state = state,
|
||||
)
|
||||
// Ensure that the action are visible
|
||||
val contentDescription = rule.activity.getString(CommonStrings.action_share)
|
||||
rule.onNodeWithContentDescription(contentDescription)
|
||||
val resources = activity!!.resources
|
||||
val contentDescription = resources.getString(CommonStrings.action_share)
|
||||
onNodeWithContentDescription(contentDescription)
|
||||
.assertExists()
|
||||
.assertHasClickAction()
|
||||
val imageContentDescription = rule.activity.getString(CommonStrings.common_image)
|
||||
rule.onNodeWithContentDescription(imageContentDescription).performClick()
|
||||
val imageContentDescription = resources.getString(CommonStrings.common_image)
|
||||
onNodeWithContentDescription(imageContentDescription).performClick()
|
||||
// Give time for the animation (? since even by removing AnimatedVisibility it still fails)
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
rule.onNodeWithContentDescription(contentDescription)
|
||||
mainClock.advanceTimeBy(1_000)
|
||||
onNodeWithContentDescription(contentDescription)
|
||||
.assertDoesNotExist()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
|
|
@ -207,19 +207,19 @@ class MediaViewerViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `clicking swipe on the image invokes the expected callback`() {
|
||||
fun `clicking swipe on the image invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
val state = aMediaViewerState(
|
||||
eventSink = eventsRecorder
|
||||
)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
state = state,
|
||||
onBackClick = callback,
|
||||
)
|
||||
val imageContentDescription = rule.activity.getString(CommonStrings.common_image)
|
||||
rule.onNodeWithContentDescription(imageContentDescription).performTouchInput { swipeDown(startY = centerY) }
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
val imageContentDescription = activity!!.getString(CommonStrings.common_image)
|
||||
onNodeWithContentDescription(imageContentDescription).performTouchInput { swipeDown(startY = centerY) }
|
||||
mainClock.advanceTimeBy(1_000)
|
||||
}
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
|
|
@ -230,18 +230,18 @@ class MediaViewerViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `error case, click on retry emits the expected Event`() {
|
||||
fun `error case, click on retry emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
val data = aMediaViewerPageData(
|
||||
downloadedMedia = AsyncData.Failure(IllegalStateException("error")),
|
||||
)
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
aMediaViewerState(
|
||||
listData = listOf(data),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_retry)
|
||||
clickOn(CommonStrings.action_retry)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
MediaViewerEvent.OnNavigateTo(0),
|
||||
|
|
@ -252,18 +252,18 @@ class MediaViewerViewTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `error case, click on cancel emits the expected Event`() {
|
||||
fun `error case, click on cancel emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<MediaViewerEvent>()
|
||||
val data = aMediaViewerPageData(
|
||||
downloadedMedia = AsyncData.Failure(IllegalStateException("error")),
|
||||
)
|
||||
rule.setMediaViewerView(
|
||||
setMediaViewerView(
|
||||
aMediaViewerState(
|
||||
listData = listOf(data),
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
MediaViewerEvent.OnNavigateTo(0),
|
||||
|
|
@ -274,7 +274,7 @@ class MediaViewerViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMediaViewerView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setMediaViewerView(
|
||||
state: MediaViewerState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.textcomposer.impl.components.markdown
|
||||
|
||||
import android.widget.EditText
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.core.text.getSpans
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
|
|
@ -32,66 +35,54 @@ import io.element.android.libraries.textcomposer.model.SuggestionType
|
|||
import io.element.android.libraries.textcomposer.model.aMarkdownTextEditorState
|
||||
import io.element.android.tests.testutils.EnsureCalledOnceWithParam
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MarkdownTextInputTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `when user types onTyping is triggered with value 'true'`() = runTest {
|
||||
fun `when user types onTyping is triggered with value 'true'`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialFocus = true)
|
||||
val onTyping = EnsureCalledOnceWithParam(expectedParam = true, result = Unit)
|
||||
rule.setMarkdownTextInput(state = state, onTyping = onTyping)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
it.findEditor().setText("Test")
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state, onTyping = onTyping)
|
||||
activity!!.findEditor().setText("Test")
|
||||
awaitIdle()
|
||||
onTyping.assertSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user removes text onTyping is triggered with value 'false'`() = runTest {
|
||||
fun `when user removes text onTyping is triggered with value 'false'`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialFocus = true)
|
||||
val onTyping = EventsRecorder<Boolean>()
|
||||
rule.setMarkdownTextInput(state = state, onTyping = onTyping)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
val editText = it.findEditor()
|
||||
editText.setText("Test")
|
||||
editText.setText("")
|
||||
editText.setText(null)
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state, onTyping = onTyping)
|
||||
val editText = activity!!.findEditor()
|
||||
editText.setText("Test")
|
||||
editText.setText("")
|
||||
editText.setText(null)
|
||||
awaitIdle()
|
||||
onTyping.assertList(listOf(true, false, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user types something that's not a mention onSuggestionReceived is triggered with 'null'`() = runTest {
|
||||
fun `when user types something that's not a mention onSuggestionReceived is triggered with 'null'`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialFocus = true)
|
||||
val onSuggestionReceived = EventsRecorder<Suggestion?>()
|
||||
rule.setMarkdownTextInput(state = state, onSuggestionReceived = onSuggestionReceived)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
it.findEditor().setText("Test")
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state, onSuggestionReceived = onSuggestionReceived)
|
||||
activity!!.findEditor().setText("Test")
|
||||
awaitIdle()
|
||||
onSuggestionReceived.assertSingle(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when user types something that's a mention onSuggestionReceived is triggered a real value`() = runTest {
|
||||
fun `when user types something that's a mention onSuggestionReceived is triggered a real value`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialFocus = true)
|
||||
val onSuggestionReceived = EventsRecorder<Suggestion?>()
|
||||
rule.setMarkdownTextInput(state = state, onSuggestionReceived = onSuggestionReceived)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
it.findEditor().setText("@")
|
||||
it.findEditor().setText("#")
|
||||
it.findEditor().setText("/")
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state, onSuggestionReceived = onSuggestionReceived)
|
||||
val editor = activity!!.findEditor()
|
||||
editor.setText("@")
|
||||
editor.setText("#")
|
||||
editor.setText("/")
|
||||
awaitIdle()
|
||||
onSuggestionReceived.assertList(
|
||||
listOf(
|
||||
// User mention suggestion
|
||||
|
|
@ -105,69 +96,59 @@ class MarkdownTextInputTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when the selection changes in the UI the state is updated`() = runTest {
|
||||
fun `when the selection changes in the UI the state is updated`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialText = "Test", initialFocus = true)
|
||||
rule.setMarkdownTextInput(state = state)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
val editor = it.findEditor()
|
||||
editor.setSelection(2)
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state)
|
||||
val editor = activity!!.findEditor()
|
||||
editor.setSelection(2)
|
||||
awaitIdle()
|
||||
// Selection is updated
|
||||
assertThat(state.selection).isEqualTo(2..2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when the selection state changes in the view is updated`() = runTest {
|
||||
fun `when the selection state changes in the view is updated`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialText = "Test", initialFocus = true)
|
||||
rule.setMarkdownTextInput(state = state)
|
||||
var editor: EditText? = null
|
||||
rule.activityRule.scenario.onActivity {
|
||||
editor = it.findEditor()
|
||||
state.selection = 2..2
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state)
|
||||
val editor = activity!!.findEditor()
|
||||
state.selection = 2..2
|
||||
awaitIdle()
|
||||
// Selection state is updated
|
||||
assertThat(editor?.selectionStart).isEqualTo(2)
|
||||
assertThat(editor?.selectionEnd).isEqualTo(2)
|
||||
assertThat(editor.selectionStart).isEqualTo(2)
|
||||
assertThat(editor.selectionEnd).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when the view focus changes the state is updated`() = runTest {
|
||||
fun `when the view focus changes the state is updated`() = runAndroidComposeUiTest {
|
||||
val state = aMarkdownTextEditorState(initialText = "Test", initialFocus = false)
|
||||
rule.setMarkdownTextInput(state = state)
|
||||
rule.activityRule.scenario.onActivity {
|
||||
val editor = it.findEditor()
|
||||
editor.requestFocus()
|
||||
}
|
||||
setMarkdownTextInput(state = state)
|
||||
val editor = activity!!.findEditor()
|
||||
editor.requestFocus()
|
||||
// Focus state is updated
|
||||
assertThat(state.hasFocus).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `inserting a mention replaces the existing text with a span`() = runTest {
|
||||
fun `inserting a mention replaces the existing text with a span`() = runAndroidComposeUiTest {
|
||||
val permalinkParser = FakePermalinkParser(result = { PermalinkData.UserLink(A_SESSION_ID) })
|
||||
val state = aMarkdownTextEditorState(initialText = "@", initialFocus = true)
|
||||
state.currentSuggestion = Suggestion(0, 1, SuggestionType.Mention, "")
|
||||
rule.setMarkdownTextInput(state = state)
|
||||
var editor: EditText? = null
|
||||
rule.activityRule.scenario.onActivity {
|
||||
editor = it.findEditor()
|
||||
state.insertSuggestion(
|
||||
ResolvedSuggestion.Member(roomMember = aRoomMember()),
|
||||
aMentionSpanProvider(permalinkParser),
|
||||
)
|
||||
}
|
||||
rule.awaitIdle()
|
||||
setMarkdownTextInput(state = state)
|
||||
val editor = activity!!.findEditor()
|
||||
state.insertSuggestion(
|
||||
ResolvedSuggestion.Member(roomMember = aRoomMember()),
|
||||
aMentionSpanProvider(permalinkParser),
|
||||
)
|
||||
awaitIdle()
|
||||
|
||||
// Text is replaced with a placeholder
|
||||
assertThat(editor?.editableText.toString()).isEqualTo("@ ")
|
||||
assertThat(editor.editableText.toString()).isEqualTo("@ ")
|
||||
// The placeholder contains a MentionSpan
|
||||
val mentionSpans = editor?.editableText?.getSpans<MentionSpan>(0, 2).orEmpty()
|
||||
val mentionSpans = editor.editableText?.getSpans<MentionSpan>(0, 2).orEmpty()
|
||||
assertThat(mentionSpans).isNotEmpty()
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMarkdownTextInput(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setMarkdownTextInput(
|
||||
state: MarkdownTextEditorState = aMarkdownTextEditorState(),
|
||||
onTyping: (Boolean) -> Unit = {},
|
||||
onSuggestionReceived: (Suggestion?) -> Unit = {},
|
||||
|
|
|
|||
|
|
@ -6,60 +6,58 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.troubleshoot.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
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 TroubleshootNotificationsViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `press menu back invokes the expected callback`() {
|
||||
fun `press menu back invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TroubleshootNotificationsEvents>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
rule.setTroubleshootNotificationsView(
|
||||
setTroubleshootNotificationsView(
|
||||
state = aTroubleshootNotificationsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onBackClick = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on run test emits the expected Event`() {
|
||||
fun `clicking on run test emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TroubleshootNotificationsEvents>()
|
||||
rule.setTroubleshootNotificationsView(
|
||||
setTroubleshootNotificationsView(
|
||||
aTroubleshootNotificationsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Run tests").performClick()
|
||||
onNodeWithText("Run tests").performClick()
|
||||
eventsRecorder.assertSingle(TroubleshootNotificationsEvents.StartTests)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on run test again emits the expected Event`() {
|
||||
fun `clicking on run test again emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TroubleshootNotificationsEvents>()
|
||||
rule.setTroubleshootNotificationsView(
|
||||
setTroubleshootNotificationsView(
|
||||
aTroubleshootNotificationsState(
|
||||
tests = listOf(
|
||||
aTroubleshootTestStateFailure(
|
||||
|
|
@ -69,7 +67,7 @@ class TroubleshootNotificationsViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Run tests again").performClick()
|
||||
onNodeWithText("Run tests again").performClick()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
TroubleshootNotificationsEvents.RetryFailedTests,
|
||||
|
|
@ -80,9 +78,9 @@ class TroubleshootNotificationsViewTest {
|
|||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on quick fix emits the expected Event`() {
|
||||
fun `clicking on quick fix emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<TroubleshootNotificationsEvents>()
|
||||
rule.setTroubleshootNotificationsView(
|
||||
setTroubleshootNotificationsView(
|
||||
aTroubleshootNotificationsState(
|
||||
tests = listOf(
|
||||
aTroubleshootTestStateFailure(
|
||||
|
|
@ -92,7 +90,7 @@ class TroubleshootNotificationsViewTest {
|
|||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText("Attempt to fix").performClick()
|
||||
onNodeWithText("Attempt to fix").performClick()
|
||||
eventsRecorder.assertList(
|
||||
listOf(
|
||||
TroubleshootNotificationsEvents.RetryFailedTests,
|
||||
|
|
@ -102,7 +100,7 @@ class TroubleshootNotificationsViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setTroubleshootNotificationsView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setTroubleshootNotificationsView(
|
||||
state: TroubleshootNotificationsState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.libraries.troubleshoot.impl.history
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.A_FORMATTED_DATE
|
||||
|
|
@ -23,67 +26,62 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PushHistoryViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `clicking on Reset sends a PushHistoryEvents`() {
|
||||
fun `clicking on Reset sends a PushHistoryEvents`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PushHistoryEvents>()
|
||||
rule.setPushHistoryView(
|
||||
setPushHistoryView(
|
||||
aPushHistoryState(
|
||||
pushCounter = 123,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val menuContentDescription = rule.activity.getString(CommonStrings.a11y_user_menu)
|
||||
rule.onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
rule.clickOn(CommonStrings.action_reset)
|
||||
val menuContentDescription = activity!!.getString(CommonStrings.a11y_user_menu)
|
||||
onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
clickOn(CommonStrings.action_reset)
|
||||
eventsRecorder.assertSingle(PushHistoryEvents.Reset(requiresConfirmation = true))
|
||||
// Also check that the push counter is rendered
|
||||
rule.onNodeWithText("123").assertExists()
|
||||
onNodeWithText("123").assertExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on show only errors sends a PushHistoryEvents(true)`() {
|
||||
fun `clicking on show only errors sends a PushHistoryEvents(true)`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PushHistoryEvents>()
|
||||
rule.setPushHistoryView(
|
||||
setPushHistoryView(
|
||||
aPushHistoryState(
|
||||
showOnlyErrors = false,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val menuContentDescription = rule.activity.getString(CommonStrings.a11y_user_menu)
|
||||
rule.onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
rule.onNodeWithText("Show only errors").performClick()
|
||||
val menuContentDescription = activity!!.getString(CommonStrings.a11y_user_menu)
|
||||
onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
onNodeWithText("Show only errors").performClick()
|
||||
eventsRecorder.assertSingle(PushHistoryEvents.SetShowOnlyErrors(showOnlyErrors = true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on show only errors sends a PushHistoryEvents(false)`() {
|
||||
fun `clicking on show only errors sends a PushHistoryEvents(false)`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PushHistoryEvents>()
|
||||
rule.setPushHistoryView(
|
||||
setPushHistoryView(
|
||||
aPushHistoryState(
|
||||
showOnlyErrors = true,
|
||||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
val menuContentDescription = rule.activity.getString(CommonStrings.a11y_user_menu)
|
||||
rule.onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
rule.onNodeWithText("Show only errors").performClick()
|
||||
val menuContentDescription = activity!!.getString(CommonStrings.a11y_user_menu)
|
||||
onNodeWithContentDescription(menuContentDescription).performClick()
|
||||
onNodeWithText("Show only errors").performClick()
|
||||
eventsRecorder.assertSingle(PushHistoryEvents.SetShowOnlyErrors(showOnlyErrors = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on an invalid event has no effect`() {
|
||||
fun `clicking on an invalid event has no effect`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PushHistoryEvents>(expectEvents = false)
|
||||
rule.setPushHistoryView(
|
||||
setPushHistoryView(
|
||||
aPushHistoryState(
|
||||
pushHistoryItems = listOf(
|
||||
aPushHistoryItem(
|
||||
|
|
@ -93,14 +91,14 @@ class PushHistoryViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(A_FORMATTED_DATE).performClick()
|
||||
onNodeWithText(A_FORMATTED_DATE).performClick()
|
||||
// No callback invoked
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a valid event emits the expected Event`() {
|
||||
fun `clicking on a valid event emits the expected Event`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<PushHistoryEvents>()
|
||||
rule.setPushHistoryView(
|
||||
setPushHistoryView(
|
||||
aPushHistoryState(
|
||||
pushHistoryItems = listOf(
|
||||
aPushHistoryItem(
|
||||
|
|
@ -113,7 +111,7 @@ class PushHistoryViewTest {
|
|||
eventSink = eventsRecorder,
|
||||
),
|
||||
)
|
||||
rule.onNodeWithText(A_FORMATTED_DATE).performClick()
|
||||
onNodeWithText(A_FORMATTED_DATE).performClick()
|
||||
eventsRecorder.assertSingle(
|
||||
PushHistoryEvents.NavigateTo(
|
||||
sessionId = A_SESSION_ID,
|
||||
|
|
@ -124,7 +122,7 @@ class PushHistoryViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPushHistoryView(
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setPushHistoryView(
|
||||
state: PushHistoryState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,15 +6,17 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.tests.testutils
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import io.element.android.libraries.designsystem.utils.LocalUiTestMode
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.rules.TestRule
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
object RobolectricDispatcherCleaner {
|
||||
|
|
@ -52,7 +54,7 @@ object RobolectricDispatcherCleaner {
|
|||
}
|
||||
}
|
||||
|
||||
fun <R : TestRule, A : ComponentActivity> AndroidComposeTestRule<R, A>.setSafeContent(
|
||||
fun AndroidComposeUiTest<ComponentActivity>.setSafeContent(
|
||||
clearAndroidUiDispatcher: Boolean = false,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalTestApi::class)
|
||||
|
||||
package io.element.android.tests.testutils
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
|
|
@ -19,19 +23,17 @@ import androidx.compose.ui.test.hasContentDescription
|
|||
import androidx.compose.ui.test.hasTestTag
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import org.junit.rules.TestRule
|
||||
|
||||
val trueMatcher = SemanticsMatcher("true matcher") { true }
|
||||
|
||||
fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.clickOn(
|
||||
fun AndroidComposeUiTest<ComponentActivity>.clickOn(
|
||||
@StringRes res: Int,
|
||||
inDialog: Boolean = false,
|
||||
) {
|
||||
val text = activity.getString(res)
|
||||
val text = activity!!.getString(res)
|
||||
onNode(
|
||||
hasText(text) and hasClickAction() and if (inDialog) hasAnyAncestor(isDialog()) else trueMatcher
|
||||
)
|
||||
|
|
@ -41,28 +43,28 @@ fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.clickOn(
|
|||
/**
|
||||
* Press the back button in the app bar.
|
||||
*/
|
||||
fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.pressBack() {
|
||||
val text = activity.getString(CommonStrings.action_back)
|
||||
fun AndroidComposeUiTest<ComponentActivity>.pressBack() {
|
||||
val text = activity!!.getString(CommonStrings.action_back)
|
||||
onNode(hasContentDescription(text)).performClick()
|
||||
}
|
||||
|
||||
/**
|
||||
* Press the back key.
|
||||
*/
|
||||
fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.pressBackKey() {
|
||||
activity.onBackPressedDispatcher.onBackPressed()
|
||||
fun AndroidComposeUiTest<ComponentActivity>.pressBackKey() {
|
||||
activity!!.onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
||||
fun SemanticsNodeInteractionsProvider.pressTag(tag: String) {
|
||||
onNode(hasTestTag(tag)).performClick()
|
||||
}
|
||||
|
||||
fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.assertNoNodeWithText(@StringRes res: Int) {
|
||||
val text = activity.getString(res)
|
||||
fun AndroidComposeUiTest<ComponentActivity>.assertNoNodeWithText(@StringRes res: Int) {
|
||||
val text = activity!!.getString(res)
|
||||
onNodeWithText(text).assertDoesNotExist()
|
||||
}
|
||||
|
||||
fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.assertNodeWithTextIsDisplayed(@StringRes res: Int) {
|
||||
val text = activity.getString(res)
|
||||
fun AndroidComposeUiTest<ComponentActivity>.assertNodeWithTextIsDisplayed(@StringRes res: Int) {
|
||||
val text = activity!!.getString(res)
|
||||
onNodeWithText(text).assertIsDisplayed()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue