Android tests: introduce TestBackgroundDetectionObserver so sync is not cancelled while testing + fix small warnings
This commit is contained in:
parent
67975e0c83
commit
69720ffdd3
@ -35,16 +35,16 @@ import org.matrix.android.sdk.internal.SessionManager
|
||||
import org.matrix.android.sdk.internal.network.ApiInterceptor
|
||||
import org.matrix.android.sdk.internal.network.UserAgentHolder
|
||||
import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver
|
||||
import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory
|
||||
import org.matrix.olm.OlmManager
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* This is the main entry point to the matrix sdk.
|
||||
* To get the singleton instance, use getInstance static method.
|
||||
* This mimics the Matrix class but using TestMatrixComponent internally instead of regular MatrixComponent.
|
||||
*/
|
||||
class Matrix private constructor(context: Context, matrixConfiguration: MatrixConfiguration) {
|
||||
class TestMatrix constructor(context: Context, matrixConfiguration: MatrixConfiguration) {
|
||||
|
||||
@Inject internal lateinit var legacySessionImporter: LegacySessionImporter
|
||||
@Inject internal lateinit var authenticationService: AuthenticationService
|
||||
@ -55,15 +55,18 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
|
||||
@Inject internal lateinit var sessionManager: SessionManager
|
||||
@Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService
|
||||
@Inject internal lateinit var apiInterceptor: ApiInterceptor
|
||||
@Inject internal lateinit var matrixWorkerFactory: MatrixWorkerFactory
|
||||
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
init {
|
||||
Monarchy.init(context)
|
||||
DaggerTestMatrixComponent.factory().create(context, matrixConfiguration).inject(this)
|
||||
if (context.applicationContext !is Configuration.Provider) {
|
||||
WorkManager.initialize(context, Configuration.Builder().setExecutor(Executors.newCachedThreadPool()).build())
|
||||
}
|
||||
val configuration = Configuration.Builder()
|
||||
.setExecutor(Executors.newCachedThreadPool())
|
||||
.setWorkerFactory(matrixWorkerFactory)
|
||||
.build()
|
||||
WorkManager.initialize(context, configuration)
|
||||
uiHandler.post {
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
|
||||
}
|
||||
@ -93,21 +96,21 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
|
||||
|
||||
companion object {
|
||||
|
||||
private lateinit var instance: Matrix
|
||||
private lateinit var instance: TestMatrix
|
||||
private val isInit = AtomicBoolean(false)
|
||||
|
||||
fun initialize(context: Context, matrixConfiguration: MatrixConfiguration) {
|
||||
if (isInit.compareAndSet(false, true)) {
|
||||
instance = Matrix(context.applicationContext, matrixConfiguration)
|
||||
instance = TestMatrix(context.applicationContext, matrixConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
fun getInstance(context: Context): Matrix {
|
||||
fun getInstance(context: Context): TestMatrix {
|
||||
if (isInit.compareAndSet(false, true)) {
|
||||
val appContext = context.applicationContext
|
||||
if (appContext is MatrixConfiguration.Provider) {
|
||||
val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration()
|
||||
instance = Matrix(appContext, matrixConfiguration)
|
||||
instance = TestMatrix(appContext, matrixConfiguration)
|
||||
} else {
|
||||
throw IllegalStateException("Matrix is not initialized properly." +
|
||||
" You should call Matrix.initialize or let your application implements MatrixConfiguration.Provider.")
|
@ -20,7 +20,6 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
|
||||
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -30,9 +29,9 @@ import kotlinx.coroutines.withTimeout
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
@ -45,7 +44,6 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||
import java.util.ArrayList
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -56,13 +54,13 @@ import java.util.concurrent.TimeUnit
|
||||
*/
|
||||
class CommonTestHelper(context: Context) {
|
||||
|
||||
val matrix: Matrix
|
||||
val matrix: TestMatrix
|
||||
|
||||
fun getTestInterceptor(session: Session): MockOkHttpInterceptor? = TestNetworkModule.interceptorForSession(session.sessionId) as? MockOkHttpInterceptor
|
||||
fun getTestInterceptor(session: Session): MockOkHttpInterceptor? = TestModule.interceptorForSession(session.sessionId) as? MockOkHttpInterceptor
|
||||
|
||||
init {
|
||||
UiThreadStatement.runOnUiThread {
|
||||
Matrix.initialize(
|
||||
TestMatrix.initialize(
|
||||
context,
|
||||
MatrixConfiguration(
|
||||
applicationFlavor = "TestFlavor",
|
||||
@ -70,7 +68,7 @@ class CommonTestHelper(context: Context) {
|
||||
)
|
||||
)
|
||||
}
|
||||
matrix = Matrix.getInstance(context)
|
||||
matrix = TestMatrix.getInstance(context)
|
||||
}
|
||||
|
||||
fun createAccount(userNamePrefix: String, testParams: SessionTestParams): Session {
|
||||
|
@ -20,6 +20,7 @@ import android.content.Context
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.internal.auth.AuthModule
|
||||
import org.matrix.android.sdk.internal.di.MatrixComponent
|
||||
import org.matrix.android.sdk.internal.di.MatrixModule
|
||||
@ -34,12 +35,13 @@ import org.matrix.android.sdk.internal.util.system.SystemModule
|
||||
NetworkModule::class,
|
||||
AuthModule::class,
|
||||
RawModule::class,
|
||||
SystemModule::class,
|
||||
TestNetworkModule::class
|
||||
SystemModule::class
|
||||
])
|
||||
@MatrixScope
|
||||
internal interface TestMatrixComponent : MatrixComponent {
|
||||
|
||||
fun inject(matrix: TestMatrix)
|
||||
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
fun create(@BindsInstance context: Context,
|
||||
|
@ -18,10 +18,43 @@ package org.matrix.android.sdk.common
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import org.matrix.android.sdk.internal.di.MatrixComponent
|
||||
import org.matrix.android.sdk.internal.di.MatrixScope
|
||||
import org.matrix.android.sdk.internal.session.MockHttpInterceptor
|
||||
import org.matrix.android.sdk.internal.session.TestInterceptor
|
||||
import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver
|
||||
import org.matrix.android.sdk.internal.util.DefaultBackgroundDetectionObserver
|
||||
import org.matrix.android.sdk.internal.util.TestBackgroundDetectionObserver
|
||||
|
||||
@Module
|
||||
internal abstract class TestModule {
|
||||
@Binds
|
||||
abstract fun providesMatrixComponent(testMatrixComponent: TestMatrixComponent): MatrixComponent
|
||||
|
||||
@Module
|
||||
companion object {
|
||||
|
||||
val interceptors = ArrayList<TestInterceptor>()
|
||||
|
||||
fun interceptorForSession(sessionId: String): TestInterceptor? = interceptors.firstOrNull { it.sessionId == sessionId }
|
||||
|
||||
@Provides
|
||||
@JvmStatic
|
||||
@MockHttpInterceptor
|
||||
fun providesTestInterceptor(): TestInterceptor? {
|
||||
return MockOkHttpInterceptor().also {
|
||||
interceptors.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@JvmStatic
|
||||
@MatrixScope
|
||||
fun providesBackgroundDetectionObserver(): BackgroundDetectionObserver {
|
||||
return TestBackgroundDetectionObserver()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.common
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import org.matrix.android.sdk.internal.session.MockHttpInterceptor
|
||||
import org.matrix.android.sdk.internal.session.TestInterceptor
|
||||
|
||||
@Module
|
||||
internal object TestNetworkModule {
|
||||
|
||||
val interceptors = ArrayList<TestInterceptor>()
|
||||
|
||||
fun interceptorForSession(sessionId: String): TestInterceptor? = interceptors.firstOrNull { it.sessionId == sessionId }
|
||||
|
||||
@Provides
|
||||
@JvmStatic
|
||||
@MockHttpInterceptor
|
||||
fun providesTestInterceptor(): TestInterceptor? {
|
||||
return MockOkHttpInterceptor().also {
|
||||
interceptors.add(it)
|
||||
}
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ object RoomDataHelper {
|
||||
content: Content? = null,
|
||||
prevContent: Content? = null,
|
||||
sender: String = FAKE_TEST_SENDER,
|
||||
stateKey: String = FAKE_TEST_SENDER
|
||||
stateKey: String? =null
|
||||
): Event {
|
||||
return Event(
|
||||
type = type,
|
||||
@ -64,6 +64,6 @@ object RoomDataHelper {
|
||||
|
||||
private fun createFakeRoomMemberEvent(): Event {
|
||||
val roomMember = RoomMemberContent(Membership.JOIN, "Fake name #${Random.nextLong()}").toContent()
|
||||
return createFakeEvent(EventType.STATE_ROOM_MEMBER, roomMember)
|
||||
return createFakeEvent(EventType.STATE_ROOM_MEMBER, roomMember, stateKey = FAKE_TEST_SENDER)
|
||||
}
|
||||
}
|
||||
|
@ -540,6 +540,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
fun testParentRelation() {
|
||||
val aliceSession = commonTestHelper.createAccount("Alice", SessionTestParams(true))
|
||||
val bobSession = commonTestHelper.createAccount("Bib", SessionTestParams(true))
|
||||
|
@ -22,22 +22,31 @@ import org.matrix.android.sdk.internal.di.MatrixScope
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* To be attached to ProcessLifecycleOwner lifecycle
|
||||
*/
|
||||
@MatrixScope
|
||||
internal class BackgroundDetectionObserver @Inject constructor() : DefaultLifecycleObserver {
|
||||
|
||||
var isInBackground: Boolean = true
|
||||
interface BackgroundDetectionObserver: DefaultLifecycleObserver {
|
||||
val isInBackground: Boolean
|
||||
|
||||
fun register(listener: Listener)
|
||||
fun unregister(listener: Listener)
|
||||
|
||||
interface Listener {
|
||||
fun onMoveToForeground()
|
||||
fun onMoveToBackground()
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultBackgroundDetectionObserver: BackgroundDetectionObserver {
|
||||
|
||||
override var isInBackground: Boolean = true
|
||||
private set
|
||||
|
||||
private val listeners = LinkedHashSet<Listener>()
|
||||
private val listeners = LinkedHashSet<BackgroundDetectionObserver.Listener>()
|
||||
|
||||
fun register(listener: Listener) {
|
||||
override fun register(listener: BackgroundDetectionObserver.Listener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun unregister(listener: Listener) {
|
||||
override fun unregister(listener: BackgroundDetectionObserver.Listener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
@ -52,9 +61,17 @@ internal class BackgroundDetectionObserver @Inject constructor() : DefaultLifecy
|
||||
isInBackground = true
|
||||
listeners.forEach { it.onMoveToBackground() }
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun onMoveToForeground()
|
||||
fun onMoveToBackground()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force foreground for testing
|
||||
*/
|
||||
internal class TestBackgroundDetectionObserver : BackgroundDetectionObserver {
|
||||
|
||||
override val isInBackground: Boolean = false
|
||||
|
||||
override fun register(listener: BackgroundDetectionObserver.Listener) = Unit
|
||||
|
||||
override fun unregister(listener: BackgroundDetectionObserver.Listener) = Unit
|
||||
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@ -62,7 +63,7 @@ class SecurityBootstrapTest : VerificationTestBase() {
|
||||
@Before
|
||||
fun createSessionWithCrossSigning() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val matrix = Matrix.getInstance(context)
|
||||
val matrix = TestMatrix.getInstance(context)
|
||||
val userName = "foobar_${System.currentTimeMillis()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
stubAllExternalIntents()
|
||||
|
@ -25,8 +25,8 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.junit.Assert
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
@ -41,7 +41,7 @@ abstract class VerificationTestBase {
|
||||
|
||||
protected val uiTestBase = OnboardingRobot()
|
||||
|
||||
fun createAccountAndSync(matrix: Matrix,
|
||||
fun createAccountAndSync(matrix: TestMatrix,
|
||||
userName: String,
|
||||
password: String,
|
||||
withInitialSync: Boolean): Session {
|
||||
|
@ -42,6 +42,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
@ -67,7 +68,7 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
@Before
|
||||
fun createSessionWithCrossSigning() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val matrix = Matrix.getInstance(context)
|
||||
val matrix = TestMatrix.getInstance(context)
|
||||
val userName = "foobar_${System.currentTimeMillis()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
doSync<Unit> {
|
||||
|
@ -46,6 +46,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.TestMatrix
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
@ -67,7 +68,7 @@ class VerifySessionPassphraseTest : VerificationTestBase() {
|
||||
@Before
|
||||
fun createSessionWithCrossSigningAnd4S() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val matrix = Matrix.getInstance(context)
|
||||
val matrix = TestMatrix.getInstance(context)
|
||||
val userName = "foobar_${System.currentTimeMillis()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
doSync<Unit> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user