srctree

Robin Linden parent f4ea6b57 a9c31ef6
Add a test checking that profile creation works

inlinesplit
.github/workflows/ci.yaml added: 108, removed: 10, total 98
@@ -8,4 +8,4 @@ jobs:
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
script: ./gradlew connectedCheck -x :domain:connectedAndroidTest
script: ./gradlew connectedCheck -x :atox:connectedAndroidTest -x :domain:connectedAndroidTest
 
atox/build.gradle.kts added: 108, removed: 10, total 98
@@ -42,6 +42,7 @@ android {
disable("GoogleAppIndexingWarning", "MissingTranslation", "InvalidPackage")
}
sourceSets["main"].java.srcDir("src/main/kotlin")
sourceSets["androidTest"].java.srcDir("src/androidTest/kotlin")
packagingOptions {
// Work around scala-compiler and scala-library (via tox4j) trying to place files in the
// same place.
@@ -79,7 +80,11 @@ dependencies {
debugImplementation(Libraries.leakcanaryAndroid)
 
testImplementation(Libraries.junit)
androidTestImplementation(Libraries.rules)
androidTestImplementation(Libraries.runner)
androidTestImplementation(Libraries.espressoCore)
androidTestImplementation(Libraries.espressoContrib)
androidTestImplementation(Libraries.androidJUnit)
androidTestImplementation(Libraries.mockk)
kaptAndroidTest(Libraries.daggerCompiler)
}
 
filename was Deleted added: 108, removed: 10, total 98
@@ -0,0 +1,84 @@
package ltd.evilcorp.atox
 
import android.app.Activity
import android.content.Context
import androidx.room.Room
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import dagger.Provides
import io.mockk.every
import io.mockk.mockk
import ltd.evilcorp.atox.di.AppComponent
import ltd.evilcorp.atox.di.ViewModelModule
import ltd.evilcorp.core.db.Database
import ltd.evilcorp.core.di.DaoModule
import ltd.evilcorp.domain.tox.SaveManager
import org.hamcrest.core.AllOf.allOf
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import javax.inject.Singleton
 
class InjectedActivityTestRule<T : Activity>(
activityClass: Class<T>,
private val listener: () -> Unit
) : ActivityTestRule<T>(activityClass, false, true) {
override fun beforeActivityLaunched() {
super.beforeActivityLaunched()
listener()
}
}
 
@Module
class TestModule {
@Singleton
@Provides
fun provideDatabase(appContext: Context): Database =
Room.inMemoryDatabaseBuilder(appContext, Database::class.java).build()
 
@Provides
fun provideSaveManager(): SaveManager = mockk(relaxUnitFun = true) {
every { list() } returns listOf()
}
}
 
@Singleton
@Component(modules = [TestModule::class, DaoModule::class, ViewModelModule::class])
interface TestComponent : AppComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance appContext: Context): AppComponent
}
}
 
@RunWith(AndroidJUnit4::class)
class IntegrationTest {
@get:Rule
val activityRule = InjectedActivityTestRule(MainActivity::class.java) {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val app = instrumentation.targetContext.applicationContext as App
app.componentOverride = DaggerTestComponent.factory().create(app)
}
 
@Test
fun profileCreationWorks() {
// ProfileFragment
onView(withId(R.id.username)).perform(typeText("mr robotto"), closeSoftKeyboard())
onView(withId(R.id.btnCreate)).perform(click())
 
// ContactListFragment
onView(withId(R.id.drawerLayout)).perform(DrawerActions.open())
onView(withId(R.id.profileName)).check(matches(isDisplayed()))
onView(allOf(withId(R.id.profileName), withText("mr robotto")))
.check(matches(isDisplayed()))
}
}
 
atox/src/main/kotlin/App.kt added: 108, removed: 10, total 98
@@ -6,6 +6,8 @@ import ltd.evilcorp.atox.di.DaggerAppComponent
 
class App : MultiDexApplication() {
val component: AppComponent by lazy {
DaggerAppComponent.factory().create(applicationContext)
componentOverride ?: DaggerAppComponent.factory().create(applicationContext)
}
 
var componentOverride: AppComponent? = null
}
 
atox/src/main/kotlin/di/AppComponent.kt added: 108, removed: 10, total 98
@@ -5,11 +5,12 @@ import dagger.BindsInstance
import dagger.Component
import ltd.evilcorp.atox.MainActivity
import ltd.evilcorp.atox.ToxService
import ltd.evilcorp.core.di.DaoModule
import ltd.evilcorp.core.di.DatabaseModule
import javax.inject.Singleton
 
@Singleton
@Component(modules = [DatabaseModule::class, ViewModelModule::class])
@Component(modules = [DatabaseModule::class, DaoModule::class, ViewModelModule::class])
interface AppComponent {
@Component.Factory
interface Factory {
 
buildSrc/src/main/kotlin/Dependencies.kt added: 108, removed: 10, total 98
@@ -91,7 +91,9 @@ object Libraries {
 
const val junit = "junit:junit:4.13"
const val runner = "androidx.test:runner:1.2.0"
const val rules = "androidx.test:rules:1.2.0"
const val espressoCore = "androidx.test.espresso:espresso-core:3.2.0"
const val espressoContrib = "androidx.test.espresso:espresso-contrib:3.2.0"
const val androidJUnit = "androidx.test.ext:junit:1.1.1"
const val roomTesting = "androidx.room:room-testing:${Version.room}"
 
 
core/src/main/kotlin/di/DatabaseModule.kt added: 108, removed: 10, total 98
@@ -16,7 +16,11 @@ class DatabaseModule {
Room.databaseBuilder(appContext, Database::class.java, "core_db")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
}
 
@Suppress("unused")
@Module
class DaoModule {
@Singleton
@Provides
internal fun provideContactDao(db: Database): ContactDao = db.contactDao()