mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Fixes 4539 : When Wikidata has no description showing instance_of's label as a description (#4799)
* Showing instance_of's name as a description * Indentation fixed * DepictsClient Test added
This commit is contained in:
parent
c2bc5b4f23
commit
27e3f20ba2
4 changed files with 101 additions and 8 deletions
|
|
@ -1,12 +1,17 @@
|
|||
package fr.free.nrw.commons.explore.depictions
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import fr.free.nrw.commons.mwapi.Binding
|
||||
import fr.free.nrw.commons.mwapi.SparqlResponse
|
||||
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.get
|
||||
import fr.free.nrw.commons.wikidata.WikidataProperties
|
||||
import fr.free.nrw.commons.wikidata.model.DepictSearchItem
|
||||
import io.reactivex.Single
|
||||
import org.wikipedia.wikidata.DataValue
|
||||
import org.wikipedia.wikidata.Entities
|
||||
import org.wikipedia.wikidata.Statement_partial
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -38,7 +43,50 @@ class DepictsClient @Inject constructor(private val depictsInterface: DepictsInt
|
|||
}.mapToDepictions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches Entities from ids ex. "Q1233|Q546" and converts them into DepictedItem
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private fun Single<String>.mapToDepictions() =
|
||||
flatMap(::getEntities)
|
||||
.map { it.entities().values.map(::DepictedItem) }
|
||||
.map { entities ->
|
||||
entities.entities().values.map { entity ->
|
||||
if (entity.descriptions().byLanguageOrFirstOrEmpty() == "") {
|
||||
val entities: Entities = getEntities(entity[WikidataProperties.INSTANCE_OF]
|
||||
.toIds()[0]).blockingGet()
|
||||
val nameAsDescription = entities.entities().values.first().labels()
|
||||
.byLanguageOrFirstOrEmpty()
|
||||
DepictedItem(
|
||||
entity,
|
||||
entity.labels().byLanguageOrFirstOrEmpty(),
|
||||
nameAsDescription
|
||||
)
|
||||
} else {
|
||||
DepictedItem(
|
||||
entity,
|
||||
entity.labels().byLanguageOrFirstOrEmpty(),
|
||||
entity.descriptions().byLanguageOrFirstOrEmpty()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to get Entities.Label by default language from the map.
|
||||
* If that returns null, Tries to retrieve first element from the map.
|
||||
* If that still returns null, function returns "".
|
||||
*/
|
||||
private fun Map<String, Entities.Label>.byLanguageOrFirstOrEmpty() =
|
||||
let {
|
||||
it[Locale.getDefault().language] ?: it.values.firstOrNull() }?.value() ?: ""
|
||||
|
||||
/**
|
||||
* returns list of id ex. "Q2323" from Statement_partial
|
||||
*/
|
||||
private fun List<Statement_partial>?.toIds(): List<String> {
|
||||
return this?.map { it.mainSnak.dataValue }
|
||||
?.filterIsInstance<DataValue.EntityId>()
|
||||
?.map { it.value.id }
|
||||
?: emptyList()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ data class DepictedItem constructor(
|
|||
place.longDescription
|
||||
)
|
||||
|
||||
private constructor(entity: Entities.Entity, name: String, description: String) : this(
|
||||
constructor(entity: Entities.Entity, name: String, description: String) : this(
|
||||
name,
|
||||
description,
|
||||
entity[IMAGE].primaryImageValue?.let {
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ 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.upload.structure.depictions.DepictedItem
|
||||
import fr.free.nrw.commons.wikidata.model.DepictSearchResponse
|
||||
import io.reactivex.Single
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.wikipedia.wikidata.Entities
|
||||
import org.wikipedia.wikidata.*
|
||||
|
||||
class DepictsClientTest {
|
||||
|
||||
|
|
@ -29,7 +29,6 @@ class DepictsClientTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore()
|
||||
fun searchForDepictions() {
|
||||
val depictSearchResponse = mock<DepictSearchResponse>()
|
||||
whenever(depictsInterface.searchForDepicts("query", "1", "en", "en", "0"))
|
||||
|
|
@ -52,7 +51,7 @@ class DepictsClientTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun toDepictions() {
|
||||
fun `Test toDepictions when description is empty`() {
|
||||
val sparqlResponse = mock<SparqlResponse>()
|
||||
val result = mock<Result>()
|
||||
whenever(sparqlResponse.results).thenReturn(result)
|
||||
|
|
@ -62,10 +61,51 @@ class DepictsClientTest {
|
|||
whenever(binding1.id).thenReturn("1")
|
||||
whenever(binding2.id).thenReturn("2")
|
||||
val entities = mock<Entities>()
|
||||
val entity = mock<Entities.Entity>()
|
||||
val statementPartial = mock<Statement_partial>()
|
||||
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
|
||||
whenever(entities.entities()).thenReturn(emptyMap())
|
||||
whenever(entities.entities()).thenReturn(mapOf("en" to entity))
|
||||
whenever(entity.statements).thenReturn(mapOf("P31" to listOf(statementPartial)))
|
||||
whenever(statementPartial.mainSnak).thenReturn(
|
||||
Snak_partial("test", "P31",
|
||||
DataValue.EntityId(
|
||||
WikiBaseEntityValue("wikibase-entityid", "Q10", 10L)
|
||||
)
|
||||
)
|
||||
)
|
||||
whenever(depictsInterface.getEntities("Q10")).thenReturn(Single.just(entities))
|
||||
whenever(entity.id()).thenReturn("Q10")
|
||||
depictsClient.toDepictions(Single.just(sparqlResponse))
|
||||
.test()
|
||||
.assertValue(emptyList())
|
||||
.assertValue(listOf(
|
||||
DepictedItem("", "", null,
|
||||
listOf("Q10"), emptyList(), false, "Q10")
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test toDepictions when description is not empty`() {
|
||||
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>()
|
||||
val entity = mock<Entities.Entity>()
|
||||
whenever(depictsInterface.getEntities("1|2")).thenReturn(Single.just(entities))
|
||||
whenever(entities.entities()).thenReturn(mapOf("en" to entity))
|
||||
whenever(entity.descriptions()).thenReturn(mapOf("en" to
|
||||
Entities.Label("en", "Test description")
|
||||
))
|
||||
whenever(entity.id()).thenReturn("Q10")
|
||||
depictsClient.toDepictions(Single.just(sparqlResponse))
|
||||
.test()
|
||||
.assertValue(listOf(
|
||||
DepictedItem("", "", null, listOf("Q10"),
|
||||
emptyList(), false, "Q10")
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,11 @@ public class Entities extends MwResponse implements PostProcessingTypeAdapter.Po
|
|||
@Nullable private String language;
|
||||
@Nullable private String value;
|
||||
|
||||
public Label(@Nullable final String language, @Nullable final String value) {
|
||||
this.language = language;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@NonNull public String language() {
|
||||
return StringUtils.defaultString(language);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue