diff --git a/build.gradle b/build.gradle
index d7a691a3b6..f4a5eac85e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
+ classpath "com.airbnb.okreplay:gradle-plugin:1.4.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 49a9a3b72f..09d01fceae 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
+apply plugin: 'okreplay'
buildscript {
@@ -38,6 +39,10 @@ android {
}
}
+ adbOptions {
+ installOptions "-g"
+ }
+
}
dependencies {
@@ -94,14 +99,20 @@ dependencies {
// Logging
implementation 'com.jakewharton.timber:timber:4.7.1'
+ debugImplementation 'com.airbnb.okreplay:okreplay:1.4.0'
+ releaseImplementation 'com.airbnb.okreplay:noop:1.4.0'
+ androidTestImplementation 'com.airbnb.okreplay:espresso:1.4.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:4.0.2'
+ testImplementation "org.koin:koin-test:$koin_version"
testImplementation 'org.robolectric:shadows-support-v4:3.0'
testImplementation "io.mockk:mockk:1.8.13.kotlin13"
testImplementation 'org.amshove.kluent:kluent-android:1.44'
+ androidTestImplementation "org.koin:koin-test:$koin_version"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation "com.android.support.test:rules:1.0.2"
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'org.amshove.kluent:kluent-android:1.44'
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
index c726b7eb0f..b40f8a8ada 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt
@@ -4,7 +4,7 @@ import android.content.Context
import android.support.test.InstrumentationRegistry
import java.io.File
-abstract class InstrumentedTest {
+interface InstrumentedTest {
fun context(): Context {
return InstrumentationRegistry.getTargetContext()
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/OkReplayRuleChainNoActivity.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/OkReplayRuleChainNoActivity.kt
new file mode 100644
index 0000000000..9ed443f53e
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/OkReplayRuleChainNoActivity.kt
@@ -0,0 +1,16 @@
+package im.vector.matrix.android
+
+import okreplay.OkReplayConfig
+import okreplay.PermissionRule
+import okreplay.RecorderRule
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+
+class OkReplayRuleChainNoActivity(
+ private val configuration: OkReplayConfig) {
+
+ fun get(): TestRule {
+ return RuleChain.outerRule(PermissionRule(configuration))
+ .around(RecorderRule(configuration))
+ }
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt
new file mode 100644
index 0000000000..e0c1c0f534
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt
@@ -0,0 +1,64 @@
+package im.vector.matrix.android.auth
+
+import android.support.test.annotation.UiThreadTest
+import android.support.test.rule.GrantPermissionRule
+import android.support.test.runner.AndroidJUnit4
+import com.zhuinden.monarchy.Monarchy
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.OkReplayRuleChainNoActivity
+import im.vector.matrix.android.api.MatrixOptions
+import im.vector.matrix.android.api.auth.Authenticator
+import im.vector.matrix.android.internal.auth.AuthModule
+import im.vector.matrix.android.internal.di.MatrixModule
+import im.vector.matrix.android.internal.di.NetworkModule
+import okreplay.*
+import org.junit.ClassRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.koin.standalone.StandAloneContext.loadKoinModules
+import org.koin.standalone.inject
+import org.koin.test.KoinTest
+
+
+@RunWith(AndroidJUnit4::class)
+internal class AuthenticatorTest : InstrumentedTest, KoinTest {
+
+ init {
+ Monarchy.init(context())
+ val matrixModule = MatrixModule(MatrixOptions(context())).definition
+ val networkModule = NetworkModule().definition
+ val authModule = AuthModule().definition
+ loadKoinModules(listOf(matrixModule, networkModule, authModule))
+ }
+
+ private val authenticator: Authenticator by inject()
+ private val okReplayInterceptor: OkReplayInterceptor by inject()
+
+ private val okReplayConfig = OkReplayConfig.Builder()
+ .tapeRoot(AndroidTapeRoot(
+ context(), javaClass))
+ .defaultMode(TapeMode.READ_WRITE) // or TapeMode.READ_ONLY
+ .sslEnabled(true)
+ .interceptor(okReplayInterceptor)
+ .build()
+
+ @get:Rule
+ val testRule = OkReplayRuleChainNoActivity(okReplayConfig).get()
+
+ @Test
+ @UiThreadTest
+ @OkReplay(tape = "auth", mode = TapeMode.READ_WRITE)
+ fun auth() {
+
+ }
+
+ companion object {
+ @ClassRule
+ @JvmField
+ val grantExternalStoragePermissionRule: GrantPermissionRule =
+ GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ }
+
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt
index b1c8993501..137ec790e1 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt
@@ -22,7 +22,7 @@ import org.junit.Test
import kotlin.random.Random
-internal class ChunkEntityTest : InstrumentedTest() {
+internal class ChunkEntityTest : InstrumentedTest {
private lateinit var monarchy: Monarchy
diff --git a/matrix-sdk-android/src/main/AndroidManifest.xml b/matrix-sdk-android/src/main/AndroidManifest.xml
index 44b519b0b0..fc705e553c 100644
--- a/matrix-sdk-android/src/main/AndroidManifest.xml
+++ b/matrix-sdk-android/src/main/AndroidManifest.xml
@@ -3,4 +3,5 @@
+
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
index 88bf3c3eb3..689f05645a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
@@ -23,12 +23,10 @@ class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
init {
Monarchy.init(matrixOptions.context)
-
- val matrixModule = MatrixModule(matrixOptions)
- val networkModule = NetworkModule()
- val authModule = AuthModule()
+ val matrixModule = MatrixModule(matrixOptions).definition
+ val networkModule = NetworkModule().definition
+ val authModule = AuthModule().definition
loadKoinModules(listOf(matrixModule, networkModule, authModule))
-
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
val lastActiveSession = authenticator.getLastActiveSession()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
index ab5443e0d1..10f760e860 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
@@ -4,13 +4,11 @@ import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.internal.auth.db.RealmSessionParamsStore
import im.vector.matrix.android.internal.auth.db.SessionParamsMapper
import io.realm.RealmConfiguration
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
-class AuthModule : Module {
+class AuthModule {
- override fun invoke(): ModuleDefinition = module {
+ val definition = module {
single {
DefaultAuthenticator(get(), get(), get()) as Authenticator
@@ -22,5 +20,5 @@ class AuthModule : Module {
RealmSessionParamsStore(mapper, realmConfiguration) as SessionParamsStore
}
- }.invoke()
+ }
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
index d5dfd618e7..154777d0e4 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt
@@ -6,14 +6,12 @@ import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asCoroutineDispatcher
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
-class MatrixModule(private val options: MatrixOptions) : Module {
+class MatrixModule(private val options: MatrixOptions) {
- override fun invoke(): ModuleDefinition = module {
+ val definition = module {
single {
options.context
@@ -27,5 +25,5 @@ class MatrixModule(private val options: MatrixOptions) : Module {
BackgroundDetectionObserver()
}
- }.invoke()
+ }
}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
index 69f2c68f0f..fe9709b24e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
@@ -4,8 +4,7 @@ import im.vector.matrix.android.internal.network.AccessTokenInterceptor
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
+import okreplay.OkReplayInterceptor
import org.koin.dsl.module.module
import retrofit2.Converter
import retrofit2.Retrofit
@@ -13,9 +12,9 @@ import retrofit2.converter.moshi.MoshiConverterFactory
import timber.log.Timber
import java.util.concurrent.TimeUnit
-class NetworkModule : Module {
+class NetworkModule {
- override fun invoke(): ModuleDefinition = module {
+ val definition = module {
single {
AccessTokenInterceptor(get())
@@ -28,13 +27,18 @@ class NetworkModule : Module {
interceptor
}
+ single {
+ OkReplayInterceptor()
+ }
+
single {
OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
- .addInterceptor(get() as AccessTokenInterceptor)
- .addInterceptor(get() as HttpLoggingInterceptor)
+ .addInterceptor(get())
+ .addInterceptor(get())
+ .addInterceptor(get())
.build()
}
@@ -56,5 +60,5 @@ class NetworkModule : Module {
.addConverterFactory(get())
}
- }.invoke()
+ }
}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
index d474c8d926..e5d86c1d41 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt
@@ -3,6 +3,7 @@ package im.vector.matrix.android.internal.session
import android.arch.lifecycle.LiveData
import android.os.Looper
import android.support.annotation.MainThread
+import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.group.Group
import im.vector.matrix.android.api.session.group.GroupService
@@ -10,7 +11,6 @@ import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.room.model.RoomSummary
-import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.session.group.GroupModule
import im.vector.matrix.android.internal.session.room.RoomModule
@@ -39,13 +39,13 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
@MainThread
override fun open() {
- checkIsMainThread()
+ assertMainThread()
assert(!isOpen)
isOpen = true
- val sessionModule = SessionModule(sessionParams)
- val syncModule = SyncModule()
- val roomModule = RoomModule()
- val groupModule = GroupModule()
+ val sessionModule = SessionModule(sessionParams).definition
+ val syncModule = SyncModule().definition
+ val roomModule = RoomModule().definition
+ val groupModule = GroupModule().definition
StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule, roomModule, groupModule))
scope = getKoin().getOrCreateScope(SCOPE)
liveEntityUpdaters.forEach { it.start() }
@@ -55,7 +55,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
@MainThread
override fun close() {
- checkIsMainThread()
+ assertMainThread()
assert(isOpen)
syncThread.kill()
liveEntityUpdaters.forEach { it.dispose() }
@@ -109,9 +109,9 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
// Private methods *****************************************************************************
- private fun checkIsMainThread() {
- if (Looper.myLooper() != Looper.getMainLooper()) {
- throw IllegalStateException("Should be called on main thread")
+ private fun assertMainThread() {
+ if (Looper.getMainLooper().thread !== Thread.currentThread()) {
+ throw IllegalStateException("This method can only be called on the main thread!")
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
index 8c88122c55..55990d4ed3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
@@ -16,15 +16,13 @@ import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameRes
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
import im.vector.matrix.android.internal.util.md5
import io.realm.RealmConfiguration
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
import retrofit2.Retrofit
import java.io.File
-internal class SessionModule(private val sessionParams: SessionParams) : Module {
+internal class SessionModule(private val sessionParams: SessionParams) {
- override fun invoke(): ModuleDefinition = module(override = true) {
+ val definition = module(override = true) {
scope(DefaultSession.SCOPE) {
sessionParams
@@ -85,7 +83,7 @@ internal class SessionModule(private val sessionParams: SessionParams) : Module
}
- }.invoke()
+ }
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupModule.kt
index 1f8bf99ce3..d1dd75ffdb 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupModule.kt
@@ -1,14 +1,12 @@
package im.vector.matrix.android.internal.session.group
import im.vector.matrix.android.internal.session.DefaultSession
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
import retrofit2.Retrofit
-class GroupModule : Module {
+class GroupModule {
- override fun invoke(): ModuleDefinition = module(override = true) {
+ val definition = module(override = true) {
scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
@@ -19,5 +17,5 @@ class GroupModule : Module {
GetGroupDataRequest(get(), get(), get())
}
- }.invoke()
+ }
}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt
index 9a7e897eaf..a823124c54 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt
@@ -9,16 +9,14 @@ import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersReq
import im.vector.matrix.android.internal.session.room.send.DefaultSendService
import im.vector.matrix.android.internal.session.room.timeline.*
import im.vector.matrix.android.internal.util.PagingRequestHelper
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
import retrofit2.Retrofit
import java.util.concurrent.Executors
-class RoomModule : Module {
+class RoomModule {
- override fun invoke(): ModuleDefinition = module(override = true) {
+ val definition = module(override = true) {
scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
@@ -56,5 +54,5 @@ class RoomModule : Module {
DefaultSendService(roomId, get(), get()) as SendService
}
- }.invoke()
+ }
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt
index 0ae3e61837..dca339c018 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt
@@ -2,15 +2,13 @@ package im.vector.matrix.android.internal.session.sync
import im.vector.matrix.android.internal.session.DefaultSession
import im.vector.matrix.android.internal.session.sync.job.SyncThread
-import org.koin.dsl.context.ModuleDefinition
-import org.koin.dsl.module.Module
import org.koin.dsl.module.module
import retrofit2.Retrofit
-internal class SyncModule : Module {
+internal class SyncModule {
- override fun invoke(): ModuleDefinition = module(override = true) {
+ val definition = module(override = true) {
scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
@@ -49,5 +47,5 @@ internal class SyncModule : Module {
SyncThread(get(), get(), get(), get())
}
- }.invoke()
+ }
}