Try to configure okreplay for testing network + start to rework koin modules

This commit is contained in:
ganfra 2018-12-12 21:15:01 +01:00
parent 1d5587c5ba
commit c8c31172b3
16 changed files with 137 additions and 54 deletions

View File

@ -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

View File

@ -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'


View File

@ -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()
}

View File

@ -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))
}
}

View File

@ -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)
}


}

View File

@ -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


View File

@ -3,4 +3,5 @@

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

View File

@ -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()

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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<AccessTokenInterceptor>())
.addInterceptor(get<HttpLoggingInterceptor>())
.addInterceptor(get<OkReplayInterceptor>())
.build()
}

@ -56,5 +60,5 @@ class NetworkModule : Module {
.addConverterFactory(get())
}

}.invoke()
}
}

View File

@ -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!")
}
}


View File

@ -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()
}


}

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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()
}
}