#3772 Convert SearchImagesFragment to use Pagination (#3779)

This commit is contained in:
Seán Mac Gillicuddy 2020-06-16 14:58:48 +01:00 committed by GitHub
parent e4190f3f7d
commit c77ed747fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 386 additions and 419 deletions

View file

@ -34,7 +34,7 @@ class BaseSearchPresenterTest {
private var searchResults: PublishProcessor<LiveData<PagedList<String>>> =
PublishProcessor.create()
private var noItemLoadedEvent: PublishProcessor<Unit> = PublishProcessor.create()
private var noItemLoadedQueries: PublishProcessor<String> = PublishProcessor.create()
@Before
@Throws(Exception::class)
@ -42,8 +42,8 @@ class BaseSearchPresenterTest {
MockitoAnnotations.initMocks(this)
whenever(pageableDataSource.searchResults).thenReturn(searchResults)
whenever(pageableDataSource.loadingStates).thenReturn(loadingStates)
whenever(pageableDataSource.noItemsLoadedEvent)
.thenReturn(noItemLoadedEvent)
whenever(pageableDataSource.noItemsLoadedQueries)
.thenReturn(noItemLoadedQueries)
testScheduler = TestScheduler()
baseSearchPresenter =
object : BaseSearchPresenter<String>(testScheduler, pageableDataSource) {}
@ -60,6 +60,7 @@ class BaseSearchPresenterTest {
@Test
fun `Loading offers a loading list item`() {
onLoadingState(LoadingState.Loading)
verify(view).hideEmptyText()
baseSearchPresenter.listFooterData.test().assertValue(listOf(FooterItem.LoadingItem))
}
@ -74,6 +75,7 @@ class BaseSearchPresenterTest {
@Test
fun `InitialLoad shows initial loader`() {
onLoadingState(LoadingState.InitialLoad)
verify(view).hideEmptyText()
verify(view).showInitialLoadInProgress()
}
@ -81,16 +83,6 @@ class BaseSearchPresenterTest {
fun `Error offers a refresh list item, hides initial loader and shows error with a set text`() {
baseSearchPresenter.onQueryUpdated("test")
onLoadingState(LoadingState.Error)
verify(view).setEmptyViewText("test")
verify(view).showSnackbar()
verify(view).hideInitialLoadProgress()
baseSearchPresenter.listFooterData.test().assertValue(listOf(FooterItem.RefreshItem))
}
@Test
fun `Error offers a refresh list item, hides initial loader and shows error with a unset text`() {
onLoadingState(LoadingState.Error)
verify(view, never()).setEmptyViewText(any())
verify(view).showSnackbar()
verify(view).hideInitialLoadProgress()
baseSearchPresenter.listFooterData.test().assertValue(listOf(FooterItem.RefreshItem))
@ -98,9 +90,8 @@ class BaseSearchPresenterTest {
@Test
fun `no Items event sets empty view text`() {
baseSearchPresenter.onQueryUpdated("test")
noItemLoadedEvent.offer(Unit)
verify(view).setEmptyViewText("test")
noItemLoadedQueries.offer("test")
verify(view).showEmptyText("test")
}
@Test

View file

@ -39,9 +39,9 @@ class PageableDataSourceTest {
fun `onQueryUpdated invokes livedatconverter with no items emitter`() {
val (zeroItemsFuncCaptor, _) = expectNewLiveData()
pageableDataSource.onQueryUpdated("test")
pageableDataSource.noItemsLoadedEvent.test()
pageableDataSource.noItemsLoadedQueries.test()
.also { zeroItemsFuncCaptor.firstValue.invoke() }
.assertValue(Unit)
.assertValue("test")
}
/*

View file

@ -0,0 +1,71 @@
package fr.free.nrw.commons.explore.media
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.depictions.Media.DepictedImagesFragment.PAGE_ID_PREFIX
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.Single
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.`is`
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult
import org.wikipedia.wikidata.Entities
class PageableMediaDataSourceTest {
@Mock
lateinit var mediaConverter: MediaConverter
@Mock
lateinit var mediaClient: MediaClient
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun `loadFunction invokes mediaClient and has Label`() {
val (media, entity: Entities.Entity) = expectMediaAndEntity()
val label: Entities.Label = mock()
whenever(entity.labels()).thenReturn(mapOf(" " to label))
whenever(label.value()).thenReturn("label")
val pageableMediaDataSource = PageableMediaDataSource(mock(), mediaConverter, mediaClient)
pageableMediaDataSource.onQueryUpdated("test")
assertThat(pageableMediaDataSource.loadFunction(0,1), `is`(listOf(media)))
verify(media).caption = "label"
}
@Test
fun `loadFunction invokes mediaClient and does not have Label`() {
val (media, entity: Entities.Entity) = expectMediaAndEntity()
whenever(entity.labels()).thenReturn(mapOf())
val pageableMediaDataSource = PageableMediaDataSource(mock(), mediaConverter, mediaClient)
pageableMediaDataSource.onQueryUpdated("test")
assertThat(pageableMediaDataSource.loadFunction(0,1), `is`(listOf(media)))
verify(media).caption = MediaClient.NO_CAPTION
}
private fun expectMediaAndEntity(): Pair<Media, Entities.Entity> {
val queryResponse: MwQueryResponse = mock()
whenever(mediaClient.getMediaListFromSearch("test", 0, 1))
.thenReturn(Single.just(queryResponse))
val queryResult: MwQueryResult = mock()
whenever(queryResponse.query()).thenReturn(queryResult)
val queryPage: MwQueryPage = mock()
whenever(queryResult.pages()).thenReturn(listOf(queryPage))
val media = mock<Media>()
whenever(mediaConverter.convert(queryPage)).thenReturn(media)
whenever(media.pageId).thenReturn("1")
val entities: Entities = mock()
whenever(mediaClient.getEntities("${PAGE_ID_PREFIX}1")).thenReturn(Single.just(entities))
val entity: Entities.Entity = mock()
whenever(entities.entities()).thenReturn(mapOf("" to entity))
return Pair(media, entity)
}
}