Преглед изворни кода

refactoring deps_versions.gradle and build.gradle for feature_auth
add unit test for UserAuthRepositoryImpl

MrOzOn пре 5 година
родитељ
комит
2006efee53

+ 15 - 10
feature_auth/build.gradle

@@ -38,25 +38,30 @@ android {
 apply from: "$project.rootDir/scripts/deps_versions.gradle"
 
 dependencies {
+    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation kotlinStdlib
+
     api project(':core_api')
     implementation project(':core')
+    implementation project(':utils')
     //DAGGER
     implementation dagger
-    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
     kapt daggerCompiler
-    implementation project(':utils')
     implementation constraintlayout
     //Timber
     implementation timber
     implementation navigationFragment
     implementation retrofit
-
-    implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
-    implementation 'androidx.core:core-ktx:1.3.1'
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    testImplementation 'junit:junit:4.12'
-    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+    //AndroidX
+    implementation legacySupport
+    implementation appCompat
+    implementation androidxCore
+    //Unit test
+    testImplementation junit
+    testImplementation mockitoCore
+    testImplementation kotlinxCoroutinesTest
+    //Instrumental Test
+    androidTestImplementation junitInstrumental
+    androidTestImplementation espressoCore
 
 }

+ 0 - 7
feature_auth/src/main/java/com/mrozon/feature_auth/data/UserAuthRemoteDataSource.kt

@@ -8,16 +8,9 @@ import javax.inject.Inject
 
 class UserAuthRemoteDataSource @Inject constructor(private val service: HealthDiaryService): BaseDataSource() {
 
-    suspend fun loginUser(userName: String, userPsw: String)
-            = getResult { service.loginUser(LoginRequest(username = userName, password = userPsw)) }
-
     suspend fun loginUser(loginRequest: LoginRequest)
             = getResult { service.loginUser(loginRequest) }
 
-    suspend fun registerUser(email: String, password: String, firstName: String, lastName: String)
-            = getResult { service.registerUser(RegisterRequest(email = email, username = email,
-                password = password, first_name = firstName, last_name = lastName )) }
-
     suspend fun registerUser(registerRequest: RegisterRequest)
             = getResult { service.registerUser(registerRequest) }
 

+ 2 - 0
feature_auth/src/main/java/com/mrozon/feature_auth/data/UserAuthRepositoryImpl.kt

@@ -12,6 +12,7 @@ import com.mrozon.utils.network.Result
 import com.mrozon.utils.network.Result.Companion.error
 import com.mrozon.utils.network.Result.Companion.loading
 import com.mrozon.utils.network.Result.Companion.success
+import timber.log.Timber
 
 @Singleton
 class UserAuthRepositoryImpl @Inject constructor(private val userAuthRemoteDataSource: UserAuthRemoteDataSource,
@@ -39,6 +40,7 @@ class UserAuthRepositoryImpl @Inject constructor(private val userAuthRemoteDataS
             val request = LoginRequest(username = userName, password = password)
             val response = userAuthRemoteDataSource.loginUser(request)
             if (response.status == Result.Status.SUCCESS) {
+                Timber.d("sahdksdh")
                 dao.insertUser(response.data!!.toUserDb())
                 emit(success(response.data!!.toUser()))
             } else if (response.status == Result.Status.ERROR) {

+ 0 - 17
feature_auth/src/test/java/com/mrozon/feature_auth/ExampleUnitTest.kt

@@ -1,17 +0,0 @@
-package com.mrozon.feature_auth
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
-    @Test
-    fun addition_isCorrect() {
-        assertEquals(4, 2 + 2)
-    }
-}

+ 188 - 0
feature_auth/src/test/java/com/mrozon/feature_auth/data/UserAuthRepositoryImplTest.kt

@@ -0,0 +1,188 @@
+package com.mrozon.feature_auth.data
+
+import com.mrozon.core_api.db.HealthDiaryDao
+import com.mrozon.core_api.network.HealthDiaryService
+import com.mrozon.core_api.network.model.*
+import com.mrozon.utils.network.Result.Companion.loading
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.toList
+import kotlinx.coroutines.test.TestCoroutineDispatcher
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.setMain
+import org.junit.Assert.*
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestWatcher
+import org.junit.runner.Description
+import com.mrozon.utils.network.Result.Companion.error
+import com.mrozon.utils.network.Result.Companion.success
+import okhttp3.MediaType
+import okhttp3.ResponseBody
+import org.junit.Before
+import org.mockito.Mock
+import org.mockito.Mockito.*
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import retrofit2.Response
+
+@ExperimentalCoroutinesApi
+class UserAuthRepositoryImplTest {
+
+    @get:Rule
+    val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    @Mock
+    lateinit var apiService: HealthDiaryService
+
+    @Mock
+    lateinit var dao: HealthDiaryDao
+
+    lateinit var repository: UserAuthRepository
+
+    @get:Rule
+    var coroutinesTestRule = CoroutineTestRule()
+
+    @Before
+    fun setUp() {
+        val source = UserAuthRemoteDataSource(apiService)
+        repository = UserAuthRepositoryImpl(source, dao)
+    }
+
+    @Test
+    fun `register user success`() = coroutinesTestRule.testDispatcher.runBlockingTest {
+        val email = "test@mail.ru"
+        val password = "password1"
+        val request = RegisterRequest(email = email, first_name = "",
+            last_name = "",username = email, password = password)
+        val response = RegisterResponse(email=email, id = 1, first_name =  "",
+            last_name = "", last_login = "", username = email )
+        val expected = listOf(
+            loading(),
+            success(response.toUser())
+        )
+
+        `when`(apiService.registerUser(request)).thenReturn(
+            Response.success(response)
+        )
+
+        val actual = repository.registerUser(response.toUser(),password)
+
+        assertEquals(
+            expected,
+            actual.toList()
+        )
+    }
+
+    @Test
+    fun `register user failed`() = coroutinesTestRule.testDispatcher.runBlockingTest {
+        val error = "Bla-Bla!"
+        val email = "test@mail.ru"
+        val password = "password1"
+        val request = RegisterRequest(email = email, first_name = "",
+            last_name = "",username = email, password = password)
+        val response = RegisterResponse(email=email, id = 1, first_name =  "",
+            last_name = "", last_login = "", username = email )
+        val expected = listOf(
+            loading(),
+            error("Network error:\n $error",null)
+        )
+
+        `when`(apiService.registerUser(request)).thenReturn(
+            Response.error(402, ResponseBody.create(MediaType.get("text/plain"),"[$error]"))
+        )
+
+        val actual = repository.registerUser(response.toUser(),password)
+
+        assertEquals(
+            expected,
+            actual.toList()
+        )
+    }
+
+    @Test
+    fun `login user success`() = coroutinesTestRule.testDispatcher.runBlockingTest {
+
+        val username = "vasya@mail.ru"
+        val password = "strong_password"
+        val request = LoginRequest(username,password)
+        val response = LoginResponse(email = username, first_name = "",
+            last_name = "", token = "aaaaa", user_id = 101)
+
+        val expected = listOf(
+            loading(),
+            success(response.toUser())
+        )
+
+        `when`(apiService.loginUser(request)).thenReturn(
+            Response.success(response)
+        )
+
+        val actual = repository.loginUser(username,password)
+
+        assertEquals(
+            expected,
+            actual.toList()
+        )
+    }
+
+    @Test
+    fun `logged user added in db`() = coroutinesTestRule.testDispatcher.runBlockingTest {
+
+        val username = "vasya@mail.ru"
+        val password = "strong_password"
+        val request = LoginRequest(username,password)
+        val response = LoginResponse(email = username, first_name = "first_name",
+            last_name = "last_name", token = "aaaaa", user_id = 101)
+
+        `when`(apiService.loginUser(request)).thenReturn(
+            Response.success(response)
+        )
+
+        repository.loginUser(username,password).toList()
+
+        verify(dao).insertUser(response.toUserDb())
+    }
+
+    @Test
+    fun `login user failed`() = coroutinesTestRule.testDispatcher.runBlockingTest {
+        val error = "Bla-Bla!"
+        val username = "vasya@mail.ru"
+        val password = "strong_password"
+        val request = LoginRequest(username,password)
+
+        val expected = listOf(
+            loading(),
+            error("Network error:\n $error",null)
+        )
+
+        `when`(apiService.loginUser(request)).thenReturn(
+            Response.error(402, ResponseBody.create(MediaType.get("text/plain"),"[$error]"))
+        )
+
+        val actual = repository.loginUser(username,password)
+
+        assertEquals(
+            expected,
+            actual.toList()
+        )
+    }
+
+
+
+}
+
+@ExperimentalCoroutinesApi
+class CoroutineTestRule(val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) : TestWatcher() {
+    override fun starting(description: Description?) {
+        super.starting(description)
+        Dispatchers.setMain(testDispatcher)
+    }
+
+    override fun finished(description: Description?) {
+        super.finished(description)
+        Dispatchers.resetMain()
+        testDispatcher.cleanupTestCoroutines()
+    }
+}

+ 21 - 18
scripts/deps_versions.gradle

@@ -1,14 +1,8 @@
 ext {
 
 
-//    jsr330Version = '1'
     daggerVersion = '2.25.2'
     roomVersion = '2.1.0'
-//    picassoVersion = '2.71828'
-//    flexLayoutVersion = '1.1.1'
-//    viewPager2Version = '1.0.0-rc01'
-//    coroutinesVersion = '1.1.1'
-//    materialVersion = '1.1.0-beta02'
     navigationVersion = '2.3.0'
     timberVersion = '4.7.1'
     retrofitVersion = '2.6.1'
@@ -19,9 +13,15 @@ ext {
     recyclerviewViersion = '1.2.0-alpha05'
     materialVersion = '1.2.1'
     lifecycleVersion = '2.3.0-alpha07'
+    junitVersion = "4.12"
+    mockitoCoreVersion = "2.28.2"
+    kotlinxCoroutinesTestVersion = "1.3.1"
+    junitInstrumentalVersion = "1.1.1"
+    espressoCoreVersion = "3.2.0"
+    legacySupportVersion = "1.0.0"
+    appCompatVersion = "1.2.0"
+    androidxCoreVersion = "1.3.1"
 
-//    retrofit = "com.squareup.retrofit2:retrofit:$retrofitVersion"
-//    jsr330 = "javax.inject:javax.inject:$jsr330Version"
     // DI
     dagger = "com.google.dagger:dagger:$daggerVersion"
     daggerCompiler = "com.google.dagger:dagger-compiler:$daggerVersion"
@@ -29,16 +29,6 @@ ext {
     room = "androidx.room:room-runtime:$roomVersion"
     roomKtx = "androidx.room:room-ktx:$roomVersion"
     roomCompiler = "androidx.room:room-compiler:$roomVersion"
-//    picasso = "com.squareup.picasso:picasso:$picassoVersion"
-//    flexLayout = "com.google.android:flexbox:$flexLayoutVersion"
-//    viewPager2 = "androidx.viewpager2:viewpager2:$viewPager2Version"
-//    coroutinesDependencies = [
-//            'coroutines_core'   : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion",
-//            'coroutines_android': "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
-//    ]
-//
-//    material = "com.google.android.material:material:$materialVersion"
-
     // Navigation
     navigationFragment = "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
     navigationUi = "androidx.navigation:navigation-ui-ktx:$navigationVersion"
@@ -61,4 +51,17 @@ ext {
     lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"
     lifecycleLivedata = "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
     lifecycleViewmodel = "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
+    // Testing
+    junit = "junit:junit:$junitVersion"
+    mockitoCore = "org.mockito:mockito-core:$mockitoCoreVersion"
+    kotlinxCoroutinesTest =  "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinxCoroutinesTestVersion"
+    junitInstrumental =  "androidx.test.ext:junit:$junitInstrumentalVersion"
+    espressoCore = "androidx.test.espresso:espresso-core:$espressoCoreVersion"
+    // Support Library AndroidX
+    legacySupport = "androidx.legacy:legacy-support-v4:$legacySupportVersion"
+    appCompat =  "androidx.appcompat:appcompat:$appCompatVersion"
+    androidxCore = "androidx.core:core-ktx:$androidxCoreVersion"
+    // Kotlin
+    kotlinStdlib = "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+
 }