diff --git a/sdk/ktlint-baseline.xml b/sdk/ktlint-baseline.xml index 1a77b5c2..837a7b82 100644 --- a/sdk/ktlint-baseline.xml +++ b/sdk/ktlint-baseline.xml @@ -616,46 +616,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sdk/src/main/java/io/radar/sdk/model/RadarEvent.kt b/sdk/src/main/java/io/radar/sdk/model/RadarEvent.kt index 2577c98c..93cce678 100644 --- a/sdk/src/main/java/io/radar/sdk/model/RadarEvent.kt +++ b/sdk/src/main/java/io/radar/sdk/model/RadarEvent.kt @@ -9,27 +9,35 @@ import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ARRIVED_AT_WRONG_TRIP_D import io.radar.sdk.model.RadarEvent.RadarEventType.USER_DWELLED_IN_GEOFENCE import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_BEACON import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_GEOFENCE +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_HOME import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_PLACE import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_REGION_COUNTRY import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_REGION_DMA import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_REGION_POSTAL_CODE import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_REGION_STATE +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_ENTERED_WORK import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_BEACON import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_GEOFENCE +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_HOME import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_PLACE import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_REGION_COUNTRY import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_REGION_DMA import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_REGION_POSTAL_CODE import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_REGION_STATE +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_EXITED_WORK import io.radar.sdk.model.RadarEvent.RadarEventType.USER_FAILED_FRAUD import io.radar.sdk.model.RadarEvent.RadarEventType.USER_FIRED_TRIP_ORDERS import io.radar.sdk.model.RadarEvent.RadarEventType.USER_NEARBY_PLACE_CHAIN +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STARTED_COMMUTING +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STARTED_TRAVELING import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STARTED_TRIP +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STOPPED_COMMUTING +import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STOPPED_TRAVELING import io.radar.sdk.model.RadarEvent.RadarEventType.USER_STOPPED_TRIP import io.radar.sdk.model.RadarEvent.RadarEventType.USER_UPDATED_TRIP +import java.util.Date import org.json.JSONArray import org.json.JSONObject -import java.util.Date /** * Represents a change in user state. @@ -142,68 +150,120 @@ class RadarEvent( enum class RadarEventType { /** Unknown */ UNKNOWN, + /** A conversion event, logged with Radar.logConversion() */ CONVERSION, + /** `user.entered_geofence` */ USER_ENTERED_GEOFENCE, + /** `user.exited_geofence` */ USER_EXITED_GEOFENCE, + /** `user.dwelled_in_geofence` */ USER_DWELLED_IN_GEOFENCE, + /** `user.entered_place` */ USER_ENTERED_PLACE, + /** `user.exited_place` */ USER_EXITED_PLACE, + /** `user.entered_region_country` */ USER_ENTERED_REGION_COUNTRY, + /** `user.exited_region_country` */ USER_EXITED_REGION_COUNTRY, + /** `user.entered_region_dma` */ USER_ENTERED_REGION_DMA, + /** `user.exited_region_dma` */ USER_EXITED_REGION_DMA, + /** `user.entered_region_state` */ USER_ENTERED_REGION_STATE, + /** `user.exited_region_state` */ USER_EXITED_REGION_STATE, + /** `user.entered_region_postal_code` */ USER_ENTERED_REGION_POSTAL_CODE, + /** `user.exited_region_postal_code` */ USER_EXITED_REGION_POSTAL_CODE, + /** `user.nearby_place_chain` */ USER_NEARBY_PLACE_CHAIN, + /** `user.entered_beacon` */ USER_ENTERED_BEACON, + /** `user.exited_beacon` */ USER_EXITED_BEACON, + /** `user.started_trip` */ USER_STARTED_TRIP, + /** `user.updated_trip` */ USER_UPDATED_TRIP, + /** `user.stopped_trip` */ USER_STOPPED_TRIP, + /** `user.approaching_trip_destination` */ USER_APPROACHING_TRIP_DESTINATION, + /** `user.arrived_at_trip_destination` */ USER_ARRIVED_AT_TRIP_DESTINATION, + /** user.arrived_at_wrong_trip_destination */ USER_ARRIVED_AT_WRONG_TRIP_DESTINATION, + /** `user.fired_trip_orders` */ USER_FIRED_TRIP_ORDERS, + /** `user.failed_fraud` */ USER_FAILED_FRAUD, + + /** `user.entered_home` */ + USER_ENTERED_HOME, + + /** `user.exited_home` */ + USER_EXITED_HOME, + + /** `user.entered_work` */ + USER_ENTERED_WORK, + + /** `user.exited_work` */ + USER_EXITED_WORK, + + /** `user.started_traveling` */ + USER_STARTED_TRAVELING, + + /** `user.stopped_traveling` */ + USER_STOPPED_TRAVELING, + + /** `user.started_commuting` */ + USER_STARTED_COMMUTING, + + /** `user.stopped_commuting` */ + USER_STOPPED_COMMUTING } /** * The confidence levels for events. */ - enum class RadarEventConfidence(val value: Int) { + enum class RadarEventConfidence(val value: Int) { /** Unknown confidence */ NONE(0), + /** Low confidence */ LOW(1), + /** Medium confidence */ MEDIUM(2), + /** High confidence */ HIGH(3) } @@ -214,8 +274,10 @@ class RadarEvent( enum class RadarEventVerification { /** Accept event */ ACCEPT, + /** Unverify event */ UNVERIFY, + /** Reject event */ REJECT } @@ -278,6 +340,14 @@ class RadarEvent( "user.arrived_at_wrong_trip_destination" -> USER_ARRIVED_AT_WRONG_TRIP_DESTINATION "user.fired_trip_orders" -> USER_FIRED_TRIP_ORDERS "user.failed_fraud" -> USER_FAILED_FRAUD + "user.entered_home" -> USER_ENTERED_HOME + "user.exited_home" -> USER_EXITED_HOME + "user.entered_work" -> USER_ENTERED_WORK + "user.exited_work" -> USER_EXITED_WORK + "user.started_traveling" -> USER_STARTED_TRAVELING + "user.stopped_traveling" -> USER_STOPPED_TRAVELING + "user.started_commuting" -> USER_STARTED_COMMUTING + "user.stopped_commuting" -> USER_STOPPED_COMMUTING else -> CONVERSION } var conversionName: String? = null @@ -317,7 +387,7 @@ class RadarEvent( } val replayed = obj.optBoolean(FIELD_REPLAYED) - + val metadataStr = obj.optString(FIELD_METADATA) val metadataJson = if (!metadataStr.isNullOrEmpty()) { try { @@ -349,7 +419,7 @@ class RadarEvent( } @JvmStatic - fun toJson(events: Array ?): JSONArray? { + fun toJson(events: Array?): JSONArray? { if (events == null) { return null } @@ -362,34 +432,40 @@ class RadarEvent( } @JvmStatic - fun stringForType(type: RadarEventType): String? { - return when (type) { - USER_ENTERED_GEOFENCE -> "user.entered_geofence" - USER_EXITED_GEOFENCE -> "user.exited_geofence" - USER_DWELLED_IN_GEOFENCE -> "user.dwelled_in_geofence" - USER_ENTERED_PLACE -> "user.entered_place" - USER_EXITED_PLACE -> "user.exited_place" - USER_ENTERED_REGION_COUNTRY -> "user.entered_region_country" - USER_EXITED_REGION_COUNTRY -> "user.exited_region_country" - USER_ENTERED_REGION_DMA -> "user.entered_region_dma" - USER_EXITED_REGION_DMA -> "user.exited_region_dma" - USER_ENTERED_REGION_STATE -> "user.entered_region_state" - USER_EXITED_REGION_STATE -> "user.exited_region_state" - USER_ENTERED_REGION_POSTAL_CODE -> "user.entered_region_postal_code" - USER_EXITED_REGION_POSTAL_CODE -> "user.exited_region_postal_code" - USER_NEARBY_PLACE_CHAIN -> "user.nearby_place_chain" - USER_ENTERED_BEACON -> "user.entered_beacon" - USER_EXITED_BEACON -> "user.exited_beacon" - USER_STARTED_TRIP -> "user.started_trip" - USER_UPDATED_TRIP -> "user.updated_trip" - USER_STOPPED_TRIP -> "user.stopped_trip" - USER_APPROACHING_TRIP_DESTINATION -> "user.approaching_trip_destination" - USER_ARRIVED_AT_TRIP_DESTINATION -> "user.arrived_at_trip_destination" - USER_ARRIVED_AT_WRONG_TRIP_DESTINATION -> "user.arrived_at_wrong_trip_destination" - USER_FIRED_TRIP_ORDERS -> "user.fired_trip_orders" - USER_FAILED_FRAUD -> "user.failed_fraud" - else -> null - } + fun stringForType(type: RadarEventType): String? = when (type) { + USER_ENTERED_GEOFENCE -> "user.entered_geofence" + USER_EXITED_GEOFENCE -> "user.exited_geofence" + USER_DWELLED_IN_GEOFENCE -> "user.dwelled_in_geofence" + USER_ENTERED_PLACE -> "user.entered_place" + USER_EXITED_PLACE -> "user.exited_place" + USER_ENTERED_REGION_COUNTRY -> "user.entered_region_country" + USER_EXITED_REGION_COUNTRY -> "user.exited_region_country" + USER_ENTERED_REGION_DMA -> "user.entered_region_dma" + USER_EXITED_REGION_DMA -> "user.exited_region_dma" + USER_ENTERED_REGION_STATE -> "user.entered_region_state" + USER_EXITED_REGION_STATE -> "user.exited_region_state" + USER_ENTERED_REGION_POSTAL_CODE -> "user.entered_region_postal_code" + USER_EXITED_REGION_POSTAL_CODE -> "user.exited_region_postal_code" + USER_NEARBY_PLACE_CHAIN -> "user.nearby_place_chain" + USER_ENTERED_BEACON -> "user.entered_beacon" + USER_EXITED_BEACON -> "user.exited_beacon" + USER_STARTED_TRIP -> "user.started_trip" + USER_UPDATED_TRIP -> "user.updated_trip" + USER_STOPPED_TRIP -> "user.stopped_trip" + USER_APPROACHING_TRIP_DESTINATION -> "user.approaching_trip_destination" + USER_ARRIVED_AT_TRIP_DESTINATION -> "user.arrived_at_trip_destination" + USER_ARRIVED_AT_WRONG_TRIP_DESTINATION -> "user.arrived_at_wrong_trip_destination" + USER_FIRED_TRIP_ORDERS -> "user.fired_trip_orders" + USER_FAILED_FRAUD -> "user.failed_fraud" + USER_ENTERED_HOME -> "user.entered_home" + USER_EXITED_HOME -> "user.exited_home" + USER_ENTERED_WORK -> "user.entered_work" + USER_EXITED_WORK -> "user.exited_work" + USER_STARTED_TRAVELING -> "user.started_traveling" + USER_STOPPED_TRAVELING -> "user.stopped_traveling" + USER_STARTED_COMMUTING -> "user.started_commuting" + USER_STOPPED_COMMUTING -> "user.stopped_commuting" + else -> null } } @@ -421,5 +497,4 @@ class RadarEvent( return obj } - } diff --git a/sdk/src/test/java/io/radar/sdk/model/RadarUserInsightsEventTest.kt b/sdk/src/test/java/io/radar/sdk/model/RadarUserInsightsEventTest.kt new file mode 100644 index 00000000..8ac0526b --- /dev/null +++ b/sdk/src/test/java/io/radar/sdk/model/RadarUserInsightsEventTest.kt @@ -0,0 +1,52 @@ +package io.radar.sdk.model + +import android.os.Build +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.json.JSONArray +import org.json.JSONObject +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(sdk = [Build.VERSION_CODES.P]) +class RadarUserInsightsEventTest { + + @Test + fun testUserInsightsEventTypesRoundTrip() { + val cases = mapOf( + "user.entered_home" to RadarEvent.RadarEventType.USER_ENTERED_HOME, + "user.exited_home" to RadarEvent.RadarEventType.USER_EXITED_HOME, + "user.entered_work" to RadarEvent.RadarEventType.USER_ENTERED_WORK, + "user.exited_work" to RadarEvent.RadarEventType.USER_EXITED_WORK, + "user.started_traveling" to RadarEvent.RadarEventType.USER_STARTED_TRAVELING, + "user.stopped_traveling" to RadarEvent.RadarEventType.USER_STOPPED_TRAVELING, + "user.started_commuting" to RadarEvent.RadarEventType.USER_STARTED_COMMUTING, + "user.stopped_commuting" to RadarEvent.RadarEventType.USER_STOPPED_COMMUTING + ) + + cases.forEach { (typeString, eventType) -> + val event = RadarEvent.fromJson(eventJson(typeString)) + + assertNotNull(event) + assertEquals(eventType, event?.type) + assertEquals(typeString, event?.toJson()?.getString("type")) + } + } + + private fun eventJson(type: String): JSONObject = JSONObject() + .put("_id", "evt_test") + .put("createdAt", "2026-06-26T12:00:00.000Z") + .put("actualCreatedAt", "2026-06-26T12:00:00.000Z") + .put("live", false) + .put("type", type) + .put("confidence", 3) + .put( + "location", + JSONObject() + .put("type", "Point") + .put("coordinates", JSONArray().put(-73.975365).put(40.783825)) + ) +}