mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-30 14:23:55 +01:00
With lazy loading of contributions (#3566)
This commit is contained in:
parent
c216fdf0d4
commit
d863a404f1
34 changed files with 1397 additions and 928 deletions
|
|
@ -0,0 +1,139 @@
|
|||
package fr.free.nrw.commons.contributions
|
||||
|
||||
import android.content.Context
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import fr.free.nrw.commons.utils.NetworkUtilsTest
|
||||
import fr.free.nrw.commons.utils.createMockDataSourceFactory
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import io.reactivex.schedulers.TestScheduler
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.*
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import java.lang.RuntimeException
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* The unit test class for ContributionBoundaryCallbackTest
|
||||
*/
|
||||
class ContributionBoundaryCallbackTest {
|
||||
@Mock
|
||||
internal lateinit var repository: ContributionsRepository
|
||||
|
||||
@Mock
|
||||
internal lateinit var sessionManager: SessionManager
|
||||
|
||||
@Mock
|
||||
internal lateinit var mediaClient: MediaClient
|
||||
|
||||
private lateinit var contributionBoundaryCallback: ContributionBoundaryCallback
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
lateinit var scheduler: Scheduler
|
||||
|
||||
/**
|
||||
* initial setup
|
||||
*/
|
||||
@Before
|
||||
@Throws(Exception::class)
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
scheduler = Schedulers.trampoline()
|
||||
contributionBoundaryCallback =
|
||||
ContributionBoundaryCallback(repository, sessionManager, mediaClient, scheduler);
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnZeroItemsLoaded() {
|
||||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(true)
|
||||
contributionBoundaryCallback.onZeroItemsLoaded()
|
||||
verify(repository).save(anyList<Contribution>());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnLastItemLoaded() {
|
||||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(true)
|
||||
contributionBoundaryCallback.onItemAtEndLoaded(mock(Contribution::class.java))
|
||||
verify(repository).save(anyList());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnFrontItemLoaded() {
|
||||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(true)
|
||||
contributionBoundaryCallback.onItemAtFrontLoaded(mock(Contribution::class.java))
|
||||
verify(repository).save(anyList());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFetchContributions() {
|
||||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(true)
|
||||
contributionBoundaryCallback.fetchContributions()
|
||||
verify(repository).save(anyList());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFetchContributionsForEndOfList() {
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(false)
|
||||
contributionBoundaryCallback.fetchContributions()
|
||||
verify(mediaClient, times(0)).getMediaListForUser(anyString())
|
||||
verifyNoMoreInteractions(repository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFetchContributionsFailed() {
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.doesMediaListForUserHaveMorePages(anyString()))
|
||||
.thenReturn(true)
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(Single.error(Exception("Error")))
|
||||
contributionBoundaryCallback.fetchContributions()
|
||||
verifyZeroInteractions(repository);
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package fr.free.nrw.commons.contributions
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.nhaarman.mockitokotlin2.times
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
/**
|
||||
* The unit test class for ContributionsListPresenterTest
|
||||
*/
|
||||
class ContributionsListPresenterTest {
|
||||
@Mock
|
||||
internal lateinit var contributionBoundaryCallback: ContributionBoundaryCallback
|
||||
|
||||
@Mock
|
||||
internal lateinit var repository: ContributionsRepository
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
lateinit var scheduler: Scheduler
|
||||
|
||||
lateinit var contributionsListPresenter: ContributionsListPresenter
|
||||
|
||||
/**
|
||||
* initial setup
|
||||
*/
|
||||
@Before
|
||||
@Throws(Exception::class)
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
scheduler = Schedulers.trampoline()
|
||||
contributionsListPresenter =
|
||||
ContributionsListPresenter(contributionBoundaryCallback, repository, scheduler);
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDeleteUpload() {
|
||||
whenever(repository.deleteContributionFromDB(any<Contribution>()))
|
||||
.thenReturn(Completable.complete())
|
||||
contributionsListPresenter.deleteUpload(mock(Contribution::class.java))
|
||||
verify(repository, times(1))
|
||||
.deleteContributionFromDB(ArgumentMatchers.any(Contribution::class.java));
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,11 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.loader.content.CursorLoader
|
||||
import androidx.loader.content.Loader
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.TestScheduler
|
||||
|
|
@ -17,9 +19,11 @@ import org.junit.Before
|
|||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.ArgumentMatchers.*
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.MockitoAnnotations
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* The unit test class for ContributionsPresenter
|
||||
|
|
@ -42,7 +46,7 @@ class ContributionsPresenterTest {
|
|||
|
||||
@Rule @JvmField var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
lateinit var scheduler : Scheduler
|
||||
lateinit var scheduler : TestScheduler
|
||||
|
||||
/**
|
||||
* initial setup
|
||||
|
|
@ -60,23 +64,13 @@ class ContributionsPresenterTest {
|
|||
liveData=MutableLiveData()
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch contributions
|
||||
*/
|
||||
@Test
|
||||
fun testFetchContributions(){
|
||||
whenever(repository.getString(ArgumentMatchers.anyString())).thenReturn("10")
|
||||
whenever(repository.fetchContributions()).thenReturn(liveData)
|
||||
contributionsPresenter.fetchContributions()
|
||||
verify(repository).fetchContributions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Test presenter actions onDeleteContribution
|
||||
*/
|
||||
@Test
|
||||
fun testDeleteContribution() {
|
||||
whenever(repository.deleteContributionFromDB(ArgumentMatchers.any(Contribution::class.java))).thenReturn(Single.just(1))
|
||||
whenever(repository.deleteContributionFromDB(ArgumentMatchers.any<Contribution>()))
|
||||
.thenReturn(Completable.complete())
|
||||
contributionsPresenter.deleteUpload(contribution)
|
||||
verify(repository).deleteContributionFromDB(contribution)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package fr.free.nrw.commons.contributions
|
||||
|
||||
import com.nhaarman.mockitokotlin2.times
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.utils.createMockDataSourceFactory
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.Single
|
||||
import junit.framework.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.*
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.mock
|
||||
|
||||
/**
|
||||
* The unit test class for ContributionsRepositoryTest
|
||||
*/
|
||||
class ContributionsRepositoryTest {
|
||||
@Mock
|
||||
internal lateinit var localDataSource: ContributionsLocalDataSource
|
||||
|
||||
@InjectMocks
|
||||
private lateinit var contributionsRepository: ContributionsRepository
|
||||
|
||||
lateinit var scheduler: Scheduler
|
||||
|
||||
/**
|
||||
* initial setup
|
||||
*/
|
||||
@Before
|
||||
@Throws(Exception::class)
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFetchContributions() {
|
||||
val contribution = mock(Contribution::class.java)
|
||||
whenever(localDataSource.getContributions())
|
||||
.thenReturn(createMockDataSourceFactory(listOf(contribution)))
|
||||
val contributionsFactory = contributionsRepository.fetchContributions()
|
||||
verify(localDataSource, times(1)).getContributions();
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSaveContribution() {
|
||||
val contributions = listOf(mock(Contribution::class.java))
|
||||
whenever(localDataSource.saveContributions(ArgumentMatchers.anyList()))
|
||||
.thenReturn(Single.just(listOf(1L)))
|
||||
val save = contributionsRepository.save(contributions).test().assertValueAt(0) {
|
||||
it.size == 1 && it.get(0) == 1L
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue