From cea1c0c0fa692af6e6ea2482076b5606f0685243 Mon Sep 17 00:00:00 2001 From: Trey Herman Date: Wed, 28 Oct 2020 14:09:55 -0500 Subject: [PATCH] add persistence --- README.md | 3 +- app/build.gradle | 9 + .../employeedirectory/AppComponent.kt | 1 + .../employeedirectory/PersistenceModule.kt | 29 +++ .../extension/RxJavaExtensions.kt | 9 + .../persistence/EmployeeDirectoryDatabase.kt | 11 + .../persistence/dao/EmployeeDao.kt | 19 ++ .../persistence/model/EmployeeEntity.kt | 17 ++ .../response/employee/EmployeeResponse.kt | 2 +- .../maindirectory/MainDirectoryPresenter.kt | 206 +++++++++++------- .../mapper/EmployeeModelMapper.kt | 5 +- .../mapper/EmployeeModelMapperImpl.kt | 39 +++- .../MainDirectoryPresenterTest.kt | 32 +-- .../mapper/EmployeeModelMapperTest.kt | 2 +- build.gradle | 1 + 15 files changed, 269 insertions(+), 116 deletions(-) create mode 100644 app/src/main/java/com/treyherman/employeedirectory/PersistenceModule.kt create mode 100644 app/src/main/java/com/treyherman/employeedirectory/persistence/EmployeeDirectoryDatabase.kt create mode 100644 app/src/main/java/com/treyherman/employeedirectory/persistence/dao/EmployeeDao.kt create mode 100644 app/src/main/java/com/treyherman/employeedirectory/persistence/model/EmployeeEntity.kt diff --git a/README.md b/README.md index 3567f0c..b76861d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ 3. Copied-in code/dependencies - Reused the extension functions from past projects - Reused Dagger module structure from past projects -- Reused AbsItemsAdapter + AbsViewHolder from past projects +- Reused AbsItemsAdapter + AbsViewHolder + from past projects 4. Tablet/phone focus - Phone diff --git a/app/build.gradle b/app/build.gradle index f37e87d..3d4d852 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,6 +80,15 @@ dependencies { implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion" implementation "com.squareup.okio:okio:2.8.0" + // room + implementation "androidx.room:room-runtime:$roomVersion" + implementation "androidx.room:room-rxjava2:$roomVersion" + annotationProcessor "androidx.room:room-compiler:$roomVersion" + kapt "androidx.room:room-compiler:$roomVersion" +// implementation "androidx.room:room-runtime:$roomVersion" +// kapt "androidx.room:room-compiler:$roomVersion" +// implementation "android.arch.persistence.room:rxjava2:$roomVersion" + // material components implementation "com.google.android.material:material:$materialComponentsVersion" diff --git a/app/src/main/java/com/treyherman/employeedirectory/AppComponent.kt b/app/src/main/java/com/treyherman/employeedirectory/AppComponent.kt index cc6e991..78a99cd 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/AppComponent.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/AppComponent.kt @@ -10,6 +10,7 @@ import javax.inject.Singleton AndroidSupportInjectionModule::class, NetworkModule::class, AppModule::class, + PersistenceModule::class, AndroidModule::class, InjectorModule::class ] diff --git a/app/src/main/java/com/treyherman/employeedirectory/PersistenceModule.kt b/app/src/main/java/com/treyherman/employeedirectory/PersistenceModule.kt new file mode 100644 index 0000000..c10b980 --- /dev/null +++ b/app/src/main/java/com/treyherman/employeedirectory/PersistenceModule.kt @@ -0,0 +1,29 @@ +package com.treyherman.employeedirectory + +import android.content.Context +import androidx.room.Room +import com.treyherman.employeedirectory.persistence.EmployeeDirectoryDatabase +import com.treyherman.employeedirectory.persistence.dao.EmployeeDao +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class PersistenceModule { + companion object { + private const val DATABASE_NAME = "employee_database" + } + + @Provides + @Singleton + fun provideEmployeeDirectoryDatabase(context: Context): EmployeeDirectoryDatabase { + return Room.databaseBuilder(context, EmployeeDirectoryDatabase::class.java, DATABASE_NAME) + .fallbackToDestructiveMigration() + .build() + } + + @Provides + fun provideEmployeeDao(database: EmployeeDirectoryDatabase): EmployeeDao { + return database.employeeDao() + } +} diff --git a/app/src/main/java/com/treyherman/employeedirectory/extension/RxJavaExtensions.kt b/app/src/main/java/com/treyherman/employeedirectory/extension/RxJavaExtensions.kt index 15614ce..69e9d90 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/extension/RxJavaExtensions.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/extension/RxJavaExtensions.kt @@ -1,5 +1,6 @@ package com.treyherman.employeedirectory.extension +import io.reactivex.Observable import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -15,3 +16,11 @@ fun Single.subscribeOnComputation(): Single { fun Single.observeOnMain(): Single { return this.observeOn(AndroidSchedulers.mainThread()) } + +fun Observable.subscribeOnIO(): Observable { + return this.subscribeOn(Schedulers.io()) +} + +fun Observable.observeOnMain(): Observable { + return this.observeOn(AndroidSchedulers.mainThread()) +} diff --git a/app/src/main/java/com/treyherman/employeedirectory/persistence/EmployeeDirectoryDatabase.kt b/app/src/main/java/com/treyherman/employeedirectory/persistence/EmployeeDirectoryDatabase.kt new file mode 100644 index 0000000..79a5ddf --- /dev/null +++ b/app/src/main/java/com/treyherman/employeedirectory/persistence/EmployeeDirectoryDatabase.kt @@ -0,0 +1,11 @@ +package com.treyherman.employeedirectory.persistence + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.treyherman.employeedirectory.persistence.dao.EmployeeDao +import com.treyherman.employeedirectory.persistence.model.EmployeeEntity + +@Database(entities = [EmployeeEntity::class], version = 1) +abstract class EmployeeDirectoryDatabase : RoomDatabase() { + abstract fun employeeDao(): EmployeeDao +} \ No newline at end of file diff --git a/app/src/main/java/com/treyherman/employeedirectory/persistence/dao/EmployeeDao.kt b/app/src/main/java/com/treyherman/employeedirectory/persistence/dao/EmployeeDao.kt new file mode 100644 index 0000000..1cbe339 --- /dev/null +++ b/app/src/main/java/com/treyherman/employeedirectory/persistence/dao/EmployeeDao.kt @@ -0,0 +1,19 @@ +package com.treyherman.employeedirectory.persistence.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.treyherman.employeedirectory.persistence.model.EmployeeEntity +import io.reactivex.Completable +import io.reactivex.Observable + +@Dao +interface EmployeeDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertEmployeesCompletable(employees: List): Completable + + @Query("SELECT * FROM EmployeeEntity") + fun localEmployeesStream(): Observable> +} \ No newline at end of file diff --git a/app/src/main/java/com/treyherman/employeedirectory/persistence/model/EmployeeEntity.kt b/app/src/main/java/com/treyherman/employeedirectory/persistence/model/EmployeeEntity.kt new file mode 100644 index 0000000..d94d036 --- /dev/null +++ b/app/src/main/java/com/treyherman/employeedirectory/persistence/model/EmployeeEntity.kt @@ -0,0 +1,17 @@ +package com.treyherman.employeedirectory.persistence.model + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity +data class EmployeeEntity( + @PrimaryKey val uuid: String, + val fullName: String, + val phoneNumber: String?, + val emailAddress: String, + val biography: String?, + val photoUrlSmall: String?, + val photoUrlLarge: String?, + val team: String, + val employeeType: String +) diff --git a/app/src/main/java/com/treyherman/employeedirectory/rest/model/response/employee/EmployeeResponse.kt b/app/src/main/java/com/treyherman/employeedirectory/rest/model/response/employee/EmployeeResponse.kt index 158b774..7ca4e21 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/rest/model/response/employee/EmployeeResponse.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/rest/model/response/employee/EmployeeResponse.kt @@ -9,7 +9,7 @@ data class EmployeeResponse( val photoUrlSmall: String?, val photoUrlLarge: String?, val team: String, - private val employeeType: String + val employeeType: String ) { val type get() = Type.enumValueFromString(employeeType) diff --git a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenter.kt b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenter.kt index 45a4ae2..e94e6de 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenter.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenter.kt @@ -6,14 +6,20 @@ import com.treyherman.employeedirectory.R import com.treyherman.employeedirectory.di.scope.ActivityScope import com.treyherman.employeedirectory.extension.observeOnMain import com.treyherman.employeedirectory.extension.subscribeOnComputation +import com.treyherman.employeedirectory.persistence.dao.EmployeeDao +import com.treyherman.employeedirectory.rest.model.response.employee.EmployeeResponseWrapper import com.treyherman.employeedirectory.rest.service.EmployeeApiService import com.treyherman.employeedirectory.scenes.maindirectory.diff.EmployeeDiffCallback import com.treyherman.employeedirectory.scenes.maindirectory.mapper.EmployeeModelMapper import com.treyherman.employeedirectory.scenes.maindirectory.model.DataSelectionType import com.treyherman.employeedirectory.scenes.maindirectory.model.UIEmployee import io.reactivex.Single +import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable +import io.reactivex.observers.DisposableCompletableObserver +import io.reactivex.observers.DisposableObserver import io.reactivex.observers.DisposableSingleObserver +import io.reactivex.rxkotlin.addTo import javax.inject.Inject @@ -22,25 +28,41 @@ class MainDirectoryPresenter @Inject constructor( private val view: MainDirectoryMvp.View, private val resources: Resources, private val employeeApiService: EmployeeApiService, - private val employeeModelMapper: EmployeeModelMapper + private val employeeModelMapper: EmployeeModelMapper, + private val employeeDao: EmployeeDao ) : MainDirectoryMvp.Presenter { + private val disposables = CompositeDisposable() + private var employeesDisposable: Disposable? = null override fun onCreate() { view.displayLoading() - employeesDisposable?.dispose() - employeesDisposable = defaultEmployeesOnce - .observeOnMain() - .subscribeWith(employeeObserver) + employeeDao.localEmployeesStream() + .doOnNext { + if (it.isEmpty()) { + currentEmployeeOnce(DataSelectionType.DEFAULT).subscribe({}, {}) + .addTo(disposables) + } + } + .map { employeeModelMapper.mapUIEmployees(it) } + .subscribeWith(object : DisposableObserver>() { + override fun onComplete() {} + + override fun onNext(employees: List) { + view.hideLoading() + view.displayEmployees(employees) + } + + override fun onError(e: Throwable) { + view.hideLoading() + view.displayEmptyContent(resources.getString(R.string.something_went_wrong)) + } + }).addTo(disposables) } override fun onRefresh(dataSelection: DataSelectionType, currentEmployees: List) { - when (dataSelection) { - DataSelectionType.DEFAULT -> subscribeToRefreshedDefaultEmployees(currentEmployees) - DataSelectionType.MALFORMED -> subscribeToRefreshedMalformedEmployees(currentEmployees) - DataSelectionType.EMPTY -> subscribeToRefreshedEmptyEmployees(currentEmployees) - } + currentEmployeeOnce(dataSelection).subscribe({}, {}).addTo(disposables) } override fun onDestroy() { @@ -52,11 +74,7 @@ class MainDirectoryPresenter @Inject constructor( currentEmployees: List ) { view.displayLoading() - when (dataSelection) { - DataSelectionType.DEFAULT -> subscribeToRefreshedDefaultEmployees(currentEmployees) - DataSelectionType.MALFORMED -> subscribeToRefreshedMalformedEmployees(currentEmployees) - DataSelectionType.EMPTY -> subscribeToRefreshedEmptyEmployees(currentEmployees) - } + currentEmployeeOnce(dataSelection).subscribe({}, {}).addTo(disposables) } override fun onDataTypeSelected( @@ -64,37 +82,40 @@ class MainDirectoryPresenter @Inject constructor( currentEmployees: List ) { view.displayLoading() - when (dataSelection) { - DataSelectionType.DEFAULT -> subscribeToRefreshedDefaultEmployees(currentEmployees) - DataSelectionType.MALFORMED -> subscribeToRefreshedMalformedEmployees(currentEmployees) - DataSelectionType.EMPTY -> subscribeToRefreshedEmptyEmployees(currentEmployees) - } + currentEmployeeOnce(dataSelection).subscribe({}, {}).addTo(disposables) } // region private - private fun subscribeToRefreshedDefaultEmployees(currentEmployees: List) { - employeesDisposable?.dispose() - employeesDisposable = defaultEmployeesOnce - .flatMap { calculateEmployeeDiffOnce(currentEmployees, it) } - .observeOnMain() - .subscribeWith(employeesDiffResultObserver) - } - - private fun subscribeToRefreshedMalformedEmployees(currentEmployees: List) { - employeesDisposable?.dispose() - employeesDisposable = malformedEmployeesOnce - .flatMap { calculateEmployeeDiffOnce(currentEmployees, it) } - .observeOnMain() - .subscribeWith(employeesDiffResultObserver) - } - - private fun subscribeToRefreshedEmptyEmployees(currentEmployees: List) { - employeesDisposable?.dispose() - employeesDisposable = emptyEmployeesOnce - .flatMap { calculateEmployeeDiffOnce(currentEmployees, it) } - .observeOnMain() - .subscribeWith(employeesDiffResultObserver) - } +// private fun subscribeToRefreshedDefaultEmployees(currentEmployees: List) { +// employeesDisposable?.dispose() +// employeesDisposable = defaultEmployeesOnce +// .flatMap { calculateEmployeeDiffOnce(currentEmployees, it) } +// .observeOnMain() +// .subscribeWith(employeesDiffResultObserver) +// } +// +// private fun subscribeToRefreshedMalformedEmployees(currentEmployees: List) { +// employeesDisposable?.dispose() +// employeesDisposable = +// malformedEmployeesOnce.subscribeWith(object : DisposableCompletableObserver() { +// override fun onComplete() { +// view.hideLoading() +// } +// +// override fun onError(e: Throwable) { +// view.hideLoading() +// view.displayEmptyContent() +// } +// }) +// } +// +// private fun subscribeToRefreshedEmptyEmployees(currentEmployees: List) { +// employeesDisposable?.dispose() +// employeesDisposable = emptyEmployeesOnce +// .flatMap { calculateEmployeeDiffOnce(currentEmployees, it) } +// .observeOnMain() +// .subscribeWith(employeesDiffResultObserver) +// } private fun calculateEmployeeDiffOnce( oldEmployees: List, @@ -109,48 +130,65 @@ class MainDirectoryPresenter @Inject constructor( }.subscribeOnComputation() } - private val defaultEmployeesOnce - get() = employeeApiService.employeesOnce() - .map { employeeModelMapper.mapEmployees(it) } - - private val malformedEmployeesOnce - get() = employeeApiService.malformedEmployeesOnce() - .map { employeeModelMapper.mapEmployees(it) } - - private val emptyEmployeesOnce - get() = employeeApiService.emptyEmployeesOnce() - .map { employeeModelMapper.mapEmployees(it) } - - private val employeeObserver - get() = object : DisposableSingleObserver>() { - override fun onSuccess(employees: List) { - view.hideLoading() - when (employees.isNotEmpty()) { - true -> view.displayEmployees(employees) - false -> view.displayEmptyContent(resources.getString(R.string.no_employees_found)) - } - } - - override fun onError(e: Throwable) { - view.hideLoading() - view.displayEmptyContent(resources.getString(R.string.something_went_wrong)) - } + private fun currentEmployeeOnce(selectionType: DataSelectionType): Single { + return when (selectionType) { + DataSelectionType.DEFAULT -> employeeApiService.employeesOnce() + DataSelectionType.MALFORMED -> employeeApiService.malformedEmployeesOnce() + DataSelectionType.EMPTY -> employeeApiService.emptyEmployeesOnce() } + } - private val employeesDiffResultObserver - get() = object : DisposableSingleObserver, DiffUtil.DiffResult>>() { - override fun onSuccess(employeeDiffPair: Pair, DiffUtil.DiffResult>) { - view.hideLoading() - when (employeeDiffPair.first.isNotEmpty()) { - true -> view.updateEmployees(employeeDiffPair.first, employeeDiffPair.second) - false -> view.displayEmptyContent(resources.getString(R.string.no_employees_found)) - } - } - - override fun onError(e: Throwable) { - view.hideLoading() - view.displayEmptyContent(resources.getString(R.string.something_went_wrong)) - } - } +// private val defaultEmployeesOnce +// get() = employeeApiService.employeesOnce() +// .flatMapCompletable { +// val entities = employeeModelMapper.mapEmployeeEntities(it) +// employeeDao.insertEmployeesCompletable(entities) +// } +// +// private val malformedEmployeesOnce +// get() = employeeApiService.malformedEmployeesOnce() +// .flatMapCompletable { +// val entities = employeeModelMapper.mapEmployeeEntities(it) +// employeeDao.insertEmployeesCompletable(entities) +// } +// +// private val emptyEmployeesOnce +// get() = employeeApiService.emptyEmployeesOnce() +// .flatMapCompletable { +// val entities = employeeModelMapper.mapEmployeeEntities(it) +// employeeDao.insertEmployeesCompletable(entities) +// } +// +// private val employeeObserver +// get() = object : DisposableSingleObserver>() { +// override fun onSuccess(employees: List) { +// view.hideLoading() +// when (employees.isNotEmpty()) { +// true -> view.displayEmployees(employees) +// false -> view.displayEmptyContent(resources.getString(R.string.no_employees_found)) +// } +// } +// +// override fun onError(e: Throwable) { +// view.hideLoading() +// view.displayEmptyContent(resources.getString(R.string.something_went_wrong)) +// } +// } +// +// private val employeesDiffResultObserver +// get() = object : DisposableSingleObserver, DiffUtil.DiffResult>>() { +// override fun onSuccess(employeeDiffPair: Pair, DiffUtil.DiffResult>) { +// view.hideLoading() +// when (employeeDiffPair.first.isNotEmpty()) { +// true -> view.updateEmployees(employeeDiffPair.first, employeeDiffPair.second) +// false -> view.displayEmptyContent(resources.getString(R.string.no_employees_found)) +// } +// } +// +// override fun onError(e: Throwable) { +// view.hideLoading() +// view.displayEmptyContent(resources.getString(R.string.something_went_wrong)) +// } +// } // endregion private } diff --git a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapper.kt b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapper.kt index dc6d820..9f850bf 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapper.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapper.kt @@ -1,8 +1,11 @@ package com.treyherman.employeedirectory.scenes.maindirectory.mapper +import com.treyherman.employeedirectory.persistence.model.EmployeeEntity import com.treyherman.employeedirectory.rest.model.response.employee.EmployeeResponseWrapper import com.treyherman.employeedirectory.scenes.maindirectory.model.UIEmployee interface EmployeeModelMapper { - fun mapEmployees(responseWrapper: EmployeeResponseWrapper): List + fun mapEmployeeEntities(responseWrapper: EmployeeResponseWrapper): List + + fun mapUIEmployees(employeeEntities: List): List } diff --git a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperImpl.kt b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperImpl.kt index c18d77f..5c8d1cf 100644 --- a/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperImpl.kt +++ b/app/src/main/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperImpl.kt @@ -1,35 +1,50 @@ package com.treyherman.employeedirectory.scenes.maindirectory.mapper import android.content.res.Resources -import android.telephony.PhoneNumberUtils import com.treyherman.employeedirectory.R import com.treyherman.employeedirectory.manager.phonenumber.PhoneNumberFormatManager +import com.treyherman.employeedirectory.persistence.model.EmployeeEntity import com.treyherman.employeedirectory.rest.model.response.employee.EmployeeResponse import com.treyherman.employeedirectory.rest.model.response.employee.EmployeeResponseWrapper import com.treyherman.employeedirectory.scenes.maindirectory.model.UIEmployee -import java.util.* import javax.inject.Inject class EmployeeModelMapperImpl @Inject constructor( private val resources: Resources, private val phoneNumberFormatManager: PhoneNumberFormatManager ) : EmployeeModelMapper { - override fun mapEmployees(responseWrapper: EmployeeResponseWrapper): List { - return responseWrapper.employees.map { mapEmployee(it) } + override fun mapEmployeeEntities(responseWrapper: EmployeeResponseWrapper): List { + return responseWrapper.employees.map { + EmployeeEntity( + it.uuid, + it.fullName, + it.phoneNumber, + it.emailAddress, + it.biography, + it.photoUrlSmall, + it.photoUrlLarge, + it.team, + it.employeeType + ) + } + } + + override fun mapUIEmployees(employeeEntities: List): List { + return employeeEntities.map { mapEmployee(it) } } // region private - private fun mapEmployee(response: EmployeeResponse): UIEmployee { + private fun mapEmployee(entity: EmployeeEntity): UIEmployee { val nameAndTeam = - resources.getString(R.string.formatted_name_and_team, response.fullName, response.team) + resources.getString(R.string.formatted_name_and_team, entity.fullName, entity.team) return UIEmployee( - response.uuid, + entity.uuid, nameAndTeam, - phoneNumberFormatManager.formatPhoneNumber(response.phoneNumber), - response.emailAddress, - response.biography, - response.photoUrlSmall, - mapEmployeeClassificationText(response.type) + phoneNumberFormatManager.formatPhoneNumber(entity.phoneNumber), + entity.emailAddress, + entity.biography, + entity.photoUrlSmall, + mapEmployeeClassificationText(EmployeeResponse.Type.valueOf(entity.employeeType)) ) } diff --git a/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenterTest.kt b/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenterTest.kt index 75574da..ce41754 100644 --- a/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenterTest.kt +++ b/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/MainDirectoryPresenterTest.kt @@ -46,10 +46,10 @@ class MainDirectoryPresenterTest { val mockResponseWrapper = EmployeeResponseWrapper(listOf(mockEmployeeResponse())) whenever(employeeApiService.employeesOnce()).thenReturn(Single.just(mockResponseWrapper)) val mockUIEmployees = listOf(mockUIEmployee()) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) presenter.onCreate() - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).employeesOnce() verify(view).displayLoading() verify(view).hideLoading() @@ -62,10 +62,10 @@ class MainDirectoryPresenterTest { fun onCreate_defaultEmployeesOnceWithEmptyEmployeesSuccess_displayEmptyContent() { val mockResponseWrapper = EmployeeResponseWrapper(emptyList()) whenever(employeeApiService.employeesOnce()).thenReturn(Single.just(mockResponseWrapper)) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(emptyList()) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(emptyList()) presenter.onCreate() - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).employeesOnce() verify(view).displayLoading() verify(view).hideLoading() @@ -103,10 +103,10 @@ class MainDirectoryPresenterTest { val mockResponseWrapper = EmployeeResponseWrapper(listOf(mockEmployeeResponse())) whenever(employeeApiService.employeesOnce()).thenReturn(Single.just(mockResponseWrapper)) val mockUIEmployees = listOf(mockUIEmployee()) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) presenter.onRefresh(DataSelectionType.DEFAULT, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).employeesOnce() verify(view).hideLoading() verify(view).updateEmployees(eq(mockUIEmployees), any()) @@ -131,10 +131,10 @@ class MainDirectoryPresenterTest { fun onRefresh_emptyEmployeesOnceWithSuccess_displayEmptyContent() { val mockResponseWrapper = EmployeeResponseWrapper(emptyList()) whenever(employeeApiService.emptyEmployeesOnce()).thenReturn(Single.just(mockResponseWrapper)) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(emptyList()) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(emptyList()) presenter.onRefresh(DataSelectionType.EMPTY, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).emptyEmployeesOnce() verify(view).hideLoading() verify(view).displayEmptyContent(NO_EMPLOYEES_FOUND) @@ -148,10 +148,10 @@ class MainDirectoryPresenterTest { val mockResponseWrapper = EmployeeResponseWrapper(listOf(mockEmployeeResponse())) whenever(employeeApiService.employeesOnce()).thenReturn(Single.just(mockResponseWrapper)) val mockUIEmployees = listOf(mockUIEmployee()) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) presenter.onTryAgainClicked(DataSelectionType.DEFAULT, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).employeesOnce() verify(view).displayLoading() verify(view).hideLoading() @@ -178,10 +178,10 @@ class MainDirectoryPresenterTest { fun onTryAgainClicked_emptyEmployeesOnceWithSuccess_displayEmptyContent() { val mockResponseWrapper = EmployeeResponseWrapper(emptyList()) whenever(employeeApiService.emptyEmployeesOnce()).thenReturn(Single.just(mockResponseWrapper)) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(emptyList()) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(emptyList()) presenter.onTryAgainClicked(DataSelectionType.EMPTY, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).emptyEmployeesOnce() verify(view).displayLoading() verify(view).hideLoading() @@ -196,10 +196,10 @@ class MainDirectoryPresenterTest { val mockResponseWrapper = EmployeeResponseWrapper(listOf(mockEmployeeResponse())) whenever(employeeApiService.employeesOnce()).thenReturn(Single.just(mockResponseWrapper)) val mockUIEmployees = listOf(mockUIEmployee()) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(mockUIEmployees) presenter.onDataTypeSelected(DataSelectionType.DEFAULT, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).employeesOnce() verify(view).displayLoading() verify(view).hideLoading() @@ -226,10 +226,10 @@ class MainDirectoryPresenterTest { fun onDataTypeSelected_emptyEmployeesOnceWithSuccess_displayEmptyContent() { val mockResponseWrapper = EmployeeResponseWrapper(emptyList()) whenever(employeeApiService.emptyEmployeesOnce()).thenReturn(Single.just(mockResponseWrapper)) - whenever(employeeModelMapper.mapEmployees(mockResponseWrapper)).thenReturn(emptyList()) + whenever(employeeModelMapper.mapUIEmployees(mockResponseWrapper)).thenReturn(emptyList()) presenter.onDataTypeSelected(DataSelectionType.EMPTY, emptyList()) - verify(employeeModelMapper).mapEmployees(mockResponseWrapper) + verify(employeeModelMapper).mapUIEmployees(mockResponseWrapper) verify(employeeApiService).emptyEmployeesOnce() verify(view).displayLoading() verify(view).hideLoading() diff --git a/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperTest.kt b/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperTest.kt index e63b870..f9f27fd 100644 --- a/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperTest.kt +++ b/app/src/test/java/com/treyherman/employeedirectory/scenes/maindirectory/mapper/EmployeeModelMapperTest.kt @@ -80,7 +80,7 @@ class EmployeeModelMapperTest { @Test fun mapEmployees_result() { - val employees = employeeModelMapper.mapEmployees(employeesResponseWrapper) + val employees = employeeModelMapper.mapUIEmployees(employeesResponseWrapper) assertEquals(employees.size, employeesResponseWrapper.employees.size) employees.forEachIndexed { index, employee -> diff --git a/build.gradle b/build.gradle index e79b575..55098e2 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,7 @@ allprojects { mockitoVersion = '2.8.9' mockitoKotlinVersion = '1.5.0' powerMockVersion = '2.0.2' + roomVersion = '2.2.5' } }