diff --git a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt index 0ed29cc46..1dd28f1fb 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt @@ -36,7 +36,7 @@ data class DepictedItem constructor( place.longDescription ) - constructor(entity: Entities.Entity, name: String, description: String) : this( + private constructor(entity: Entities.Entity, name: String, description: String) : this( name, description, entity[IMAGE].primaryImageValue?.let { @@ -69,7 +69,7 @@ private fun List?.toIds(): List { } private val List?.primaryImageValue: DataValue.ValueString? - get() = this?.first()?.mainSnak?.dataValue as? DataValue.ValueString + get() = this?.firstOrNull()?.mainSnak?.dataValue as? DataValue.ValueString operator fun Entities.Entity.get(property: WikidataProperties) = statements?.get(property.propertyName) diff --git a/app/src/test/kotlin/ModelFunctions.kt b/app/src/test/kotlin/ModelFunctions.kt index 269f8f977..a0eaedd4e 100644 --- a/app/src/test/kotlin/ModelFunctions.kt +++ b/app/src/test/kotlin/ModelFunctions.kt @@ -1,5 +1,12 @@ +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever import fr.free.nrw.commons.category.CategoryItem +import fr.free.nrw.commons.location.LatLng +import fr.free.nrw.commons.nearby.Label +import fr.free.nrw.commons.nearby.Place +import fr.free.nrw.commons.nearby.Sitelinks import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import org.wikipedia.wikidata.* fun depictedItem( name: String = "label", @@ -21,3 +28,59 @@ fun depictedItem( fun categoryItem(name: String = "name", selected: Boolean = false) = CategoryItem(name, selected) + +fun place( + name: String = "name", + label: Label? = null, + longDescription: String = "longDescription", + latLng: LatLng? = null, + category: String = "category", + siteLinks: Sitelinks? = null, + pic: String = "pic", + destroyed: String = "destroyed" +): Place { + return Place(name, label, longDescription, latLng, category, siteLinks, pic, destroyed) +} + +fun entityId(wikiBaseEntityValue: WikiBaseEntityValue = wikiBaseEntityValue()) = + DataValue.EntityId(wikiBaseEntityValue) + +fun wikiBaseEntityValue( + entityType: String = "type", + id: String = "id", + numericId: Long = 0 +) = WikiBaseEntityValue(entityType, id, numericId) + +fun statement( + mainSnak: Snak_partial = snak(), + rank: String = "rank", + type: String = "type" +) = Statement_partial(mainSnak, type, rank) + +fun snak( + snakType: String = "type", + property: String = "property", + dataValue: DataValue = valueString("") +) = Snak_partial(snakType, property, dataValue) + +fun valueString(value: String) = DataValue.ValueString(value) + +fun entity( + labels: Map = emptyMap(), + descriptions: Map = emptyMap(), + statements: Map>? = emptyMap(), + id: String = "id" +) = mock().apply { + val mockedLabels = labels.mockLabels() + whenever(labels()).thenReturn(mockedLabels) + val mockedDescriptions = descriptions.mockLabels() + whenever(descriptions()).thenReturn(mockedDescriptions) + whenever(this.statements).thenReturn(statements) + whenever(id()).thenReturn(id) +} + +private fun Map.mockLabels(): Map { + return mapValues { entry -> + mock().also { whenever(it.value()).thenReturn(entry.value) } + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/upload/structure/depictions/DepictedItemTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/upload/structure/depictions/DepictedItemTest.kt new file mode 100644 index 000000000..34e43272e --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/upload/structure/depictions/DepictedItemTest.kt @@ -0,0 +1,178 @@ +package fr.free.nrw.commons.upload.structure.depictions + +import com.nhaarman.mockitokotlin2.mock +import depictedItem +import entity +import entityId +import fr.free.nrw.commons.wikidata.WikidataProperties +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.CoreMatchers.not +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.nullValue +import org.junit.Test +import place +import snak +import statement +import valueString +import wikiBaseEntityValue + +class DepictedItemTest { + + @Test + fun `name and description get user language label`() { + val depictedItem = + DepictedItem(entity(mapOf("en" to "label"), mapOf("en" to "description"))) + assertThat(depictedItem.name, `is`("label")) + assertThat(depictedItem.description, `is`("description")) + } + + @Test + fun `name and descriptions get first language label if user language not present`() { + val depictedItem = DepictedItem(entity(mapOf("" to "label"), mapOf("" to "description"))) + assertThat(depictedItem.name, `is`("label")) + assertThat(depictedItem.description, `is`("description")) + } + + @Test + fun `name and descriptions get empty if nothing present`() { + val depictedItem = DepictedItem(entity()) + assertThat(depictedItem.name, `is`("")) + assertThat(depictedItem.description, `is`("")) + } + + @Test + fun `image is empty with null statements`() { + assertThat(DepictedItem(entity(statements = null)).imageUrl, nullValue()) + } + + @Test + fun `image is empty with no image statement`() { + assertThat(DepictedItem(entity()).imageUrl, nullValue()) + } + + @Test + fun `image is empty with dataValue not of ValueString type`() { + assertThat( + DepictedItem( + entity( + statements = mapOf( + WikidataProperties.IMAGE.propertyName to listOf(statement(snak(dataValue = mock()))) + ) + ) + ).imageUrl, + nullValue() + ) + } + + @Test + fun `image is not empty with dataValue of ValueString type`() { + assertThat( + DepictedItem( + entity( + statements = mapOf( + WikidataProperties.IMAGE.propertyName to listOf( + statement(snak(dataValue = valueString("prefix: example_"))) + ) + ) + ) + ).imageUrl, + `is`("https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/_example_/70px-_example_") + ) + } + + @Test + fun `instancesOf maps EntityIds to ids`() { + assertThat( + DepictedItem( + entity( + statements = mapOf( + WikidataProperties.INSTANCE_OF.propertyName to listOf( + statement(snak(dataValue = valueString("prefix: example_"))), + statement(snak(dataValue = entityId(wikiBaseEntityValue(id = "1")))), + statement(snak(dataValue = entityId(wikiBaseEntityValue(id = "2")))) + ) + ) + ) + ).instanceOfs, + `is`(listOf("1", "2"))) + } + + @Test + fun `instancesOf is empty with no values`() { + assertThat(DepictedItem(entity()).instanceOfs, `is`(emptyList())) + } + + @Test + fun `commonsCategory maps ValueString to strings`() { + assertThat( + DepictedItem( + entity( + statements = mapOf( + WikidataProperties.COMMONS_CATEGORY.propertyName to listOf( + statement(snak(dataValue = valueString("1"))), + statement(snak(dataValue = valueString("2"))) + ) + ) + ) + ).commonsCategories, + `is`(listOf("1", "2"))) + } + + @Test + fun `commonsCategory is empty with no values`() { + assertThat(DepictedItem(entity()).commonsCategories, `is`(emptyList())) + } + + @Test + fun `isSelected is false at creation`() { + assertThat(DepictedItem(entity()).isSelected, `is`(false)) + } + + @Test + fun `id is entityId`() { + assertThat(DepictedItem(entity(id = "1")).id, `is`("1")) + } + + @Test + fun `place constructor uses place name and longDescription`() { + val depictedItem = DepictedItem(entity(), place(name = "1", longDescription = "2")) + assertThat(depictedItem.name, `is`("1")) + assertThat(depictedItem.description, `is`("2")) + } + + + @Test + fun `same object is Equal`() { + val depictedItem = depictedItem() + assertThat(depictedItem == depictedItem, `is`(true)) + } + + @Test + fun `different type is not Equal`() { + assertThat(depictedItem().equals(Unit), `is`(false)) + } + + @Test + fun `if names are equal is Equal`() { + assertThat( + depictedItem(name="a", id = "0") == depictedItem(name="a", id = "1"), + `is`(true)) + } + + @Test + fun `if names are not equal is not Equal`() { + assertThat( + depictedItem(name="a") == depictedItem(name="b"), + `is`(false)) + } + + @Test + fun `hashCode returns same values for objects with same name`() { + assertThat(depictedItem(name="a").hashCode(), `is`(depictedItem(name="a").hashCode())) + } + + @Test + fun `hashCode returns different values for objects with different name`() { + assertThat(depictedItem(name="a").hashCode(), not(depictedItem(name="b").hashCode())) + } +}