mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
#3810 Convert DepictedImagesFragment to use Pagination - rename base classes to better reflect usage
This commit is contained in:
parent
181a63a233
commit
310c29c2bd
25 changed files with 104 additions and 103 deletions
|
|
@ -1,12 +1,12 @@
|
||||||
package fr.free.nrw.commons.depictions.Media
|
package fr.free.nrw.commons.depictions.Media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.explore.SearchFragmentContract
|
import fr.free.nrw.commons.explore.PagingContract
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract with which DepictedImagesFragment and its presenter will talk to each other
|
* Contract with which DepictedImagesFragment and its presenter will talk to each other
|
||||||
*/
|
*/
|
||||||
interface DepictedImagesContract {
|
interface DepictedImagesContract {
|
||||||
interface View : SearchFragmentContract.View<Media>
|
interface View : PagingContract.View<Media>
|
||||||
interface Presenter : SearchFragmentContract.Presenter<Media>
|
interface Presenter : PagingContract.Presenter<Media>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ class DepictedImagesFragment : PageableMediaFragment(), DepictedImagesContract.V
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: DepictedImagesContract.Presenter
|
lateinit var presenter: DepictedImagesContract.Presenter
|
||||||
|
|
||||||
override val injectedPresenter: DepictedImagesContract.Presenter
|
override val injectedPresenter
|
||||||
get() = presenter
|
get() = presenter
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
injectedPresenter.onQueryUpdated(arguments!!.getString("entityId")!!)
|
onQueryUpdated(arguments!!.getString("entityId")!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClicked(position: Int) {
|
override fun onItemClicked(position: Int) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package fr.free.nrw.commons.depictions.Media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.di.CommonsApplicationModule
|
import fr.free.nrw.commons.di.CommonsApplicationModule
|
||||||
import fr.free.nrw.commons.explore.BaseSearchPresenter
|
import fr.free.nrw.commons.explore.BasePagingPresenter
|
||||||
import io.reactivex.Scheduler
|
import io.reactivex.Scheduler
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
|
|
@ -13,5 +13,5 @@ import javax.inject.Named
|
||||||
class DepictedImagesPresenter @Inject constructor(
|
class DepictedImagesPresenter @Inject constructor(
|
||||||
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
||||||
dataSourceFactory: PageableDepictedMediaDataSource
|
dataSourceFactory: PageableDepictedMediaDataSource
|
||||||
) : BaseSearchPresenter<Media>(mainThreadScheduler, dataSourceFactory),
|
) : BasePagingPresenter<Media>(mainThreadScheduler, dataSourceFactory),
|
||||||
DepictedImagesContract.Presenter
|
DepictedImagesContract.Presenter
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package fr.free.nrw.commons.depictions.Media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.explore.LiveDataConverter
|
import fr.free.nrw.commons.explore.LiveDataConverter
|
||||||
import fr.free.nrw.commons.explore.PageableDataSource
|
import fr.free.nrw.commons.explore.PageableBaseDataSource
|
||||||
import fr.free.nrw.commons.explore.depictions.LoadFunction
|
import fr.free.nrw.commons.explore.depictions.LoadFunction
|
||||||
import fr.free.nrw.commons.media.MediaClient
|
import fr.free.nrw.commons.media.MediaClient
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -10,7 +10,7 @@ import javax.inject.Inject
|
||||||
class PageableDepictedMediaDataSource @Inject constructor(
|
class PageableDepictedMediaDataSource @Inject constructor(
|
||||||
liveDataConverter: LiveDataConverter,
|
liveDataConverter: LiveDataConverter,
|
||||||
private val mediaClient: MediaClient
|
private val mediaClient: MediaClient
|
||||||
) : PageableDataSource<Media>(liveDataConverter) {
|
) : PageableBaseDataSource<Media>(liveDataConverter) {
|
||||||
override val loadFunction: LoadFunction<Media> = { loadSize: Int, startPosition: Int ->
|
override val loadFunction: LoadFunction<Media> = { loadSize: Int, startPosition: Int ->
|
||||||
mediaClient.fetchImagesForDepictedItem(query, loadSize, startPosition).blockingGet()
|
mediaClient.fetchImagesForDepictedItem(query, loadSize, startPosition).blockingGet()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ import fr.free.nrw.commons.utils.ViewUtil
|
||||||
import kotlinx.android.synthetic.main.fragment_search_paginated.*
|
import kotlinx.android.synthetic.main.fragment_search_paginated.*
|
||||||
|
|
||||||
|
|
||||||
abstract class BaseSearchFragment<T> : CommonsDaggerSupportFragment(),
|
abstract class BasePagingFragment<T> : CommonsDaggerSupportFragment(),
|
||||||
SearchFragmentContract.View<T> {
|
PagingContract.View<T> {
|
||||||
|
|
||||||
abstract val pagedListAdapter: PagedListAdapter<T, *>
|
abstract val pagedListAdapter: PagedListAdapter<T, *>
|
||||||
abstract val injectedPresenter: SearchFragmentContract.Presenter<T>
|
abstract val injectedPresenter: PagingContract.Presenter<T>
|
||||||
abstract val errorTextId: Int
|
abstract val errorTextId: Int
|
||||||
private val loadingAdapter by lazy { FooterAdapter { injectedPresenter.retryFailedRequest() } }
|
private val loadingAdapter by lazy { FooterAdapter { injectedPresenter.retryFailedRequest() } }
|
||||||
private val mergeAdapter by lazy { MergeAdapter(pagedListAdapter, loadingAdapter) }
|
private val mergeAdapter by lazy { MergeAdapter(pagedListAdapter, loadingAdapter) }
|
||||||
|
|
@ -47,11 +47,12 @@ abstract class BaseSearchFragment<T> : CommonsDaggerSupportFragment(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeSearchResults(searchResults: LiveData<PagedList<T>>) {
|
override fun observePagingResults(searchResults: LiveData<PagedList<T>>) {
|
||||||
this.searchResults?.removeObservers(viewLifecycleOwner)
|
this.searchResults?.removeObservers(viewLifecycleOwner)
|
||||||
this.searchResults = searchResults
|
this.searchResults = searchResults
|
||||||
searchResults.observe(viewLifecycleOwner, Observer {
|
searchResults.observe(viewLifecycleOwner, Observer {
|
||||||
pagedListAdapter.submitList(it) })
|
pagedListAdapter.submitList(it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
|
|
@ -85,7 +86,7 @@ abstract class BaseSearchFragment<T> : CommonsDaggerSupportFragment(),
|
||||||
contentNotFound.visibility = View.VISIBLE
|
contentNotFound.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun getEmptyText(query: String):String
|
abstract fun getEmptyText(query: String): String
|
||||||
|
|
||||||
override fun hideEmptyText() {
|
override fun hideEmptyText() {
|
||||||
contentNotFound.visibility = View.GONE
|
contentNotFound.visibility = View.GONE
|
||||||
|
|
@ -7,25 +7,25 @@ import io.reactivex.disposables.CompositeDisposable
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
|
||||||
abstract class BaseSearchPresenter<T>(
|
abstract class BasePagingPresenter<T>(
|
||||||
val mainThreadScheduler: Scheduler,
|
val mainThreadScheduler: Scheduler,
|
||||||
val pageableDataSource: PageableDataSource<T>
|
val pageableBaseDataSource: PageableBaseDataSource<T>
|
||||||
) : SearchFragmentContract.Presenter<T> {
|
) : PagingContract.Presenter<T> {
|
||||||
|
|
||||||
private val DUMMY: SearchFragmentContract.View<T> = proxy()
|
private val DUMMY: PagingContract.View<T> = proxy()
|
||||||
private var view: SearchFragmentContract.View<T> = DUMMY
|
private var view: PagingContract.View<T> = DUMMY
|
||||||
|
|
||||||
private val compositeDisposable = CompositeDisposable()
|
private val compositeDisposable = CompositeDisposable()
|
||||||
override val listFooterData = MutableLiveData<List<FooterItem>>().apply { value = emptyList() }
|
override val listFooterData = MutableLiveData<List<FooterItem>>().apply { value = emptyList() }
|
||||||
|
|
||||||
override fun onAttachView(view: SearchFragmentContract.View<T>) {
|
override fun onAttachView(view: PagingContract.View<T>) {
|
||||||
this.view = view
|
this.view = view
|
||||||
compositeDisposable.addAll(
|
compositeDisposable.addAll(
|
||||||
pageableDataSource.searchResults.subscribe(view::observeSearchResults),
|
pageableBaseDataSource.pagingResults.subscribe(view::observePagingResults),
|
||||||
pageableDataSource.loadingStates
|
pageableBaseDataSource.loadingStates
|
||||||
.observeOn(mainThreadScheduler)
|
.observeOn(mainThreadScheduler)
|
||||||
.subscribe(::onLoadingState, Timber::e),
|
.subscribe(::onLoadingState, Timber::e),
|
||||||
pageableDataSource.noItemsLoadedQueries.subscribe(view::showEmptyText)
|
pageableBaseDataSource.noItemsLoadedQueries.subscribe(view::showEmptyText)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ abstract class BaseSearchPresenter<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun retryFailedRequest() {
|
override fun retryFailedRequest() {
|
||||||
pageableDataSource.retryFailedRequest()
|
pageableBaseDataSource.retryFailedRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDetachView() {
|
override fun onDetachView() {
|
||||||
|
|
@ -59,7 +59,7 @@ abstract class BaseSearchPresenter<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryUpdated(query: String) {
|
override fun onQueryUpdated(query: String) {
|
||||||
pageableDataSource.onQueryUpdated(query)
|
pageableBaseDataSource.onQueryUpdated(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,10 +4,10 @@ import androidx.lifecycle.LiveData
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import fr.free.nrw.commons.BasePresenter
|
import fr.free.nrw.commons.BasePresenter
|
||||||
|
|
||||||
interface SearchFragmentContract {
|
interface PagingContract {
|
||||||
interface View<T> {
|
interface View<T> {
|
||||||
fun showSnackbar()
|
fun showSnackbar()
|
||||||
fun observeSearchResults(searchResults: LiveData<PagedList<T>>)
|
fun observePagingResults(searchResults: LiveData<PagedList<T>>)
|
||||||
fun showInitialLoadInProgress()
|
fun showInitialLoadInProgress()
|
||||||
fun hideInitialLoadProgress()
|
fun hideInitialLoadProgress()
|
||||||
fun showEmptyText(query: String)
|
fun showEmptyText(query: String)
|
||||||
|
|
@ -14,25 +14,25 @@ import javax.inject.Inject
|
||||||
private const val PAGE_SIZE = 50
|
private const val PAGE_SIZE = 50
|
||||||
private const val INITIAL_LOAD_SIZE = 50
|
private const val INITIAL_LOAD_SIZE = 50
|
||||||
|
|
||||||
abstract class PageableDataSource<T>(private val liveDataConverter: LiveDataConverter) {
|
abstract class PageableBaseDataSource<T>(private val liveDataConverter: LiveDataConverter) {
|
||||||
|
|
||||||
lateinit var query: String
|
lateinit var query: String
|
||||||
private val dataSourceFactoryFactory: () -> SearchDataSourceFactory<T> = {
|
private val dataSourceFactoryFactory: () -> PagingDataSourceFactory<T> = {
|
||||||
dataSourceFactory(_loadingStates, loadFunction)
|
dataSourceFactory(_loadingStates, loadFunction)
|
||||||
}
|
}
|
||||||
private val _loadingStates = PublishProcessor.create<LoadingState>()
|
private val _loadingStates = PublishProcessor.create<LoadingState>()
|
||||||
val loadingStates: Flowable<LoadingState> = _loadingStates
|
val loadingStates: Flowable<LoadingState> = _loadingStates
|
||||||
private val _searchResults = PublishProcessor.create<LiveData<PagedList<T>>>()
|
private val _pagingResults = PublishProcessor.create<LiveData<PagedList<T>>>()
|
||||||
val searchResults: Flowable<LiveData<PagedList<T>>> = _searchResults
|
val pagingResults: Flowable<LiveData<PagedList<T>>> = _pagingResults
|
||||||
private val _noItemsLoadedEvent = PublishProcessor.create<String>()
|
private val _noItemsLoadedEvent = PublishProcessor.create<String>()
|
||||||
val noItemsLoadedQueries: Flowable<String> = _noItemsLoadedEvent
|
val noItemsLoadedQueries: Flowable<String> = _noItemsLoadedEvent
|
||||||
private var currentFactory: SearchDataSourceFactory<T>? = null
|
private var currentFactory: PagingDataSourceFactory<T>? = null
|
||||||
|
|
||||||
abstract val loadFunction: LoadFunction<T>
|
abstract val loadFunction: LoadFunction<T>
|
||||||
|
|
||||||
fun onQueryUpdated(query: String) {
|
fun onQueryUpdated(query: String) {
|
||||||
this.query = query
|
this.query = query
|
||||||
_searchResults.offer(
|
_pagingResults.offer(
|
||||||
liveDataConverter.convert(dataSourceFactoryFactory().also { currentFactory = it }) {
|
liveDataConverter.convert(dataSourceFactoryFactory().also { currentFactory = it }) {
|
||||||
_noItemsLoadedEvent.offer(query)
|
_noItemsLoadedEvent.offer(query)
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ abstract class PageableDataSource<T>(private val liveDataConverter: LiveDataConv
|
||||||
|
|
||||||
class LiveDataConverter @Inject constructor() {
|
class LiveDataConverter @Inject constructor() {
|
||||||
fun <T> convert(
|
fun <T> convert(
|
||||||
dataSourceFactory: SearchDataSourceFactory<T>,
|
dataSourceFactory: PagingDataSourceFactory<T>,
|
||||||
zeroItemsLoadedFunction: () -> Unit
|
zeroItemsLoadedFunction: () -> Unit
|
||||||
): LiveData<PagedList<T>> {
|
): LiveData<PagedList<T>> {
|
||||||
return dataSourceFactory.toLiveData(
|
return dataSourceFactory.toLiveData(
|
||||||
|
|
@ -65,7 +65,7 @@ class LiveDataConverter @Inject constructor() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SearchDataSourceFactory<T>(val loadingStates: LoadingStates) :
|
abstract class PagingDataSourceFactory<T>(val loadingStates: LoadingStates) :
|
||||||
DataSource.Factory<Int, T>() {
|
DataSource.Factory<Int, T>() {
|
||||||
private var currentDataSource: SearchDataSource<T>? = null
|
private var currentDataSource: SearchDataSource<T>? = null
|
||||||
abstract val loadFunction: LoadFunction<T>
|
abstract val loadFunction: LoadFunction<T>
|
||||||
|
|
@ -80,7 +80,7 @@ abstract class SearchDataSourceFactory<T>(val loadingStates: LoadingStates) :
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> dataSourceFactory(loadingStates: LoadingStates, loadFunction: LoadFunction<T>) =
|
fun <T> dataSourceFactory(loadingStates: LoadingStates, loadFunction: LoadFunction<T>) =
|
||||||
object : SearchDataSourceFactory<T>(loadingStates) {
|
object : PagingDataSourceFactory<T>(loadingStates) {
|
||||||
override val loadFunction: LoadFunction<T> = loadFunction
|
override val loadFunction: LoadFunction<T> = loadFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10,5 +10,5 @@ import javax.inject.Named
|
||||||
class SearchCategoriesFragmentPresenter @Inject constructor(
|
class SearchCategoriesFragmentPresenter @Inject constructor(
|
||||||
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
||||||
dataSourceFactory: PageableCategoriesDataSource
|
dataSourceFactory: PageableCategoriesDataSource
|
||||||
) : BaseSearchPresenter<String>(mainThreadScheduler, dataSourceFactory),
|
) : BasePagingPresenter<String>(mainThreadScheduler, dataSourceFactory),
|
||||||
SearchCategoriesFragmentContract.Presenter
|
SearchCategoriesFragmentContract.Presenter
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ package fr.free.nrw.commons.explore.categories
|
||||||
|
|
||||||
import fr.free.nrw.commons.category.CategoryClient
|
import fr.free.nrw.commons.category.CategoryClient
|
||||||
import fr.free.nrw.commons.explore.LiveDataConverter
|
import fr.free.nrw.commons.explore.LiveDataConverter
|
||||||
import fr.free.nrw.commons.explore.PageableDataSource
|
import fr.free.nrw.commons.explore.PageableBaseDataSource
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PageableCategoriesDataSource @Inject constructor(
|
class PageableCategoriesDataSource @Inject constructor(
|
||||||
liveDataConverter: LiveDataConverter,
|
liveDataConverter: LiveDataConverter,
|
||||||
val categoryClient: CategoryClient
|
val categoryClient: CategoryClient
|
||||||
) : PageableDataSource<String>(liveDataConverter) {
|
) : PageableBaseDataSource<String>(liveDataConverter) {
|
||||||
|
|
||||||
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
||||||
categoryClient.searchCategories(query, loadSize, startPosition).blockingFirst()
|
categoryClient.searchCategories(query, loadSize, startPosition).blockingFirst()
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package fr.free.nrw.commons.explore.categories
|
package fr.free.nrw.commons.explore.categories
|
||||||
|
|
||||||
import fr.free.nrw.commons.explore.SearchFragmentContract
|
import fr.free.nrw.commons.explore.PagingContract
|
||||||
|
|
||||||
interface SearchCategoriesFragmentContract {
|
interface SearchCategoriesFragmentContract {
|
||||||
interface View : SearchFragmentContract.View<String>
|
interface View : PagingContract.View<String>
|
||||||
interface Presenter : SearchFragmentContract.Presenter<String>
|
interface Presenter : PagingContract.Presenter<String>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,20 @@ package fr.free.nrw.commons.explore.categories
|
||||||
|
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.category.CategoryDetailsActivity
|
import fr.free.nrw.commons.category.CategoryDetailsActivity
|
||||||
import fr.free.nrw.commons.explore.BaseSearchFragment
|
import fr.free.nrw.commons.explore.BasePagingFragment
|
||||||
import fr.free.nrw.commons.explore.SearchFragmentContract
|
import fr.free.nrw.commons.explore.PagingContract
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the category search screen.
|
* Displays the category search screen.
|
||||||
*/
|
*/
|
||||||
class SearchCategoryFragment : BaseSearchFragment<String>() {
|
class SearchCategoryFragment : BasePagingFragment<String>() {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: SearchCategoriesFragmentContract.Presenter
|
lateinit var presenter: SearchCategoriesFragmentContract.Presenter
|
||||||
|
|
||||||
override val errorTextId: Int = R.string.error_loading_categories
|
override val errorTextId: Int = R.string.error_loading_categories
|
||||||
|
|
||||||
override val injectedPresenter: SearchFragmentContract.Presenter<String>
|
override val injectedPresenter
|
||||||
get() = presenter
|
get() = presenter
|
||||||
|
|
||||||
override val pagedListAdapter by lazy {
|
override val pagedListAdapter by lazy {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
import fr.free.nrw.commons.explore.LiveDataConverter
|
import fr.free.nrw.commons.explore.LiveDataConverter
|
||||||
import fr.free.nrw.commons.explore.LoadingState
|
import fr.free.nrw.commons.explore.LoadingState
|
||||||
import fr.free.nrw.commons.explore.PageableDataSource
|
import fr.free.nrw.commons.explore.PageableBaseDataSource
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import io.reactivex.processors.PublishProcessor
|
import io.reactivex.processors.PublishProcessor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -13,7 +13,7 @@ typealias LoadingStates = PublishProcessor<LoadingState>
|
||||||
class PageableDepictionsDataSource @Inject constructor(
|
class PageableDepictionsDataSource @Inject constructor(
|
||||||
liveDataConverter: LiveDataConverter,
|
liveDataConverter: LiveDataConverter,
|
||||||
val depictsClient: DepictsClient
|
val depictsClient: DepictsClient
|
||||||
) : PageableDataSource<DepictedItem>(liveDataConverter) {
|
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
|
||||||
|
|
||||||
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
||||||
depictsClient.searchForDepictions(query, loadSize, startPosition).blockingGet()
|
depictsClient.searchForDepictions(query, loadSize, startPosition).blockingGet()
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,21 @@ package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity
|
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity
|
||||||
import fr.free.nrw.commons.explore.BaseSearchFragment
|
import fr.free.nrw.commons.explore.BasePagingFragment
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display depictions in search fragment
|
* Display depictions in search fragment
|
||||||
*/
|
*/
|
||||||
class SearchDepictionsFragment : BaseSearchFragment<DepictedItem>(),
|
class SearchDepictionsFragment : BasePagingFragment<DepictedItem>(),
|
||||||
SearchDepictionsFragmentContract.View {
|
SearchDepictionsFragmentContract.View {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: SearchDepictionsFragmentContract.Presenter
|
lateinit var presenter: SearchDepictionsFragmentContract.Presenter
|
||||||
|
|
||||||
override val errorTextId: Int = R.string.error_loading_depictions
|
override val errorTextId: Int = R.string.error_loading_depictions
|
||||||
|
|
||||||
override val injectedPresenter: SearchDepictionsFragmentContract.Presenter
|
override val injectedPresenter
|
||||||
get() = presenter
|
get() = presenter
|
||||||
|
|
||||||
override val pagedListAdapter by lazy {
|
override val pagedListAdapter by lazy {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package fr.free.nrw.commons.explore.depictions
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
import fr.free.nrw.commons.explore.SearchFragmentContract
|
import fr.free.nrw.commons.explore.PagingContract
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The contract with with SearchDepictionsFragment and its presenter would talk to each other
|
* The contract with with SearchDepictionsFragment and its presenter would talk to each other
|
||||||
*/
|
*/
|
||||||
interface SearchDepictionsFragmentContract {
|
interface SearchDepictionsFragmentContract {
|
||||||
interface View : SearchFragmentContract.View<DepictedItem>
|
interface View : PagingContract.View<DepictedItem>
|
||||||
interface Presenter : SearchFragmentContract.Presenter<DepictedItem>
|
interface Presenter : PagingContract.Presenter<DepictedItem>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package fr.free.nrw.commons.explore.depictions
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
import fr.free.nrw.commons.di.CommonsApplicationModule
|
import fr.free.nrw.commons.di.CommonsApplicationModule
|
||||||
import fr.free.nrw.commons.explore.BaseSearchPresenter
|
import fr.free.nrw.commons.explore.BasePagingPresenter
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import io.reactivex.Scheduler
|
import io.reactivex.Scheduler
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -13,5 +13,5 @@ import javax.inject.Named
|
||||||
class SearchDepictionsFragmentPresenter @Inject constructor(
|
class SearchDepictionsFragmentPresenter @Inject constructor(
|
||||||
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
||||||
dataSourceFactory: PageableDepictionsDataSource
|
dataSourceFactory: PageableDepictionsDataSource
|
||||||
) : BaseSearchPresenter<DepictedItem>(mainThreadScheduler, dataSourceFactory),
|
) : BasePagingPresenter<DepictedItem>(mainThreadScheduler, dataSourceFactory),
|
||||||
SearchDepictionsFragmentContract.Presenter
|
SearchDepictionsFragmentContract.Presenter
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package fr.free.nrw.commons.explore.media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.explore.LiveDataConverter
|
import fr.free.nrw.commons.explore.LiveDataConverter
|
||||||
import fr.free.nrw.commons.explore.PageableDataSource
|
import fr.free.nrw.commons.explore.PageableBaseDataSource
|
||||||
import fr.free.nrw.commons.explore.depictions.LoadFunction
|
import fr.free.nrw.commons.explore.depictions.LoadFunction
|
||||||
import fr.free.nrw.commons.media.MediaClient
|
import fr.free.nrw.commons.media.MediaClient
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -10,7 +10,7 @@ import javax.inject.Inject
|
||||||
class PageableMediaDataSource @Inject constructor(
|
class PageableMediaDataSource @Inject constructor(
|
||||||
liveDataConverter: LiveDataConverter,
|
liveDataConverter: LiveDataConverter,
|
||||||
private val mediaClient: MediaClient
|
private val mediaClient: MediaClient
|
||||||
) : PageableDataSource<Media>(liveDataConverter) {
|
) : PageableBaseDataSource<Media>(liveDataConverter) {
|
||||||
override val loadFunction: LoadFunction<Media> = { loadSize: Int, startPosition: Int ->
|
override val loadFunction: LoadFunction<Media> = { loadSize: Int, startPosition: Int ->
|
||||||
mediaClient.getMediaListFromSearch(query, loadSize, startPosition).blockingGet()
|
mediaClient.getMediaListFromSearch(query, loadSize, startPosition).blockingGet()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.explore.BaseSearchFragment
|
import fr.free.nrw.commons.explore.BasePagingFragment
|
||||||
import kotlinx.android.synthetic.main.fragment_search_paginated.*
|
import kotlinx.android.synthetic.main.fragment_search_paginated.*
|
||||||
|
|
||||||
|
|
||||||
abstract class PageableMediaFragment : BaseSearchFragment<Media>() {
|
abstract class PageableMediaFragment : BasePagingFragment<Media>() {
|
||||||
override val pagedListAdapter by lazy { PagedMediaAdapter(::onItemClicked) }
|
override val pagedListAdapter by lazy { PagedMediaAdapter(::onItemClicked) }
|
||||||
|
|
||||||
override val errorTextId: Int = R.string.error_loading_images
|
override val errorTextId: Int = R.string.error_loading_images
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class SearchMediaFragment : PageableMediaFragment(), SearchMediaFragmentContract
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: SearchMediaFragmentContract.Presenter
|
lateinit var presenter: SearchMediaFragmentContract.Presenter
|
||||||
|
|
||||||
override val injectedPresenter: SearchMediaFragmentContract.Presenter
|
override val injectedPresenter
|
||||||
get() = presenter
|
get() = presenter
|
||||||
|
|
||||||
override fun onItemClicked(position: Int) {
|
override fun onItemClicked(position: Int) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package fr.free.nrw.commons.explore.media
|
package fr.free.nrw.commons.explore.media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.explore.SearchFragmentContract
|
import fr.free.nrw.commons.explore.PagingContract
|
||||||
|
|
||||||
|
|
||||||
interface SearchMediaFragmentContract {
|
interface SearchMediaFragmentContract {
|
||||||
interface View : SearchFragmentContract.View<Media>
|
interface View : PagingContract.View<Media>
|
||||||
interface Presenter : SearchFragmentContract.Presenter<Media>
|
interface Presenter : PagingContract.Presenter<Media>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package fr.free.nrw.commons.explore.media
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.di.CommonsApplicationModule
|
import fr.free.nrw.commons.di.CommonsApplicationModule
|
||||||
import fr.free.nrw.commons.explore.BaseSearchPresenter
|
import fr.free.nrw.commons.explore.BasePagingPresenter
|
||||||
import io.reactivex.Scheduler
|
import io.reactivex.Scheduler
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
|
|
@ -10,5 +10,5 @@ import javax.inject.Named
|
||||||
class SearchMediaFragmentPresenter @Inject constructor(
|
class SearchMediaFragmentPresenter @Inject constructor(
|
||||||
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
@Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler,
|
||||||
dataSourceFactory: PageableMediaDataSource
|
dataSourceFactory: PageableMediaDataSource
|
||||||
) : BaseSearchPresenter<Media>(mainThreadScheduler, dataSourceFactory),
|
) : BasePagingPresenter<Media>(mainThreadScheduler, dataSourceFactory),
|
||||||
SearchMediaFragmentContract.Presenter
|
SearchMediaFragmentContract.Presenter
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,21 @@ import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
class BaseSearchPresenterTest {
|
class BasePagingPresenterTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
internal lateinit var view: SearchFragmentContract.View<String>
|
internal lateinit var view: PagingContract.View<String>
|
||||||
|
|
||||||
private lateinit var baseSearchPresenter: BaseSearchPresenter<String>
|
private lateinit var basePagingPresenter: BasePagingPresenter<String>
|
||||||
|
|
||||||
private lateinit var testScheduler: TestScheduler
|
private lateinit var testScheduler: TestScheduler
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var pageableDataSource: PageableDataSource<String>
|
private lateinit var pageableBaseDataSource: PageableBaseDataSource<String>
|
||||||
|
|
||||||
private var loadingStates: PublishProcessor<LoadingState> = PublishProcessor.create()
|
private var loadingStates: PublishProcessor<LoadingState> = PublishProcessor.create()
|
||||||
|
|
||||||
|
|
@ -42,34 +42,34 @@ class BaseSearchPresenterTest {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
whenever(pageableDataSource.searchResults).thenReturn(searchResults)
|
whenever(pageableBaseDataSource.pagingResults).thenReturn(searchResults)
|
||||||
whenever(pageableDataSource.loadingStates).thenReturn(loadingStates)
|
whenever(pageableBaseDataSource.loadingStates).thenReturn(loadingStates)
|
||||||
whenever(pageableDataSource.noItemsLoadedQueries)
|
whenever(pageableBaseDataSource.noItemsLoadedQueries)
|
||||||
.thenReturn(noItemLoadedQueries)
|
.thenReturn(noItemLoadedQueries)
|
||||||
testScheduler = TestScheduler()
|
testScheduler = TestScheduler()
|
||||||
baseSearchPresenter =
|
basePagingPresenter =
|
||||||
object : BaseSearchPresenter<String>(testScheduler, pageableDataSource) {}
|
object : BasePagingPresenter<String>(testScheduler, pageableBaseDataSource) {}
|
||||||
baseSearchPresenter.onAttachView(view)
|
basePagingPresenter.onAttachView(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `searchResults emission updates the view`() {
|
fun `searchResults emission updates the view`() {
|
||||||
val pagedListLiveData = mock<LiveData<PagedList<String>>>()
|
val pagedListLiveData = mock<LiveData<PagedList<String>>>()
|
||||||
searchResults.offer(pagedListLiveData)
|
searchResults.offer(pagedListLiveData)
|
||||||
verify(view).observeSearchResults(pagedListLiveData)
|
verify(view).observePagingResults(pagedListLiveData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Loading offers a loading list item`() {
|
fun `Loading offers a loading list item`() {
|
||||||
onLoadingState(LoadingState.Loading)
|
onLoadingState(LoadingState.Loading)
|
||||||
verify(view).hideEmptyText()
|
verify(view).hideEmptyText()
|
||||||
baseSearchPresenter.listFooterData.test().assertValue(listOf(FooterItem.LoadingItem))
|
basePagingPresenter.listFooterData.test().assertValue(listOf(FooterItem.LoadingItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Complete offers an empty list item and hides initial loader`() {
|
fun `Complete offers an empty list item and hides initial loader`() {
|
||||||
onLoadingState(LoadingState.Complete)
|
onLoadingState(LoadingState.Complete)
|
||||||
baseSearchPresenter.listFooterData.test()
|
basePagingPresenter.listFooterData.test()
|
||||||
.assertValue(emptyList())
|
.assertValue(emptyList())
|
||||||
verify(view).hideInitialLoadProgress()
|
verify(view).hideInitialLoadProgress()
|
||||||
}
|
}
|
||||||
|
|
@ -83,11 +83,11 @@ class BaseSearchPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Error offers a refresh list item, hides initial loader and shows error with a set text`() {
|
fun `Error offers a refresh list item, hides initial loader and shows error with a set text`() {
|
||||||
baseSearchPresenter.onQueryUpdated("test")
|
basePagingPresenter.onQueryUpdated("test")
|
||||||
onLoadingState(LoadingState.Error)
|
onLoadingState(LoadingState.Error)
|
||||||
verify(view).showSnackbar()
|
verify(view).showSnackbar()
|
||||||
verify(view).hideInitialLoadProgress()
|
verify(view).hideInitialLoadProgress()
|
||||||
baseSearchPresenter.listFooterData.test().assertValue(listOf(FooterItem.RefreshItem))
|
basePagingPresenter.listFooterData.test().assertValue(listOf(FooterItem.RefreshItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -98,21 +98,21 @@ class BaseSearchPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `retryFailedRequest calls retry`() {
|
fun `retryFailedRequest calls retry`() {
|
||||||
baseSearchPresenter.retryFailedRequest()
|
basePagingPresenter.retryFailedRequest()
|
||||||
verify(pageableDataSource).retryFailedRequest()
|
verify(pageableBaseDataSource).retryFailedRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `onDetachView stops subscriptions`() {
|
fun `onDetachView stops subscriptions`() {
|
||||||
baseSearchPresenter.onDetachView()
|
basePagingPresenter.onDetachView()
|
||||||
onLoadingState(LoadingState.Loading)
|
onLoadingState(LoadingState.Loading)
|
||||||
baseSearchPresenter.listFooterData.test().assertValue(emptyList())
|
basePagingPresenter.listFooterData.test().assertValue(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `onQueryUpdated updates dataSourceFactory`() {
|
fun `onQueryUpdated updates dataSourceFactory`() {
|
||||||
baseSearchPresenter.onQueryUpdated("test")
|
basePagingPresenter.onQueryUpdated("test")
|
||||||
verify(pageableDataSource).onQueryUpdated("test")
|
verify(pageableBaseDataSource).onQueryUpdated("test")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onLoadingState(loadingState: LoadingState) {
|
private fun onLoadingState(loadingState: LoadingState) {
|
||||||
|
|
@ -10,17 +10,17 @@ import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
class PageableDataSourceTest {
|
class PageableBaseDataSourceTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var liveDataConverter: LiveDataConverter
|
private lateinit var liveDataConverter: LiveDataConverter
|
||||||
|
|
||||||
private lateinit var pageableDataSource: PageableDataSource<String>
|
private lateinit var pageableBaseDataSource: PageableBaseDataSource<String>
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
pageableDataSource = object: PageableDataSource<String>(liveDataConverter){
|
pageableBaseDataSource = object: PageableBaseDataSource<String>(liveDataConverter){
|
||||||
override val loadFunction: LoadFunction<String>
|
override val loadFunction: LoadFunction<String>
|
||||||
get() = mock()
|
get() = mock()
|
||||||
|
|
||||||
|
|
@ -30,16 +30,16 @@ class PageableDataSourceTest {
|
||||||
@Test
|
@Test
|
||||||
fun `onQueryUpdated emits new liveData`() {
|
fun `onQueryUpdated emits new liveData`() {
|
||||||
val (_, liveData) = expectNewLiveData()
|
val (_, liveData) = expectNewLiveData()
|
||||||
pageableDataSource.searchResults.test()
|
pageableBaseDataSource.pagingResults.test()
|
||||||
.also { pageableDataSource.onQueryUpdated("test") }
|
.also { pageableBaseDataSource.onQueryUpdated("test") }
|
||||||
.assertValue(liveData)
|
.assertValue(liveData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `onQueryUpdated invokes livedatconverter with no items emitter`() {
|
fun `onQueryUpdated invokes livedatconverter with no items emitter`() {
|
||||||
val (zeroItemsFuncCaptor, _) = expectNewLiveData()
|
val (zeroItemsFuncCaptor, _) = expectNewLiveData()
|
||||||
pageableDataSource.onQueryUpdated("test")
|
pageableBaseDataSource.onQueryUpdated("test")
|
||||||
pageableDataSource.noItemsLoadedQueries.test()
|
pageableBaseDataSource.noItemsLoadedQueries.test()
|
||||||
.also { zeroItemsFuncCaptor.firstValue.invoke() }
|
.also { zeroItemsFuncCaptor.firstValue.invoke() }
|
||||||
.assertValue("test")
|
.assertValue("test")
|
||||||
}
|
}
|
||||||
|
|
@ -49,22 +49,22 @@ class PageableDataSourceTest {
|
||||||
* */
|
* */
|
||||||
@Test
|
@Test
|
||||||
fun `retryFailedRequest does nothing without a factory`() {
|
fun `retryFailedRequest does nothing without a factory`() {
|
||||||
pageableDataSource.retryFailedRequest()
|
pageableBaseDataSource.retryFailedRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("Rewrite with Mockk constructor mocks")
|
@Ignore("Rewrite with Mockk constructor mocks")
|
||||||
fun `retryFailedRequest retries with a factory`() {
|
fun `retryFailedRequest retries with a factory`() {
|
||||||
val (_, _, dataSourceFactoryCaptor) = expectNewLiveData()
|
val (_, _, dataSourceFactoryCaptor) = expectNewLiveData()
|
||||||
pageableDataSource.onQueryUpdated("test")
|
pageableBaseDataSource.onQueryUpdated("test")
|
||||||
val dataSourceFactory = spy(dataSourceFactoryCaptor.firstValue)
|
val dataSourceFactory = spy(dataSourceFactoryCaptor.firstValue)
|
||||||
pageableDataSource.retryFailedRequest()
|
pageableBaseDataSource.retryFailedRequest()
|
||||||
verify(dataSourceFactory).retryFailedRequest()
|
verify(dataSourceFactory).retryFailedRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun expectNewLiveData(): Triple<KArgumentCaptor<() -> Unit>, LiveData<PagedList<String>>, KArgumentCaptor<SearchDataSourceFactory<String>>> {
|
private fun expectNewLiveData(): Triple<KArgumentCaptor<() -> Unit>, LiveData<PagedList<String>>, KArgumentCaptor<PagingDataSourceFactory<String>>> {
|
||||||
val captor = argumentCaptor<() -> Unit>()
|
val captor = argumentCaptor<() -> Unit>()
|
||||||
val dataSourceFactoryCaptor = argumentCaptor<SearchDataSourceFactory<String>>()
|
val dataSourceFactoryCaptor = argumentCaptor<PagingDataSourceFactory<String>>()
|
||||||
val liveData: LiveData<PagedList<String>> = mock()
|
val liveData: LiveData<PagedList<String>> = mock()
|
||||||
whenever(liveDataConverter.convert(dataSourceFactoryCaptor.capture(), captor.capture()))
|
whenever(liveDataConverter.convert(dataSourceFactoryCaptor.capture(), captor.capture()))
|
||||||
.thenReturn(liveData)
|
.thenReturn(liveData)
|
||||||
|
|
@ -14,21 +14,21 @@ import org.mockito.Mock
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
class SearchDataSourceFactoryTest {
|
class PagingDataSourceFactoryTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var depictsClient: DepictsClient
|
private lateinit var depictsClient: DepictsClient
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var loadingStates: PublishProcessor<LoadingState>
|
private lateinit var loadingStates: PublishProcessor<LoadingState>
|
||||||
private lateinit var factory: SearchDataSourceFactory<String>
|
private lateinit var factory: PagingDataSourceFactory<String>
|
||||||
|
|
||||||
private var function: (Int, Int) -> List<String> = mock()
|
private var function: (Int, Int) -> List<String> = mock()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
factory = object : SearchDataSourceFactory<String>(loadingStates) {
|
factory = object : PagingDataSourceFactory<String>(loadingStates) {
|
||||||
override val loadFunction get() = function
|
override val loadFunction get() = function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue