mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-06 00:02:48 +02:00
Compare commits
10 Commits
v1.6.46
...
feature/am
Author | SHA1 | Date | |
---|---|---|---|
|
7c0862282f | ||
|
7c198c68e5 | ||
|
64e84af378 | ||
|
f44f4e8d3d | ||
|
0933dd2c03 | ||
|
a5b0ba656d | ||
|
99e729334c | ||
|
b58f98a39c | ||
|
00a270bfbe | ||
|
4f66a2f470 |
@@ -17,15 +17,21 @@
|
||||
package im.vector.app
|
||||
|
||||
import android.view.View
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||
import dagger.hilt.EntryPoints
|
||||
import im.vector.app.core.di.SingletonEntryPoint
|
||||
import im.vector.app.features.MainActivity
|
||||
import im.vector.app.ui.robot.ElementRobot
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
@@ -39,7 +45,6 @@ class CantVerifyTest {
|
||||
@get:Rule
|
||||
val testRule = RuleChain
|
||||
.outerRule(ActivityScenarioRule(MainActivity::class.java))
|
||||
.around(ClearCurrentSessionRule())
|
||||
|
||||
private val elementRobot = ElementRobot()
|
||||
var userName: String = "loginTest_${UUID.randomUUID()}"
|
||||
@@ -76,4 +81,19 @@ class CantVerifyTest {
|
||||
Espresso.onView(ViewMatchers.withText(R.string.bottom_sheet_setup_secure_backup_title))
|
||||
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
runBlocking {
|
||||
reflectAnalyticDatastore(context).edit { it.clear() }
|
||||
runCatching {
|
||||
val entryPoint = EntryPoints.get(context.applicationContext, SingletonEntryPoint::class.java)
|
||||
val sessionHolder = entryPoint.activeSessionHolder()
|
||||
sessionHolder.getSafeActiveSession()?.signOutService()?.signOut(true)
|
||||
entryPoint.vectorPreferences().clearPreferences()
|
||||
sessionHolder.clearActiveSession()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ import kotlin.reflect.KClass
|
||||
* The VectorPreferences and AnalyticsDatastore are also cleared in an attempt to recreate a fresh base.
|
||||
*/
|
||||
class ClearCurrentSessionRule : TestWatcher() {
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
runBlocking {
|
||||
@@ -59,7 +60,7 @@ private fun KClass<*>.asTopLevel() = Class.forName("${qualifiedName}Kt")
|
||||
* via reflection to avoid exposing property to all callers.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun reflectAnalyticDatastore(context: Context): DataStore<Preferences> {
|
||||
fun reflectAnalyticDatastore(context: Context): DataStore<Preferences> {
|
||||
val klass = AnalyticsStore::class.asTopLevel()
|
||||
val method = klass.getMethod("access\$getDataStore", Context::class.java)
|
||||
return method.invoke(klass, context) as DataStore<Preferences>
|
||||
|
@@ -40,6 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import im.vector.app.core.utils.getMatrixInstance
|
||||
import im.vector.app.features.MainActivity
|
||||
import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
|
||||
import im.vector.app.features.crypto.recover.SetupMode
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
@@ -82,6 +83,12 @@ class SecurityBootstrapTest : VerificationTestBase() {
|
||||
|
||||
uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl)
|
||||
|
||||
withIdlingResource(activityIdlingResource(AnalyticsOptInActivity::class.java)) {
|
||||
onView(withId(R.id.submit))
|
||||
.check(matches(isDisplayed()))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
// Thread.sleep(6000)
|
||||
withIdlingResource(activityIdlingResource(HomeActivity::class.java)) {
|
||||
onView(withId(R.id.roomListContainer))
|
||||
|
@@ -17,7 +17,11 @@
|
||||
package im.vector.app
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dagger.hilt.EntryPoints
|
||||
import im.vector.app.core.di.SingletonEntryPoint
|
||||
import im.vector.app.ui.robot.OnboardingRobot
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -25,6 +29,7 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
@@ -114,7 +119,9 @@ abstract class VerificationTestBase {
|
||||
private fun syncSession(session: Session) {
|
||||
val lock = CountDownLatch(1)
|
||||
|
||||
GlobalScope.launch(Dispatchers.Main) { session.open() }
|
||||
runBlocking(Dispatchers.Main) {
|
||||
session.open()
|
||||
}
|
||||
|
||||
session.syncService().startSync(true)
|
||||
|
||||
@@ -133,4 +140,22 @@ abstract class VerificationTestBase {
|
||||
|
||||
lock.await(20_000, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the session after every test. It is necessary to reset otherwise further UI tests fails.
|
||||
*/
|
||||
@After
|
||||
fun tearDown() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
runBlocking {
|
||||
reflectAnalyticDatastore(context).edit { it.clear() }
|
||||
runCatching {
|
||||
val entryPoint = EntryPoints.get(context.applicationContext, SingletonEntryPoint::class.java)
|
||||
val sessionHolder = entryPoint.activeSessionHolder()
|
||||
sessionHolder.getSafeActiveSession()?.signOutService()?.signOut(true)
|
||||
entryPoint.vectorPreferences().clearPreferences()
|
||||
sessionHolder.clearActiveSession()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,12 +36,13 @@ import androidx.test.filters.LargeTest
|
||||
import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||
import im.vector.app.core.utils.getMatrixInstance
|
||||
import im.vector.app.features.MainActivity
|
||||
import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
@@ -59,20 +60,21 @@ import kotlin.random.Random
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
|
||||
var existingSession: Session? = null
|
||||
|
||||
@get:Rule
|
||||
val activityRule = ActivityScenarioRule(MainActivity::class.java)
|
||||
val testRule: RuleChain = RuleChain
|
||||
.outerRule(ActivityScenarioRule(MainActivity::class.java))
|
||||
.around(ClearCurrentSessionRule())
|
||||
|
||||
@Before
|
||||
fun createSessionWithCrossSigning() {
|
||||
val matrix = getMatrixInstance()
|
||||
val userName = "foobar_${Random.nextLong()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
doSync<Unit> {
|
||||
doSync {
|
||||
existingSession!!.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(
|
||||
object : UserInteractiveAuthInterceptor {
|
||||
@@ -96,6 +98,12 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
|
||||
uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl)
|
||||
|
||||
withIdlingResource(activityIdlingResource(AnalyticsOptInActivity::class.java)) {
|
||||
onView(withId(R.id.submit))
|
||||
.check(matches(isDisplayed()))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
// Thread.sleep(6000)
|
||||
withIdlingResource(activityIdlingResource(HomeActivity::class.java)) {
|
||||
onView(withId(R.id.roomListContainer))
|
||||
@@ -139,21 +147,29 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
onView(withId(R.id.bottomSheetFragmentContainer))
|
||||
.check(matches(not(hasDescendant(withText(R.string.verification_cannot_access_other_session)))))
|
||||
|
||||
val request = existingSession!!.cryptoService().verificationService().requestKeyVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
existingSession!!.myUserId,
|
||||
listOf(uiSession.sessionParams.deviceId!!)
|
||||
// The emulator at this point has sent requests to other sessions.
|
||||
// Find the incoming request from the existing session and start the verification process.
|
||||
val incomingRequest = existingSession!!.cryptoService().verificationService().getExistingVerificationRequests(existingSession!!.myUserId).first {
|
||||
it.requestInfo?.fromDevice == uiSession.sessionParams.deviceId
|
||||
}
|
||||
|
||||
existingSession!!.cryptoService().verificationService().readyPendingVerification(
|
||||
listOf(
|
||||
VerificationMethod.SAS,
|
||||
VerificationMethod.QR_CODE_SCAN,
|
||||
VerificationMethod.QR_CODE_SHOW
|
||||
), existingSession!!.myUserId, incomingRequest.transactionId!!
|
||||
)
|
||||
|
||||
val transactionId = request.transactionId!!
|
||||
val transactionId = incomingRequest.transactionId!!
|
||||
val sasReadyIdle = verificationStateIdleResource(transactionId, VerificationTxState.ShortCodeReady, uiSession)
|
||||
val otherSessionSasReadyIdle = verificationStateIdleResource(transactionId, VerificationTxState.ShortCodeReady, existingSession!!)
|
||||
|
||||
onView(isRoot()).perform(SleepViewAction.sleep(1000))
|
||||
onView(isRoot()).perform(SleepViewAction.sleep(5000))
|
||||
|
||||
// Assert QR code option is there and available
|
||||
onView(withId(R.id.bottomSheetVerificationRecyclerView))
|
||||
.check(matches(hasDescendant(withText(R.string.verification_scan_their_code))))
|
||||
.check(matches(hasDescendant(withText(R.string.verification_scan_with_this_device))))
|
||||
|
||||
onView(withId(R.id.bottomSheetVerificationRecyclerView))
|
||||
.check(matches(hasDescendant(withId(R.id.itemVerificationQrCodeImage))))
|
||||
@@ -173,7 +189,7 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
|
||||
IdlingRegistry.getInstance().register(sasReadyIdle)
|
||||
IdlingRegistry.getInstance().register(otherSessionSasReadyIdle)
|
||||
onView(isRoot()).perform(SleepViewAction.sleep(300))
|
||||
onView(isRoot()).perform(SleepViewAction.sleep(5000))
|
||||
// will only execute when Idle is ready
|
||||
val expectedEmojis = firstSessionTr.getEmojiCodeRepresentation()
|
||||
val targets = listOf(R.id.emoji0, R.id.emoji1, R.id.emoji2, R.id.emoji3, R.id.emoji4, R.id.emoji5, R.id.emoji6)
|
||||
@@ -241,7 +257,7 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
fun verificationStateIdleResource(transactionId: String, checkForState: VerificationTxState, session: Session): IdlingResource {
|
||||
private fun verificationStateIdleResource(transactionId: String, checkForState: VerificationTxState, session: Session): IdlingResource {
|
||||
val idle = object : IdlingResource, VerificationService.Listener {
|
||||
private var callback: IdlingResource.ResourceCallback? = null
|
||||
|
||||
|
@@ -37,6 +37,7 @@ import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.utils.getMatrixInstance
|
||||
import im.vector.app.features.MainActivity
|
||||
import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
|
||||
import im.vector.app.features.crypto.quads.SharedSecureStorageActivity
|
||||
import im.vector.app.features.crypto.recover.BootstrapCrossSigningTask
|
||||
import im.vector.app.features.crypto.recover.Params
|
||||
@@ -44,9 +45,9 @@ import im.vector.app.features.crypto.recover.SetupMode
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
@@ -59,14 +60,15 @@ import kotlin.random.Random
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class VerifySessionPassphraseTest : VerificationTestBase() {
|
||||
|
||||
var existingSession: Session? = null
|
||||
val passphrase = "person woman camera tv"
|
||||
|
||||
@get:Rule
|
||||
val activityRule = ActivityScenarioRule(MainActivity::class.java)
|
||||
val testRule: RuleChain = RuleChain
|
||||
.outerRule(ActivityScenarioRule(MainActivity::class.java))
|
||||
.around(ClearCurrentSessionRule())
|
||||
|
||||
@Before
|
||||
fun createSessionWithCrossSigningAnd4S() {
|
||||
@@ -74,7 +76,7 @@ class VerifySessionPassphraseTest : VerificationTestBase() {
|
||||
val matrix = getMatrixInstance()
|
||||
val userName = "foobar_${Random.nextLong()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
doSync<Unit> {
|
||||
doSync {
|
||||
existingSession!!.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(
|
||||
object : UserInteractiveAuthInterceptor {
|
||||
@@ -120,6 +122,12 @@ class VerifySessionPassphraseTest : VerificationTestBase() {
|
||||
|
||||
uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl)
|
||||
|
||||
withIdlingResource(activityIdlingResource(AnalyticsOptInActivity::class.java)) {
|
||||
onView(withId(R.id.submit))
|
||||
.check(matches(isDisplayed()))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
// Thread.sleep(6000)
|
||||
withIdlingResource(activityIdlingResource(HomeActivity::class.java)) {
|
||||
onView(withId(R.id.roomListContainer))
|
||||
|
Reference in New Issue
Block a user