Skip to content

Commit 542d321

Browse files
authored
#3841 Unit Test DepictsClient (#3842)
* #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
1 parent 9d59915 commit 542d321

File tree

8 files changed

+100
-25
lines changed

8 files changed

+100
-25
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package fr.free.nrw.commons.explore.depictions
22

3+
import fr.free.nrw.commons.mwapi.Binding
34
import fr.free.nrw.commons.mwapi.SparqlResponse
45
import fr.free.nrw.commons.upload.depicts.DepictsInterface
56
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
6-
import io.reactivex.Observable
7+
import fr.free.nrw.commons.wikidata.model.DepictSearchItem
78
import io.reactivex.Single
89
import org.wikipedia.wikidata.Entities
910
import java.util.*
@@ -14,9 +15,7 @@ import javax.inject.Singleton
1415
* Depicts Client to handle custom calls to Commons Wikibase APIs
1516
*/
1617
@Singleton
17-
class DepictsClient @Inject constructor(
18-
private val depictsInterface: DepictsInterface
19-
) {
18+
class DepictsClient @Inject constructor(private val depictsInterface: DepictsInterface) {
2019

2120
/**
2221
* Search for depictions using the search item
@@ -25,22 +24,21 @@ class DepictsClient @Inject constructor(
2524
fun searchForDepictions(query: String?, limit: Int, offset: Int): Single<List<DepictedItem>> {
2625
val language = Locale.getDefault().language
2726
return depictsInterface.searchForDepicts(query, "$limit", language, language, "$offset")
28-
.map { it.search.joinToString("|") { searchItem -> searchItem.id } }
29-
.flatMap(::getEntities)
30-
.map { it.entities().values.map(::DepictedItem) }
27+
.map { it.search.joinToString("|", transform = DepictSearchItem::id) }
28+
.mapToDepictions()
3129
}
3230

3331
fun getEntities(ids: String): Single<Entities> {
3432
return depictsInterface.getEntities(ids)
3533
}
3634

37-
fun toDepictions(sparqlResponse: Observable<SparqlResponse>): Observable<List<DepictedItem>> {
35+
fun toDepictions(sparqlResponse: Single<SparqlResponse>): Single<List<DepictedItem>> {
3836
return sparqlResponse.map {
39-
it.results.bindings.joinToString("|") { binding ->
40-
binding.id
41-
}
42-
}
43-
.flatMap { getEntities(it).toObservable() }
44-
.map { it.entities().values.map(::DepictedItem) }
37+
it.results.bindings.joinToString("|", transform = Binding::id)
38+
}.mapToDepictions()
4539
}
40+
41+
private fun Single<String>.mapToDepictions() =
42+
flatMap(::getEntities)
43+
.map { it.entities().values.map(::DepictedItem) }
4644
}

app/src/main/java/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSource.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class PageableChildDepictionsDataSource @Inject constructor(
1111
private val okHttpJsonApiClient: OkHttpJsonApiClient
1212
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
1313
override val loadFunction = { limit: Int, startPosition: Int ->
14-
okHttpJsonApiClient.getChildDepictions(query, startPosition, limit).blockingFirst()
14+
okHttpJsonApiClient.getChildDepictions(query, startPosition, limit).blockingGet()
1515
}
1616
}
1717

app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSource.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class PageableParentDepictionsDataSource @Inject constructor(
1111
private val okHttpJsonApiClient: OkHttpJsonApiClient
1212
) : PageableBaseDataSource<DepictedItem>(liveDataConverter) {
1313
override val loadFunction = { limit: Int, startPosition: Int ->
14-
okHttpJsonApiClient.getParentDepictions(query, startPosition, limit).blockingFirst()
14+
okHttpJsonApiClient.getParentDepictions(query, startPosition, limit).blockingGet()
1515
}
1616
}
1717

app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ public Observable<List<Place>> getNearbyPlaces(LatLng cur, String language, doub
209209
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
210210
* bridge -> suspended bridge, aqueduct, etc
211211
*/
212-
public Observable<List<DepictedItem>> getChildDepictions(String qid, int startPosition,
212+
public Single<List<DepictedItem>> getChildDepictions(String qid, int startPosition,
213213
int limit) throws IOException {
214214
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,"/queries/subclasses_query.rq"));
215215
}
@@ -218,14 +218,14 @@ public Observable<List<DepictedItem>> getChildDepictions(String qid, int startPo
218218
* Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example:
219219
* bridge -> suspended bridge, aqueduct, etc
220220
*/
221-
public Observable<List<DepictedItem>> getParentDepictions(String qid, int startPosition,
221+
public Single<List<DepictedItem>> getParentDepictions(String qid, int startPosition,
222222
int limit) throws IOException {
223223
return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,
224224
"/queries/parentclasses_query.rq"));
225225
}
226226

227-
private Observable<List<DepictedItem>> depictedItemsFrom(Request request) {
228-
return depictsClient.toDepictions(Observable.fromCallable(() -> {
227+
private Single<List<DepictedItem>> depictedItemsFrom(Request request) {
228+
return depictsClient.toDepictions(Single.fromCallable(() -> {
229229
try (ResponseBody body = okHttpClient.newCall(request).execute().body()) {
230230
return gson.fromJson(body.string(), SparqlResponse.class);
231231
}

app/src/test/kotlin/ModelFunctions.kt

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import fr.free.nrw.commons.nearby.Label
77
import fr.free.nrw.commons.nearby.Place
88
import fr.free.nrw.commons.nearby.Sitelinks
99
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
10+
import fr.free.nrw.commons.wikidata.model.DepictSearchItem
1011
import org.wikipedia.wikidata.*
1112
import java.util.*
1213

@@ -63,6 +64,14 @@ fun media(
6364
depictionIds
6465
)
6566

67+
fun depictSearchItem(
68+
id: String = "id",
69+
pageId: String = "pageid",
70+
url: String = "url",
71+
label: String = "label",
72+
description: String = "description"
73+
) = DepictSearchItem(id, pageId, url, label, description)
74+
6675
fun place(
6776
name: String = "name",
6877
label: Label? = null,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package fr.free.nrw.commons.explore.depictions
2+
3+
import com.nhaarman.mockitokotlin2.mock
4+
import com.nhaarman.mockitokotlin2.whenever
5+
import depictSearchItem
6+
import fr.free.nrw.commons.mwapi.Binding
7+
import fr.free.nrw.commons.mwapi.Result
8+
import fr.free.nrw.commons.mwapi.SparqlResponse
9+
import fr.free.nrw.commons.upload.depicts.DepictsInterface
10+
import fr.free.nrw.commons.wikidata.model.DepictSearchResponse
11+
import io.reactivex.Single
12+
import org.junit.Before
13+
import org.junit.Test
14+
import org.mockito.Mock
15+
import org.mockito.MockitoAnnotations
16+
import org.wikipedia.wikidata.Entities
17+
18+
class DepictsClientTest {
19+
20+
@Mock
21+
private lateinit var depictsInterface: DepictsInterface
22+
private lateinit var depictsClient: DepictsClient
23+
24+
@Before
25+
fun setUp() {
26+
MockitoAnnotations.initMocks(this)
27+
depictsClient = DepictsClient(depictsInterface)
28+
}
29+
30+
@Test
31+
fun searchForDepictions() {
32+
val depictSearchResponse = mock<DepictSearchResponse>()
33+
whenever(depictsInterface.searchForDepicts("query", "1", "en", "en", "0"))
34+
.thenReturn(Single.just(depictSearchResponse))
35+
whenever(depictSearchResponse.search).thenReturn(listOf(depictSearchItem("1"),depictSearchItem("2")))
36+
val entities = mock<Entities>()
37+
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
38+
whenever(entities.entities()).thenReturn(emptyMap())
39+
depictsClient.searchForDepictions("query", 1, 0)
40+
.test()
41+
.assertValue(emptyList())
42+
}
43+
44+
45+
@Test
46+
fun getEntities() {
47+
val entities = mock<Entities>()
48+
whenever(depictsInterface.getEntities("ids")).thenReturn(Single.just(entities))
49+
depictsClient.getEntities("ids").test().assertValue(entities)
50+
}
51+
52+
@Test
53+
fun toDepictions() {
54+
val sparqlResponse = mock<SparqlResponse>()
55+
val result = mock<Result>()
56+
whenever(sparqlResponse.results).thenReturn(result)
57+
val binding1 = mock<Binding>()
58+
val binding2 = mock<Binding>()
59+
whenever(result.bindings).thenReturn(listOf(binding1, binding2))
60+
whenever(binding1.id).thenReturn("1")
61+
whenever(binding2.id).thenReturn("2")
62+
val entities = mock<Entities>()
63+
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
64+
whenever(entities.entities()).thenReturn(emptyMap())
65+
depictsClient.toDepictions(Single.just(sparqlResponse))
66+
.test()
67+
.assertValue(emptyList())
68+
}
69+
}

app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSourceTest.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package fr.free.nrw.commons.explore.depictions.child
22

3-
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
43
import com.nhaarman.mockitokotlin2.whenever
54
import depictedItem
65
import fr.free.nrw.commons.explore.paging.LiveDataConverter
76
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
8-
import io.reactivex.Observable
7+
import io.reactivex.Single
98
import org.hamcrest.CoreMatchers.`is`
109
import org.hamcrest.MatcherAssert.assertThat
1110
import org.junit.Before
@@ -30,7 +29,7 @@ class PageableChildDepictionsDataSourceTest {
3029
PageableChildDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
3130
dataSource.onQueryUpdated("test")
3231
whenever(okHttpJsonApiClient.getChildDepictions("test", 0, 1))
33-
.thenReturn(Observable.just(listOf(depictedItem())))
32+
.thenReturn(Single.just(listOf(depictedItem())))
3433
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
3534
}
3635
}

app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSourceTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.nhaarman.mockitokotlin2.whenever
44
import depictedItem
55
import fr.free.nrw.commons.explore.paging.LiveDataConverter
66
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
7-
import io.reactivex.Observable
7+
import io.reactivex.Single
88
import org.hamcrest.CoreMatchers.`is`
99
import org.hamcrest.MatcherAssert.assertThat
1010
import org.junit.Before
@@ -30,7 +30,7 @@ class PageableParentDepictionsDataSourceTest {
3030
PageableParentDepictionsDataSource(liveDataConverter, okHttpJsonApiClient)
3131
dataSource.onQueryUpdated("test")
3232
whenever(okHttpJsonApiClient.getParentDepictions("test", 0, 1))
33-
.thenReturn(Observable.just(listOf(depictedItem())))
33+
.thenReturn(Single.just(listOf(depictedItem())))
3434
assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem())))
3535
}
3636
}

0 commit comments

Comments
 (0)