Skip to content
Permalink
Browse files

Update data-android test to use Dagger graph

Currently on FollowedShowsRepository uses it,
but the other tests will be converted later
  • Loading branch information...
chrisbanes committed Sep 29, 2019
1 parent b7497a0 commit 31f6486fa744f7b5d0222e9c025cdf537bed846d
@@ -26,6 +26,7 @@ import app.tivi.showdetails.ShowDetailsBuilder
import app.tivi.tasks.inject.TasksModule
import app.tivi.tmdb.TmdbModule
import app.tivi.trakt.TraktAuthModule
import app.tivi.trakt.TraktModule
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjector
@@ -42,6 +43,7 @@ import javax.inject.Singleton
DataModule::class,
HomeBuilder::class,
ShowDetailsBuilder::class,
TraktModule::class,
TraktAuthModule::class,
TmdbModule::class,
NetworkModule::class,
@@ -86,6 +86,7 @@ dependencies {
testImplementation Libs.AndroidX.Room.testing
testImplementation Libs.Coroutines.test
kaptTest Libs.AndroidX.Room.compiler
kaptTest Libs.Dagger.compiler

// Needed for Tzdb
testImplementation Libs.threeTenBp
@@ -1,5 +1,5 @@
/*
* Copyright 2017 Google LLC
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,12 +19,21 @@ package app.tivi.data
import androidx.room.Room
import android.content.Context
import android.os.Debug
import app.tivi.data.daos.EntityInserter
import dagger.Binds
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module(includes = [DatabaseModuleBinds::class])
class DatabaseModule {
@Module(includes = [
RoomDatabaseModule::class,
DatabaseModuleBinds::class,
DatabaseDaoModule::class
])
class DatabaseModule

@Module
class RoomDatabaseModule {
@Singleton
@Provides
fun provideDatabase(context: Context): TiviRoomDatabase {
@@ -36,7 +45,10 @@ class DatabaseModule {
}
return builder.build()
}
}

@Module
class DatabaseDaoModule {
@Provides
fun provideTiviShowDao(db: TiviDatabase) = db.showDao()

@@ -78,4 +90,18 @@ class DatabaseModule {

@Provides
fun provideRecommendedShowsDao(db: TiviDatabase) = db.recommendedShowsDao()
}

@Module
abstract class DatabaseModuleBinds {
@Binds
abstract fun bindTiviDatabase(context: TiviRoomDatabase): TiviDatabase

@Singleton
@Binds
abstract fun provideDatabaseTransactionRunner(runner: RoomTransactionRunner): DatabaseTransactionRunner

@Singleton
@Binds
abstract fun provideEntityInserter(inserter: TiviEntityInserter): EntityInserter
}
@@ -0,0 +1,137 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.tivi.data

import android.content.Context
import androidx.room.Room
import app.tivi.data.daos.EntityInserter
import app.tivi.data.entities.Success
import app.tivi.data.entities.TiviShow
import app.tivi.data.repositories.FollowedShowRepositoryTest
import app.tivi.data.repositories.SeasonsEpisodesRepositoryTest
import app.tivi.data.repositories.episodes.EpisodeDataSource
import app.tivi.data.repositories.episodes.TraktSeasonsEpisodesDataSource
import app.tivi.data.repositories.followedshows.TraktFollowedShowsDataSource
import app.tivi.data.repositories.shows.ShowDataSource
import app.tivi.inject.Trakt
import app.tivi.trakt.TraktAuthState
import app.tivi.trakt.TraktServiceModule
import app.tivi.util.Logger
import app.tivi.utils.TestTransactionRunner
import app.tivi.utils.TiviTestDatabase
import com.uwetrottmann.tmdb2.Tmdb
import com.uwetrottmann.trakt5.TraktV2
import dagger.Binds
import dagger.Component
import dagger.Module
import dagger.Provides
import io.mockk.coEvery
import io.mockk.mockk
import javax.inject.Singleton

@Singleton
@Component(modules = [
TestDataSourceModule::class,
TestDatabaseModule::class,
TestContextModule::class
])
interface TestComponent {
fun inject(test: SeasonsEpisodesRepositoryTest)
fun inject(test: FollowedShowRepositoryTest)
}

@Module
class TestContextModule(private val context: Context) {
@Provides
fun provideContext(): Context = context
}

@Module
class TestDataSourceModule(
private val traktFollowedShowsDataSource: TraktFollowedShowsDataSource = mockk(),
private val traktEpisodeDataSource: EpisodeDataSource = mockk(),
private val tmdbEpisodeDataSource: EpisodeDataSource = mockk(),
private val seasonsDataSource: TraktSeasonsEpisodesDataSource = mockk(),
private val traktShowDataSource: ShowDataSource = mockk(),
private val tmdbShowDataSource: ShowDataSource = mockk()
) {
@Provides
fun provideTraktFollowedShowsDataSource() = traktFollowedShowsDataSource

@Provides
@Trakt
fun provideTraktEpisodeDataSource() = traktEpisodeDataSource

@Provides
@app.tivi.inject.Tmdb
fun provideTmdbEpisodeDataSource() = tmdbEpisodeDataSource

@Provides
@Trakt
fun provideTraktSeasonsEpisodesDataSource() = seasonsDataSource

@Provides
@Trakt
fun provideTraktShowDataSource(): ShowDataSource = traktShowDataSource

@Provides
@app.tivi.inject.Tmdb
fun provideTmdbShowDataSource(): ShowDataSource = tmdbShowDataSource
}

@Module(includes = [
TestRoomDatabaseModule::class,
TestDatabaseModuleBinds::class,
DatabaseDaoModule::class,
TraktServiceModule::class
])
class TestDatabaseModule {
@Provides
fun provideTrakt(): TraktV2 = TraktV2("fakefakefake")

@Provides
fun provideTmdb(): Tmdb = Tmdb("fakefakefake")

@Provides
fun provideTraktAuthState() = TraktAuthState.LOGGED_IN
}

@Module
class TestRoomDatabaseModule {
@Singleton
@Provides
fun provideDatabase(context: Context): TiviDatabase {
return Room.inMemoryDatabaseBuilder(context, TiviTestDatabase::class.java)
.allowMainThreadQueries()
.build()
}

@Singleton
@Provides
fun provideDatabaseTransactionRunner(): DatabaseTransactionRunner = TestTransactionRunner

@Singleton
@Provides
fun provideLogger(): Logger = mockk(relaxUnitFun = true)
}

@Module
abstract class TestDatabaseModuleBinds {
@Singleton
@Binds
abstract fun provideEntityInserter(inserter: TiviEntityInserter): EntityInserter
}
@@ -16,20 +16,20 @@

package app.tivi.data.repositories

import app.tivi.data.TiviEntityInserter
import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.core.app.ApplicationProvider
import app.tivi.data.DaggerTestComponent
import app.tivi.data.TestContextModule
import app.tivi.data.TestDataSourceModule
import app.tivi.data.TiviDatabase
import app.tivi.data.daos.FollowedShowsDao
import app.tivi.data.entities.ErrorResult
import app.tivi.data.entities.Success
import app.tivi.data.repositories.followedshows.FollowedShowsDataSource
import app.tivi.data.repositories.followedshows.FollowedShowsLastRequestStore
import app.tivi.data.repositories.followedshows.FollowedShowsRepository
import app.tivi.data.repositories.followedshows.FollowedShowsStore
import app.tivi.data.repositories.followedshows.TraktFollowedShowsDataSource
import app.tivi.data.repositories.shows.ShowRepository
import app.tivi.data.repositories.shows.ShowStore
import app.tivi.trakt.TraktAuthState
import app.tivi.util.Logger
import app.tivi.utils.BaseDatabaseTest
import app.tivi.utils.TestTransactionRunner
import app.tivi.utils.SuccessFakeShowDataSource
import app.tivi.utils.followedShow1Local
import app.tivi.utils.followedShow1Network
import app.tivi.utils.followedShow1PendingDelete
@@ -41,49 +41,47 @@ import app.tivi.utils.insertShow
import app.tivi.utils.show
import app.tivi.utils.show2
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.test.runBlockingTest
import org.hamcrest.Matchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Provider

class FollowedShowRepositoryTest : BaseDatabaseTest() {
private lateinit var followShowsDao: FollowedShowsDao

private lateinit var traktDataSource: FollowedShowsDataSource
private lateinit var showRepository: ShowRepository

private lateinit var repository: FollowedShowsRepository

override fun setup() {
super.setup()
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import javax.inject.Inject

@RunWith(RobolectricTestRunner::class)
class FollowedShowRepositoryTest {
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()

@Inject lateinit var followShowsDao: FollowedShowsDao
@Inject lateinit var showRepository: ShowRepository
@Inject lateinit var repository: FollowedShowsRepository
@Inject lateinit var database: TiviDatabase
@Inject lateinit var traktDataSource: TraktFollowedShowsDataSource

@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext<Context>()

val fakeShowDataSource = SuccessFakeShowDataSource()

DaggerTestComponent.builder()
.testContextModule(TestContextModule(context))
.testDataSourceModule(
TestDataSourceModule(
traktShowDataSource = fakeShowDataSource,
tmdbShowDataSource = fakeShowDataSource
)
)
.build()
.inject(this)

runBlockingTest {
// We'll assume that there's a show in the db
insertShow(db)

followShowsDao = db.followedShowsDao()

showRepository = mockk(relaxUnitFun = true)
coEvery { showRepository.needsUpdate(any()) } returns true
coEvery { showRepository.needsInitialUpdate(any()) } returns true
coEvery { showRepository.needsImagesUpdate(any(), any()) } returns true

val logger = mockk<Logger>(relaxUnitFun = true)
val txRunner = TestTransactionRunner
val entityInserter = TiviEntityInserter(txRunner, logger)
traktDataSource = mockk()

repository = FollowedShowsRepository(
FollowedShowsStore(txRunner, entityInserter, db.followedShowsDao(), logger),
FollowedShowsLastRequestStore(db.lastRequestDao()),
ShowStore(entityInserter, db.showDao(), db.showFtsDao(), db.showImagesDao(), txRunner),
traktDataSource,
showRepository,
Provider { TraktAuthState.LOGGED_IN },
logger
)
insertShow(database)
}
}

@@ -94,31 +92,34 @@ class FollowedShowRepositoryTest : BaseDatabaseTest() {

repository.syncFollowedShows()

assertThat(repository.getFollowedShows(), `is`(listOf(followedShow1Local)))
assertThat(repository.getFollowedShows(),
`is`(listOf(followedShow1Local)))
}

@Test
fun testSync_emptyResponse() = runBlockingTest {
insertFollowedShow(db)
insertFollowedShow(database)

coEvery { traktDataSource.getFollowedListId() } returns Success(0)
coEvery { traktDataSource.getListShows(0) } returns Success(emptyList())

repository.syncFollowedShows()

assertThat(repository.getFollowedShows(), `is`(emptyList()))
assertThat(repository.getFollowedShows(),
`is`(emptyList()))
}

@Test
fun testSync_responseDifferentShow() = runBlockingTest {
insertFollowedShow(db)
insertFollowedShow(database)

coEvery { traktDataSource.getFollowedListId() } returns Success(0)
coEvery { traktDataSource.getListShows(0) } returns Success(listOf(followedShow2Network to show2))

repository.syncFollowedShows()

assertThat(repository.getFollowedShows(), `is`(listOf(followedShow2Local)))
assertThat(repository.getFollowedShows(),
`is`(listOf(followedShow2Local)))
}

@Test
@@ -130,7 +131,8 @@ class FollowedShowRepositoryTest : BaseDatabaseTest() {

repository.syncFollowedShows()

assertThat(repository.getFollowedShows(), `is`(emptyList()))
assertThat(repository.getFollowedShows(),
`is`(emptyList()))
}

@Test
@@ -142,6 +144,7 @@ class FollowedShowRepositoryTest : BaseDatabaseTest() {

repository.syncFollowedShows()

assertThat(repository.getFollowedShows(), `is`(listOf(followedShow1Local)))
assertThat(repository.getFollowedShows(),
`is`(listOf(followedShow1Local)))
}
}

0 comments on commit 31f6486

Please sign in to comment.
You can’t perform that action at this time.