mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
* #3468 Switch from RvRenderer to AdapterDelegates - replace SearchDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadCategoryDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - update BaseAdapter to be easier to use * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchImagesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchCategoriesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace NotificationRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadDepictsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace PlaceRenderer * #3756 Convert SearchDepictionsFragment to use Pagination - convert SearchDepictionsFragment * #3756 Convert SearchDepictionsFragment to use Pagination - fix presenter unit tests now that view is not nullable - fix Category prefix imports * #3756 Convert SearchDepictionsFragment to use Pagination - test DataSource related classes * #3756 Convert SearchDepictionsFragment to use Pagination - reset rx scheduler - ignore failing test * #3760 Convert SearchCategoriesFragment to use Pagination - extract functionality of pagination to base classes - add category pagination * #3772 Convert SearchImagesFragment to use Pagination - convert SearchImagesFragment - tidy up showing the empty view - make search fragments show snackbar with appropriate text * #3772 Convert SearchImagesFragment to use Pagination - allow viewpager to load more data * #3760 remove test that got re-added by merge * #3760 remove duplicate dependency * #3772 fix compilation * #3780 Create media using a combination of Entities & MwQueryResult - construct media with an entity - move fields from media down to contribution - move dynamic fields outside of media - remove unused constructors - remove all unnecessary fetching of captions/descriptions - bump database version * #3808 Construct media objects that depict an item id correctly - use generator to construct media for DepictedImages * #3810 Convert DepictedImagesFragment to use Pagination - extract common media paging methods - convert to DepictedImages to use pagination * #3810 Convert DepictedImagesFragment to use Pagination - rename base classes to better reflect usage * #3810 Convert DepictedImagesFragment to use Pagination - map to empty result with no pages * #3810 Convert DepictedImagesFragment to use Pagination - align test with returned values * #3780 Create media using a combination of Entities & MwQueryResult - update wikicode to align with expected behaviour * #3780 Create media using a combination of Entities & MwQueryResult - replace old site of thumbnail title with most relevant caption * #3818 Convert SubDepictionListFragment to use Pagination - replace SubDepictionList with Child and Parent Fragments - replace contracts with simple presenter declarations - move classes to appropriate packages - delete unused network models - delete duplicated paging classes * #3820 Convert CategoryImagesListFragment to use Pagination - replace CategoryImagesListFragment with CategoriesMediaFragment - disallow the construction of media objects without imageinfo * #3822 Convert SubCategoryImagesListFragment to use Pagination - convert subcategories - add continuation support in category client - rely on interfaces for callbacks of PageableMediaFragments * #3822 Convert SubCategoryImagesListFragment to use Pagination - convert parent categories - delete list fragment - creat base class to support continuation requests in clients * #3822 Convert SubCategoryImagesListFragment to use Pagination - add tests for ParentCategoriesDataSource * #3822 Convert SubCategoryImagesListFragment to use Pagination - remove no longer applicable test * #3841 Unit Test DepictsClient - add tests * #3841 Unit Test DepictsClient - fix return types
This commit is contained in:
parent
9d59915459
commit
542d321acc
8 changed files with 100 additions and 25 deletions
|
|
@ -1,9 +1,10 @@
|
||||||
package fr.free.nrw.commons.explore.depictions
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.mwapi.Binding
|
||||||
import fr.free.nrw.commons.mwapi.SparqlResponse
|
import fr.free.nrw.commons.mwapi.SparqlResponse
|
||||||
import fr.free.nrw.commons.upload.depicts.DepictsInterface
|
import fr.free.nrw.commons.upload.depicts.DepictsInterface
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import io.reactivex.Observable
|
import fr.free.nrw.commons.wikidata.model.DepictSearchItem
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import org.wikipedia.wikidata.Entities
|
import org.wikipedia.wikidata.Entities
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -14,9 +15,7 @@ import javax.inject.Singleton
|
||||||
* Depicts Client to handle custom calls to Commons Wikibase APIs
|
* Depicts Client to handle custom calls to Commons Wikibase APIs
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
class DepictsClient @Inject constructor(
|
class DepictsClient @Inject constructor(private val depictsInterface: DepictsInterface) {
|
||||||
private val depictsInterface: DepictsInterface
|
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for depictions using the search item
|
* Search for depictions using the search item
|
||||||
|
|
@ -25,22 +24,21 @@ class DepictsClient @Inject constructor(
|
||||||
fun searchForDepictions(query: String?, limit: Int, offset: Int): Single<List<DepictedItem>> {
|
fun searchForDepictions(query: String?, limit: Int, offset: Int): Single<List<DepictedItem>> {
|
||||||
val language = Locale.getDefault().language
|
val language = Locale.getDefault().language
|
||||||
return depictsInterface.searchForDepicts(query, "$limit", language, language, "$offset")
|
return depictsInterface.searchForDepicts(query, "$limit", language, language, "$offset")
|
||||||
.map { it.search.joinToString("|") { searchItem -> searchItem.id } }
|
.map { it.search.joinToString("|", transform = DepictSearchItem::id) }
|
||||||
.flatMap(::getEntities)
|
.mapToDepictions()
|
||||||
.map { it.entities().values.map(::DepictedItem) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEntities(ids: String): Single<Entities> {
|
fun getEntities(ids: String): Single<Entities> {
|
||||||
return depictsInterface.getEntities(ids)
|
return depictsInterface.getEntities(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toDepictions(sparqlResponse: Observable<SparqlResponse>): Observable<List<DepictedItem>> {
|
fun toDepictions(sparqlResponse: Single<SparqlResponse>): Single<List<DepictedItem>> {
|
||||||
return sparqlResponse.map {
|
return sparqlResponse.map {
|
||||||
it.results.bindings.joinToString("|") { binding ->
|
it.results.bindings.joinToString("|", transform = Binding::id)
|
||||||
binding.id
|
}.mapToDepictions()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.flatMap { getEntities(it).toObservable() }
|
private fun Single<String>.mapToDepictions() =
|
||||||
|
flatMap(::getEntities)
|
||||||
.map { it.entities().values.map(::DepictedItem) }
|
.map { it.entities().values.map(::DepictedItem) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class PageableChildDepictionsDataSource @Inject constructor(
|
||||||
private val okHttpJsonApiClient: OkHttpJsonApiClient
|
private val okHttpJsonApiClient: OkHttpJsonApiClient
|
||||||
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
|
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
|
||||||
override val loadFunction = { limit: Int, startPosition: Int ->
|
override val loadFunction = { limit: Int, startPosition: Int ->
|
||||||
okHttpJsonApiClient.getChildDepictions(query, startPosition, limit).blockingFirst()
|
okHttpJsonApiClient.getChildDepictions(query, startPosition, limit).blockingGet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class PageableParentDepictionsDataSource @Inject constructor(
|
||||||
private val okHttpJsonApiClient: OkHttpJsonApiClient
|
private val okHttpJsonApiClient: OkHttpJsonApiClient
|
||||||
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
|
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
|
||||||
override val loadFunction = { limit: Int, startPosition: Int ->
|
override val loadFunction = { limit: Int, startPosition: Int ->
|
||||||
okHttpJsonApiClient.getParentDepictions(query, startPosition, limit).blockingFirst()
|
okHttpJsonApiClient.getParentDepictions(query, startPosition, limit).blockingGet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ public class OkHttpJsonApiClient {
|
||||||
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
|
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
|
||||||
* bridge -> suspended bridge, aqueduct, etc
|
* bridge -> suspended bridge, aqueduct, etc
|
||||||
*/
|
*/
|
||||||
public Observable<List<DepictedItem>> getChildDepictions(String qid, int startPosition,
|
public Single<List<DepictedItem>> getChildDepictions(String qid, int startPosition,
|
||||||
int limit) throws IOException {
|
int limit) throws IOException {
|
||||||
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,"/queries/subclasses_query.rq"));
|
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,"/queries/subclasses_query.rq"));
|
||||||
}
|
}
|
||||||
|
|
@ -218,14 +218,14 @@ public class OkHttpJsonApiClient {
|
||||||
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
|
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
|
||||||
* bridge -> suspended bridge, aqueduct, etc
|
* bridge -> suspended bridge, aqueduct, etc
|
||||||
*/
|
*/
|
||||||
public Observable<List<DepictedItem>> getParentDepictions(String qid, int startPosition,
|
public Single<List<DepictedItem>> getParentDepictions(String qid, int startPosition,
|
||||||
int limit) throws IOException {
|
int limit) throws IOException {
|
||||||
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,
|
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,
|
||||||
"/queries/parentclasses_query.rq"));
|
"/queries/parentclasses_query.rq"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observable<List<DepictedItem>> depictedItemsFrom(Request request) {
|
private Single<List<DepictedItem>> depictedItemsFrom(Request request) {
|
||||||
return depictsClient.toDepictions(Observable.fromCallable(() -> {
|
return depictsClient.toDepictions(Single.fromCallable(() -> {
|
||||||
try (ResponseBody body = okHttpClient.newCall(request).execute().body()) {
|
try (ResponseBody body = okHttpClient.newCall(request).execute().body()) {
|
||||||
return gson.fromJson(body.string(), SparqlResponse.class);
|
return gson.fromJson(body.string(), SparqlResponse.class);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import fr.free.nrw.commons.nearby.Label
|
||||||
import fr.free.nrw.commons.nearby.Place
|
import fr.free.nrw.commons.nearby.Place
|
||||||
import fr.free.nrw.commons.nearby.Sitelinks
|
import fr.free.nrw.commons.nearby.Sitelinks
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
import fr.free.nrw.commons.wikidata.model.DepictSearchItem
|
||||||
import org.wikipedia.wikidata.*
|
import org.wikipedia.wikidata.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
@ -63,6 +64,14 @@ fun media(
|
||||||
depictionIds
|
depictionIds
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun depictSearchItem(
|
||||||
|
id: String = "id",
|
||||||
|
pageId: String = "pageid",
|
||||||
|
url: String = "url",
|
||||||
|
label: String = "label",
|
||||||
|
description: String = "description"
|
||||||
|
) = DepictSearchItem(id, pageId, url, label, description)
|
||||||
|
|
||||||
fun place(
|
fun place(
|
||||||
name: String = "name",
|
name: String = "name",
|
||||||
label: Label? = null,
|
label: Label? = null,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
|
import com.nhaarman.mockitokotlin2.mock
|
||||||
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
|
import depictSearchItem
|
||||||
|
import fr.free.nrw.commons.mwapi.Binding
|
||||||
|
import fr.free.nrw.commons.mwapi.Result
|
||||||
|
import fr.free.nrw.commons.mwapi.SparqlResponse
|
||||||
|
import fr.free.nrw.commons.upload.depicts.DepictsInterface
|
||||||
|
import fr.free.nrw.commons.wikidata.model.DepictSearchResponse
|
||||||
|
import io.reactivex.Single
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
import org.wikipedia.wikidata.Entities
|
||||||
|
|
||||||
|
class DepictsClientTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var depictsInterface: DepictsInterface
|
||||||
|
private lateinit var depictsClient: DepictsClient
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
depictsClient = DepictsClient(depictsInterface)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun searchForDepictions() {
|
||||||
|
val depictSearchResponse = mock<DepictSearchResponse>()
|
||||||
|
whenever(depictsInterface.searchForDepicts("query", "1", "en", "en", "0"))
|
||||||
|
.thenReturn(Single.just(depictSearchResponse))
|
||||||
|
whenever(depictSearchResponse.search).thenReturn(listOf(depictSearchItem("1"),depictSearchItem("2")))
|
||||||
|
val entities = mock<Entities>()
|
||||||
|
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
|
||||||
|
whenever(entities.entities()).thenReturn(emptyMap())
|
||||||
|
depictsClient.searchForDepictions("query", 1, 0)
|
||||||
|
.test()
|
||||||
|
.assertValue(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getEntities() {
|
||||||
|
val entities = mock<Entities>()
|
||||||
|
whenever(depictsInterface.getEntities("ids")).thenReturn(Single.just(entities))
|
||||||
|
depictsClient.getEntities("ids").test().assertValue(entities)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun toDepictions() {
|
||||||
|
val sparqlResponse = mock<SparqlResponse>()
|
||||||
|
val result = mock<Result>()
|
||||||
|
whenever(sparqlResponse.results).thenReturn(result)
|
||||||
|
val binding1 = mock<Binding>()
|
||||||
|
val binding2 = mock<Binding>()
|
||||||
|
whenever(result.bindings).thenReturn(listOf(binding1, binding2))
|
||||||
|
whenever(binding1.id).thenReturn("1")
|
||||||
|
whenever(binding2.id).thenReturn("2")
|
||||||
|
val entities = mock<Entities>()
|
||||||
|
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
|
||||||
|
whenever(entities.entities()).thenReturn(emptyMap())
|
||||||
|
depictsClient.toDepictions(Single.just(sparqlResponse))
|
||||||
|
.test()
|
||||||
|
.assertValue(emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
package fr.free.nrw.commons.explore.depictions.child
|
package fr.free.nrw.commons.explore.depictions.child
|
||||||
|
|
||||||
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
|
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import depictedItem
|
import depictedItem
|
||||||
import fr.free.nrw.commons.explore.paging.LiveDataConverter
|
import fr.free.nrw.commons.explore.paging.LiveDataConverter
|
||||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Single
|
||||||
import org.hamcrest.CoreMatchers.`is`
|
import org.hamcrest.CoreMatchers.`is`
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -30,7 +29,7 @@ class PageableChildDepictionsDataSourceTest {
|
||||||
PageableChildDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
|
PageableChildDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
|
||||||
dataSource.onQueryUpdated("test")
|
dataSource.onQueryUpdated("test")
|
||||||
whenever(okHttpJsonApiClient.getChildDepictions("test", 0, 1))
|
whenever(okHttpJsonApiClient.getChildDepictions("test", 0, 1))
|
||||||
.thenReturn(Observable.just(listOf(depictedItem())))
|
.thenReturn(Single.just(listOf(depictedItem())))
|
||||||
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
|
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import com.nhaarman.mockitokotlin2.whenever
|
||||||
import depictedItem
|
import depictedItem
|
||||||
import fr.free.nrw.commons.explore.paging.LiveDataConverter
|
import fr.free.nrw.commons.explore.paging.LiveDataConverter
|
||||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Single
|
||||||
import org.hamcrest.CoreMatchers.`is`
|
import org.hamcrest.CoreMatchers.`is`
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -30,7 +30,7 @@ class PageableParentDepictionsDataSourceTest {
|
||||||
PageableParentDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
|
PageableParentDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
|
||||||
dataSource.onQueryUpdated("test")
|
dataSource.onQueryUpdated("test")
|
||||||
whenever(okHttpJsonApiClient.getParentDepictions("test", 0, 1))
|
whenever(okHttpJsonApiClient.getParentDepictions("test", 0, 1))
|
||||||
.thenReturn(Observable.just(listOf(depictedItem())))
|
.thenReturn(Single.just(listOf(depictedItem())))
|
||||||
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
|
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue