Merge pull request #6748 from vector-im/feature/adm/flaky-verification-test

Fixing flaky `CantVerifyTest`
This commit is contained in:
Adam Brown 2022-08-08 08:46:29 +01:00 committed by GitHub
commit dd496dc1a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 1 deletions

View File

@ -598,4 +598,5 @@ dependencies {
androidTestImplementation libs.mockk.mockkAndroid androidTestImplementation libs.mockk.mockkAndroid
androidTestUtil libs.androidx.orchestrator androidTestUtil libs.androidx.orchestrator
debugImplementation libs.androidx.fragmentTesting debugImplementation libs.androidx.fragmentTesting
androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:1.7.10"
} }

View File

@ -27,6 +27,7 @@ import im.vector.app.features.MainActivity
import im.vector.app.ui.robot.ElementRobot import im.vector.app.ui.robot.ElementRobot
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith import org.junit.runner.RunWith
import java.util.UUID import java.util.UUID
@ -35,7 +36,9 @@ import java.util.UUID
class CantVerifyTest : VerificationTestBase() { class CantVerifyTest : VerificationTestBase() {
@get:Rule @get:Rule
val activityRule = ActivityScenarioRule(MainActivity::class.java) val testRule = RuleChain
.outerRule(ActivityScenarioRule(MainActivity::class.java))
.around(ClearCurrentSessionRule())
private val elementRobot = ElementRobot() private val elementRobot = ElementRobot()
var userName: String = "loginTest_${UUID.randomUUID()}" var userName: String = "loginTest_${UUID.randomUUID()}"

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.test.platform.app.InstrumentationRegistry
import im.vector.app.features.analytics.store.AnalyticsStore
import kotlinx.coroutines.runBlocking
import org.junit.rules.TestWatcher
import org.junit.runner.Description
import org.junit.runners.model.Statement
import kotlin.reflect.KClass
/**
* A TestRule to reset and clear the current Session.
* If a Session is active it will be signed out and cleared from the ActiveSessionHolder.
* 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 {
reflectAnalyticDatastore(context).edit { it.clear() }
runCatching {
val holder = (context.applicationContext as VectorApplication).activeSessionHolder
holder.getSafeActiveSession()?.signOutService()?.signOut(true)
(context.applicationContext as VectorApplication).vectorPreferences.clearPreferences()
holder.clearActiveSession()
}
}
return super.apply(base, description)
}
}
private fun KClass<*>.asTopLevel() = Class.forName("${qualifiedName}Kt")
/**
* Fetches the top level, private [Context.dataStore] extension property from [im.vector.app.features.analytics.store.AnalyticsStore]
* via reflection to avoid exposing property to all callers.
*/
@Suppress("UNCHECKED_CAST")
private 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>
}

View File

@ -29,6 +29,9 @@ import kotlinx.coroutines.flow.map
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
import javax.inject.Inject import javax.inject.Inject
/**
* Also accessed via reflection by the instrumentation tests @see [im.vector.app.ClearCurrentSessionRule].
*/
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_analytics") private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_analytics")
/** /**