diff --git a/ground/src/main/java/com/google/android/ground/Config.kt b/ground/src/main/java/com/google/android/ground/Config.kt index 238d04befc..c9c862e8ab 100644 --- a/ground/src/main/java/com/google/android/ground/Config.kt +++ b/ground/src/main/java/com/google/android/ground/Config.kt @@ -26,7 +26,7 @@ object Config { // Local db settings. // TODO(#128): Reset version to 1 before releasing. - const val DB_VERSION = 109 + const val DB_VERSION = 110 const val DB_NAME = "ground.db" // Firebase Cloud Firestore settings. diff --git a/ground/src/main/java/com/google/android/ground/model/locationofinterest/LocationOfInterest.kt b/ground/src/main/java/com/google/android/ground/model/locationofinterest/LocationOfInterest.kt index e358c21de5..438c23eab1 100644 --- a/ground/src/main/java/com/google/android/ground/model/locationofinterest/LocationOfInterest.kt +++ b/ground/src/main/java/com/google/android/ground/model/locationofinterest/LocationOfInterest.kt @@ -22,6 +22,9 @@ import com.google.android.ground.model.mutation.LocationOfInterestMutation import com.google.android.ground.model.mutation.Mutation import com.google.android.ground.model.mutation.Mutation.SyncStatus +/** Alias for a map of properties with string names. */ +typealias LoiProperties = Map + /** User-defined locations of interest (LOI) shown on the map. */ data class LocationOfInterest( /** A system-defined ID for this LOI. */ @@ -31,9 +34,7 @@ data class LocationOfInterest( /** The job associated with this LOI. */ val job: Job, /** A user-specified ID for this location of interest. */ - val customId: String? = null, - /** A human readable caption for this location of interest. */ - val caption: String? = null, + val customId: String = "", /** User and time audit info pertaining to the creation of this LOI. */ val created: AuditInfo, /** User and time audit info pertaining to the last modification of this LOI. */ @@ -51,7 +52,9 @@ data class LocationOfInterest( * Whether this LOI was created opportunistically by the user through the Suggest LOI flow, or * false if the LOI was created by the survey organizer. */ - val isOpportunistic: Boolean = false + val isOpportunistic: Boolean = false, + /** Custom map of properties for this LOI. Corresponds to the properties field in GeoJSON */ + val properties: LoiProperties = mapOf(), ) { /** @@ -66,11 +69,12 @@ data class LocationOfInterest( surveyId = surveyId, locationOfInterestId = id, userId = userId, + customId = customId, clientTimestamp = lastModified.clientTimestamp, geometry = geometry, - caption = caption, submissionCount = submissionCount, ownerEmail = ownerEmail, - isOpportunistic = isOpportunistic + isOpportunistic = isOpportunistic, + properties = properties ) } diff --git a/ground/src/main/java/com/google/android/ground/model/mutation/LocationOfInterestMutation.kt b/ground/src/main/java/com/google/android/ground/model/mutation/LocationOfInterestMutation.kt index b3756fb0ec..dcc34d1f49 100644 --- a/ground/src/main/java/com/google/android/ground/model/mutation/LocationOfInterestMutation.kt +++ b/ground/src/main/java/com/google/android/ground/model/mutation/LocationOfInterestMutation.kt @@ -16,6 +16,7 @@ package com.google.android.ground.model.mutation import com.google.android.ground.model.geometry.Geometry +import com.google.android.ground.model.locationofinterest.LoiProperties import java.util.Date data class LocationOfInterestMutation( @@ -29,9 +30,10 @@ data class LocationOfInterestMutation( override val retryCount: Long = 0, override val lastError: String = "", val jobId: String = "", + val customId: String = "", val geometry: Geometry? = null, - val caption: String? = null, val submissionCount: Int = 0, val ownerEmail: String? = null, - val isOpportunistic: Boolean = false + val isOpportunistic: Boolean = false, + val properties: LoiProperties = mapOf(), ) : Mutation() diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/LocalDatabase.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/LocalDatabase.kt index efcffa9413..5e4d34ba10 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/local/room/LocalDatabase.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/LocalDatabase.kt @@ -22,6 +22,7 @@ import com.google.android.ground.Config import com.google.android.ground.persistence.local.room.converter.GeometryWrapperTypeConverter import com.google.android.ground.persistence.local.room.converter.JsonArrayTypeConverter import com.google.android.ground.persistence.local.room.converter.JsonObjectTypeConverter +import com.google.android.ground.persistence.local.room.converter.LoiPropertiesMapConverter import com.google.android.ground.persistence.local.room.converter.StyleTypeConverter import com.google.android.ground.persistence.local.room.dao.* import com.google.android.ground.persistence.local.room.entity.* @@ -64,7 +65,8 @@ import com.google.android.ground.persistence.local.room.fields.* MutationEntitySyncStatus::class, OfflineAreaEntityState::class, StyleTypeConverter::class, - TileSetEntityState::class + TileSetEntityState::class, + LoiPropertiesMapConverter::class, ) abstract class LocalDatabase : RoomDatabase() { abstract fun locationOfInterestDao(): LocationOfInterestDao diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/ConverterExt.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/ConverterExt.kt index 806cd801a8..c1f140707e 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/ConverterExt.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/ConverterExt.kt @@ -130,13 +130,14 @@ fun LocationOfInterest.toLocalDataStoreObject() = surveyId = surveyId, jobId = job.id, state = EntityState.DEFAULT, - caption = caption, created = created.toLocalDataStoreObject(), lastModified = lastModified.toLocalDataStoreObject(), geometry = geometry.toLocalDataStoreObject(), + customId = customId, submissionCount = submissionCount, ownerEmail = ownerEmail, - isOpportunistic = isOpportunistic + isOpportunistic = isOpportunistic, + properties = properties, ) fun LocationOfInterestEntity.toModelObject(survey: Survey): LocationOfInterest = @@ -148,9 +149,10 @@ fun LocationOfInterestEntity.toModelObject(survey: Survey): LocationOfInterest = surveyId = surveyId, created = created.toModelObject(), lastModified = lastModified.toModelObject(), - caption = caption, + customId = customId, geometry = geometry.getGeometry(), submissionCount = submissionCount, + properties = properties, job = survey.getJob(jobId = jobId) ?: throw LocalDataConsistencyException( "Unknown jobId ${this.jobId} in location of interest ${this.id}" @@ -173,14 +175,15 @@ fun LocationOfInterestMutation.toLocalDataStoreObject(user: User): LocationOfInt surveyId = surveyId, jobId = jobId, state = EntityState.DEFAULT, - caption = caption, // TODO(#1562): Preserve creation audit info for UPDATE mutations. created = auditInfo, lastModified = auditInfo, geometry = geometry?.toLocalDataStoreObject(), + customId = customId, submissionCount = submissionCount, ownerEmail = ownerEmail, - isOpportunistic = isOpportunistic + isOpportunistic = isOpportunistic, + properties = properties ) } @@ -191,13 +194,14 @@ fun LocationOfInterestMutation.toLocalDataStoreObject() = jobId = jobId, type = MutationEntityType.fromMutationType(type), newGeometry = geometry?.toLocalDataStoreObject(), - caption = caption, + newCustomId = customId, userId = userId, locationOfInterestId = locationOfInterestId, syncStatus = MutationEntitySyncStatus.fromMutationSyncStatus(syncStatus), clientTimestamp = clientTimestamp.time, lastError = lastError, - retryCount = retryCount + retryCount = retryCount, + newProperties = properties ) fun LocationOfInterestMutationEntity.toModelObject() = @@ -207,13 +211,14 @@ fun LocationOfInterestMutationEntity.toModelObject() = jobId = jobId, type = type.toMutationType(), geometry = newGeometry?.getGeometry(), - caption = caption, + customId = newCustomId, userId = userId, locationOfInterestId = locationOfInterestId, syncStatus = syncStatus.toMutationSyncStatus(), clientTimestamp = Date(clientTimestamp), lastError = lastError, retryCount = retryCount, + properties = newProperties ) fun MultipleChoiceEntity.toModelObject(optionEntities: List): MultipleChoice { diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/LoiPropertiesMapConverter.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/LoiPropertiesMapConverter.kt new file mode 100644 index 0000000000..ced2c94265 --- /dev/null +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/converter/LoiPropertiesMapConverter.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.ground.persistence.local.room.converter + +import androidx.room.TypeConverter +import com.google.common.reflect.TypeToken +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException +import kotlinx.collections.immutable.toPersistentMap +import org.json.JSONException +import org.json.JSONObject +import timber.log.Timber + +object LoiPropertiesMapConverter { + @TypeConverter + fun toString(properties: Map): String { + var jsonString = "" + try { + jsonString = JSONObject(properties).toString() + } catch (e: JSONException) { + Timber.e(e, "Error building JSON") + } + return jsonString + } + + @TypeConverter + fun fromString(jsonString: String): Map { + var map = mutableMapOf() + try { + val type = object : TypeToken>() {}.type + map = Gson().fromJson(jsonString, type) + } catch (e: JsonSyntaxException) { + Timber.e(e, "Error parsing JSON string") + } + return map.toPersistentMap() + } +} diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestEntity.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestEntity.kt index d3f6d78a96..44e078ca59 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestEntity.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestEntity.kt @@ -16,6 +16,7 @@ package com.google.android.ground.persistence.local.room.entity import androidx.room.* +import com.google.android.ground.model.locationofinterest.LoiProperties import com.google.android.ground.persistence.local.room.fields.EntityState /** @@ -28,11 +29,12 @@ data class LocationOfInterestEntity( @ColumnInfo(name = "survey_id") val surveyId: String, @ColumnInfo(name = "job_id") val jobId: String, @ColumnInfo(name = "state") val state: EntityState, // TODO: Rename to DeletionState. - @ColumnInfo(name = "caption") val caption: String?, @Embedded(prefix = "created_") val created: AuditInfoEntity, @Embedded(prefix = "modified_") val lastModified: AuditInfoEntity, val geometry: GeometryWrapper?, + val customId: String, val submissionCount: Int, val ownerEmail: String?, - val isOpportunistic: Boolean + val isOpportunistic: Boolean, + val properties: LoiProperties, ) diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestMutationEntity.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestMutationEntity.kt index cf904d65c1..5187111397 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestMutationEntity.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/LocationOfInterestMutationEntity.kt @@ -16,6 +16,7 @@ package com.google.android.ground.persistence.local.room.entity import androidx.room.* +import com.google.android.ground.model.locationofinterest.LoiProperties import com.google.android.ground.persistence.local.room.fields.MutationEntitySyncStatus import com.google.android.ground.persistence.local.room.fields.MutationEntityType @@ -48,7 +49,8 @@ data class LocationOfInterestMutationEntity( @ColumnInfo(name = "client_timestamp") val clientTimestamp: Long, @ColumnInfo(name = "location_of_interest_id") val locationOfInterestId: String, @ColumnInfo(name = "job_id") val jobId: String, - @ColumnInfo(name = "caption") val caption: String?, /** Non-null if the LOI's geometry was updated, null if unchanged. */ val newGeometry: GeometryWrapper?, + val newProperties: LoiProperties, + val newCustomId: String ) diff --git a/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiConverter.kt b/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiConverter.kt index 1d4a6fbbc2..d632fb5b49 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiConverter.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiConverter.kt @@ -64,14 +64,14 @@ object LoiConverter { return LocationOfInterest( id = loiId, surveyId = survey.id, - customId = loiDoc.customId, - caption = loiDoc.caption, + customId = loiDoc.customId ?: "", job = job, created = AuditInfoConverter.toAuditInfo(created), lastModified = AuditInfoConverter.toAuditInfo(lastModified), // TODO(#929): Set geometry once LOI has been updated to use our own model. geometry = geometry, - submissionCount = submissionCount + submissionCount = submissionCount, + properties = loiDoc.properties ?: mapOf() ) } } diff --git a/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiDocument.kt b/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiDocument.kt index 0ca2757ee9..2ce6fc0b0a 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiDocument.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/remote/firebase/schema/LoiDocument.kt @@ -16,6 +16,7 @@ package com.google.android.ground.persistence.remote.firebase.schema +import com.google.android.ground.model.locationofinterest.LoiProperties import com.google.firebase.firestore.GeoPoint import com.google.firebase.firestore.IgnoreExtraProperties @@ -24,11 +25,11 @@ import com.google.firebase.firestore.IgnoreExtraProperties data class LoiDocument( val jobId: String? = null, val customId: String? = null, - val caption: String? = null, val location: GeoPoint? = null, val geoJson: String? = null, val geometry: Map? = null, val created: AuditInfoNestedObject? = null, val lastModified: AuditInfoNestedObject? = null, - val submissionCount: Int? = null + val submissionCount: Int? = null, + val properties: LoiProperties? = null, ) diff --git a/ground/src/main/java/com/google/android/ground/ui/common/LocationOfInterestHelper.kt b/ground/src/main/java/com/google/android/ground/ui/common/LocationOfInterestHelper.kt index 43960fd589..ee5a9ec4d6 100644 --- a/ground/src/main/java/com/google/android/ground/ui/common/LocationOfInterestHelper.kt +++ b/ground/src/main/java/com/google/android/ground/ui/common/LocationOfInterestHelper.kt @@ -34,7 +34,8 @@ class LocationOfInterestHelper @Inject internal constructor(private val resource locationOfInterest.map(::getLabel).orElse("") fun getLabel(loi: LocationOfInterest): String { - val caption = loi.caption?.trim { it <= ' ' } ?: "" + // TODO(#2046): Reuse logic from card util to display LOI label + val caption = loi.customId?.trim { it <= ' ' } ?: "" return caption.ifEmpty { getLocationOfInterestType(loi) } } diff --git a/ground/src/main/java/com/google/android/ground/ui/home/mapcontainer/cards/LoiCardUtil.kt b/ground/src/main/java/com/google/android/ground/ui/home/mapcontainer/cards/LoiCardUtil.kt index 20184da5d1..1122c65bdd 100644 --- a/ground/src/main/java/com/google/android/ground/ui/home/mapcontainer/cards/LoiCardUtil.kt +++ b/ground/src/main/java/com/google/android/ground/ui/home/mapcontainer/cards/LoiCardUtil.kt @@ -28,15 +28,16 @@ import com.google.android.ground.util.isNotNullOrEmpty object LoiCardUtil { fun getDisplayLoiName(context: Context, loi: LocationOfInterest): String { - val caption = loi.caption - val customId = loi.customId + val loiId = + if (loi.customId.isNotNullOrEmpty()) loi.customId else loi.properties?.get("id")?.toString() val geometry = loi.geometry - return if (caption.isNotNullOrEmpty() && customId.isNotNullOrEmpty()) { - "$caption ($customId)" - } else if (caption.isNotNullOrEmpty()) { - "$caption" - } else if (customId.isNotNullOrEmpty()) { - "${geometry.toType(context)} ($customId)" + val name: String? = loi.properties?.get("name")?.toString() + return if (name.isNotNullOrEmpty() && loiId.isNotNullOrEmpty()) { + "$name ($loiId)" + } else if (name.isNotNullOrEmpty()) { + "$name" + } else if (loiId.isNotNullOrEmpty()) { + "${geometry.toType(context)} ($loiId)" } else { geometry.toDefaultName(context) } diff --git a/ground/src/test/java/com/google/android/ground/persistence/remote/firebase/schema/LoiLocalDataStoreConverterTest.kt b/ground/src/test/java/com/google/android/ground/persistence/remote/firebase/schema/LoiLocalDataStoreConverterTest.kt index 17aa07ac45..a01ee7b684 100644 --- a/ground/src/test/java/com/google/android/ground/persistence/remote/firebase/schema/LoiLocalDataStoreConverterTest.kt +++ b/ground/src/test/java/com/google/android/ground/persistence/remote/firebase/schema/LoiLocalDataStoreConverterTest.kt @@ -58,15 +58,13 @@ class LoiLocalDataStoreConverterTest { mockLoiDocumentSnapshot( "loi001", LoiDocument( - /* jobId */ - "job001", /* customId */ - null, /* caption */ - null, /* location */ - null, /* geoJson */ - null, /* geometry */ - null, /* created */ - AUDIT_INFO_1_NESTED_OBJECT, /* lastModified */ - AUDIT_INFO_2_NESTED_OBJECT + /* jobId */ "job001", + /* customId */ null, + /* location */ null, + /* geoJson */ null, + /* geometry */ null, + /* created */ AUDIT_INFO_1_NESTED_OBJECT, + /* lastModified */ AUDIT_INFO_2_NESTED_OBJECT ) ) assertThat(toLocationOfInterest().isFailure).isTrue() @@ -93,7 +91,6 @@ class LoiLocalDataStoreConverterTest { null, null, null, - null, noVerticesGeometry, AUDIT_INFO_1_NESTED_OBJECT, AUDIT_INFO_2_NESTED_OBJECT diff --git a/ground/src/test/java/com/google/android/ground/repository/LocationOfInterestRepositoryTest.kt b/ground/src/test/java/com/google/android/ground/repository/LocationOfInterestRepositoryTest.kt index 06b3080b8c..52b05c664d 100644 --- a/ground/src/test/java/com/google/android/ground/repository/LocationOfInterestRepositoryTest.kt +++ b/ground/src/test/java/com/google/android/ground/repository/LocationOfInterestRepositoryTest.kt @@ -80,8 +80,7 @@ class LocationOfInterestRepositoryTest : BaseHiltTest() { // TODO(#1559): Remove once customId and caption are handled consistently. val loi = LOCATION_OF_INTEREST.copy( - customId = null, - caption = null, + customId = "", // TODO(#1562): Remove once creation time is preserved in local db. lastModified = LOCATION_OF_INTEREST.created ) @@ -201,8 +200,7 @@ class LocationOfInterestRepositoryTest : BaseHiltTest() { id = id, geometry = Point(coordinate), surveyId = TEST_SURVEY.id, - caption = null, - customId = null + customId = "" ) private fun createPolygon(id: String, coordinates: List) = @@ -210,8 +208,7 @@ class LocationOfInterestRepositoryTest : BaseHiltTest() { id = id, geometry = Polygon(LinearRing(coordinates)), surveyId = TEST_SURVEY.id, - caption = null, - customId = null + customId = "" ) } } diff --git a/ground/src/test/java/com/google/android/ground/ui/common/LocationOfInterestHelperTest.kt b/ground/src/test/java/com/google/android/ground/ui/common/LocationOfInterestHelperTest.kt index b7efc16fa1..4907dc9ac4 100644 --- a/ground/src/test/java/com/google/android/ground/ui/common/LocationOfInterestHelperTest.kt +++ b/ground/src/test/java/com/google/android/ground/ui/common/LocationOfInterestHelperTest.kt @@ -52,28 +52,15 @@ class LocationOfInterestHelperTest : BaseHiltTest() { @Test fun testGetLabel_whenCaptionIsEmptyAndLoiIsPoint() { - val loi = FakeData.LOCATION_OF_INTEREST.copy(caption = "") + val loi = FakeData.LOCATION_OF_INTEREST.copy("") assertLabel(loi, "Point") } @Test fun testGetLabel_whenCaptionIsEmptyAndLoiIsPolygon() { - val loi = FakeData.AREA_OF_INTEREST.copy(caption = "") + val loi = FakeData.AREA_OF_INTEREST.copy("") assertLabel(loi, "Polygon") } - - @Test - fun testGetLabel_whenCaptionIsPresentAndLoiIsPoint() { - val loi = FakeData.LOCATION_OF_INTEREST.copy(caption = TEST_CAPTION) - assertLabel(loi, TEST_CAPTION) - } - - @Test - fun testGetLabel_whenCaptionIsPresentAndLoiIsPolygon() { - val loi = FakeData.AREA_OF_INTEREST.copy(caption = TEST_CAPTION) - assertLabel(loi, TEST_CAPTION) - } - @Test fun testGetSubtitle() { val loi = FakeData.LOCATION_OF_INTEREST.copy(job = FakeData.JOB.copy(name = TEST_JOB_NAME)) @@ -99,7 +86,6 @@ class LocationOfInterestHelperTest : BaseHiltTest() { companion object { private const val TEST_USER_NAME = "some user name" - private const val TEST_CAPTION = "some caption text" private const val TEST_JOB_NAME = "some job name" } } diff --git a/ground/src/test/java/com/google/android/ground/ui/datacollection/DataCollectionFragmentTest.kt b/ground/src/test/java/com/google/android/ground/ui/datacollection/DataCollectionFragmentTest.kt index c536430879..b91767d1ba 100644 --- a/ground/src/test/java/com/google/android/ground/ui/datacollection/DataCollectionFragmentTest.kt +++ b/ground/src/test/java/com/google/android/ground/ui/datacollection/DataCollectionFragmentTest.kt @@ -69,7 +69,8 @@ class DataCollectionFragmentTest : BaseHiltTest() { setupSubmission() setupFragment() - onView(withText(LOCATION_OF_INTEREST.caption)).check(matches(isDisplayed())) + // TODO(#2046): Update this test to match new LOI label format + onView(withText("Point")).check(matches(isDisplayed())) onView(withText(JOB.name)).check(matches(isDisplayed())) } diff --git a/ground/src/test/java/com/google/android/ground/ui/home/mapcontainer/LoiCardUtilTest.kt b/ground/src/test/java/com/google/android/ground/ui/home/mapcontainer/LoiCardUtilTest.kt index 1c12eee7a0..ecccb9a8a2 100644 --- a/ground/src/test/java/com/google/android/ground/ui/home/mapcontainer/LoiCardUtilTest.kt +++ b/ground/src/test/java/com/google/android/ground/ui/home/mapcontainer/LoiCardUtilTest.kt @@ -32,19 +32,68 @@ class LoiCardUtilTest { private val context: Context = ApplicationProvider.getApplicationContext() @Test - fun testLoiNameWithPoint_whenCaptionIsNull() { - assertThat(getDisplayLoiName(context, TEST_LOI.copy(caption = null))).isEqualTo("Unnamed point") + fun testLoiNameWithPoint_whenCustomIdAndPropertiesAreNull() { + assertThat(getDisplayLoiName(context, TEST_LOI.copy(customId = "", properties = mapOf()))) + .isEqualTo("Unnamed point") } @Test - fun testLoiNameWithPolygon_whenCaptionIsNull() { - assertThat(getDisplayLoiName(context, TEST_AREA.copy(caption = null))).isEqualTo("Unnamed area") + fun testLoiNameWithPolygon_whenCustomIdAndPropertiesAreNull() { + assertThat(getDisplayLoiName(context, TEST_AREA.copy(customId = "", properties = mapOf()))) + .isEqualTo("Unnamed area") } @Test - fun testLoiName_whenCaptionIsAvailable() { - assertThat(getDisplayLoiName(context, TEST_LOI.copy(caption = "some value"))) - .isEqualTo("some value") + fun testLoiName_whenCustomIdIsAvailable() { + assertThat(getDisplayLoiName(context, TEST_LOI.copy(customId = "some value"))) + .isEqualTo("Point (some value)") + } + + @Test + fun testArea_whenCustomIdIsAvailable() { + assertThat(getDisplayLoiName(context, TEST_AREA.copy(customId = "some value"))) + .isEqualTo("Area (some value)") + } + + @Test + fun testArea_whenCustomIdIsNotAvailable_usesPropertiesId() { + assertThat( + getDisplayLoiName( + context, + TEST_AREA.copy(customId = "", properties = mapOf("id" to "property id")) + ) + ) + .isEqualTo("Area (property id)") + } + + @Test + fun testLoiName_whenPropertiesNameIsAvailable() { + assertThat( + getDisplayLoiName(context, TEST_LOI.copy(properties = mapOf("name" to "custom name"))) + ) + .isEqualTo("custom name") + } + + @Test + fun testLoiName_whenCustomIdAndPropertiesNameIsAvailable() { + assertThat( + getDisplayLoiName( + context, + TEST_LOI.copy(customId = "some value", properties = mapOf("name" to "custom name")) + ) + ) + .isEqualTo("custom name (some value)") + } + + @Test + fun testLoiName_whenPropertiesDoesNotContainName() { + assertThat( + getDisplayLoiName( + context, + TEST_LOI.copy(customId = "", properties = mapOf("not" to "a name field")) + ) + ) + .isEqualTo("Unnamed point") } @Test @@ -75,7 +124,7 @@ class LoiCardUtilTest { } companion object { - private val TEST_LOI = FakeData.LOCATION_OF_INTEREST.copy(caption = null) - private val TEST_AREA = FakeData.AREA_OF_INTEREST.copy(caption = null) + private val TEST_LOI = FakeData.LOCATION_OF_INTEREST.copy() + private val TEST_AREA = FakeData.AREA_OF_INTEREST.copy() } } diff --git a/sharedTest/src/main/kotlin/com/sharedtest/FakeData.kt b/sharedTest/src/main/kotlin/com/sharedtest/FakeData.kt index f97b251369..11a3ebff45 100644 --- a/sharedTest/src/main/kotlin/com/sharedtest/FakeData.kt +++ b/sharedTest/src/main/kotlin/com/sharedtest/FakeData.kt @@ -53,18 +53,15 @@ object FakeData { mapOf(USER.email to "data-collector") ) - private const val LOI_NAME = "loi name" - val LOCATION_OF_INTEREST = LocationOfInterest( "loi id", SURVEY.id, JOB, - null, - LOI_NAME, - AuditInfo(USER), - AuditInfo(USER), - Point(Coordinates(0.0, 0.0)) + customId = "", + created = AuditInfo(USER), + lastModified = AuditInfo(USER), + geometry = Point(Coordinates(0.0, 0.0)), ) val LOCATION_OF_INTEREST_FEATURE = @@ -94,7 +91,6 @@ object FakeData { SURVEY.id, JOB, "", - "", AUDIT_INFO, AUDIT_INFO, Polygon(LinearRing(VERTICES.map { it.coordinates })),