Skip to content

Commit

Permalink
fix: filter null values in identify intercept (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
qingzhuozhen authored Apr 6, 2023
1 parent a7b387f commit 3689fc1
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,29 @@ class IdentifyInterceptorTest {
assertEquals("identify_user_id", events[1].userId)
}

@Test
fun `test null user properties filtered out`() {
server.enqueue(MockResponse().setBody("{\"code\": \"success\"}"))
amplitude.identify(Identify().set("key1", "key1-value1").set("key2", "key2-value1"))
amplitude.identify(Identify().set("key3", "key3-value1").set("key1", "key1-value2"))
amplitude.identify(Identify().set("key4", "key4-value1").set("key2", "key2-value2"))
amplitude.identify(Identify().set("key3", "key3-value2").set("key4", "key4-value2"))
val testEvent = BaseEvent()
testEvent.eventType = "test_event"
testEvent.userProperties = mutableMapOf("key1" to null, "key2" to null)
amplitude.flush()
val request: RecordedRequest? = runRequest()
assertNotNull(request)
val events = getEventsFromRequest(request!!)
assertEquals(1, events.size)
val expectedUserProperties = mapOf("key1" to "key1-value2", "key2" to "key2-value2", "key3" to "key3-value2", "key4" to "key4-value2")
assertEquals(Constants.IDENTIFY_EVENT, events[0].eventType)
assertEquals(
expectedUserProperties,
events[0].userProperties?.get(IdentifyOperation.SET.operationType)
)
}

private fun getEventsFromRequest(request: RecordedRequest): List<BaseEvent> {
val body = request.body.readUtf8()
return JSONObject(body).getJSONArray("events").toEvents()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.amplitude.common.Logger
import com.amplitude.core.Amplitude
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.events.IdentifyOperation
import com.amplitude.core.platform.intercept.IdentifyInterceptorUtil.filterNonNullValues
import com.amplitude.core.utilities.EventsFileStorage
import com.amplitude.core.utilities.toEvents
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -45,7 +46,7 @@ class IdentifyInterceptFileStorageHandler(
var events = eventsList
if (event == null) {
event = eventsList[0]
identifyEventUserProperties = event?.userProperties?.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>
identifyEventUserProperties = filterNonNullValues(event?.userProperties?.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>)
events = eventsList.subList(1, eventsList.size)
}
val userProperties = IdentifyInterceptorUtil.mergeIdentifyList(events)
Expand Down Expand Up @@ -75,7 +76,7 @@ class IdentifyInterceptFileStorageHandler(
override suspend fun fetchAndMergeToIdentifyEvent(event: BaseEvent): BaseEvent {
val userProperties = fetchAndMergeToUserProperties()
if (event.userProperties?.contains(IdentifyOperation.SET.operationType) == true) {
userProperties.putAll(event.userProperties!![IdentifyOperation.SET.operationType] as MutableMap<String, Any?>)
userProperties.putAll(filterNonNullValues(event.userProperties!![IdentifyOperation.SET.operationType] as MutableMap<String, Any?>))
}
event.userProperties?.put(IdentifyOperation.SET.operationType, userProperties)
return event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.amplitude.core.platform.intercept

import com.amplitude.core.events.BaseEvent
import com.amplitude.core.events.IdentifyOperation
import com.amplitude.core.platform.intercept.IdentifyInterceptorUtil.filterNonNullValues
import com.amplitude.core.utilities.InMemoryStorage

class IdentifyInterceptInMemoryStorageHandler(
Expand All @@ -14,7 +15,7 @@ class IdentifyInterceptInMemoryStorageHandler(
}
val events = eventsData[0]
val identifyEvent = events[0]
val identifyEventUserProperties = identifyEvent.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>
val identifyEventUserProperties = filterNonNullValues(identifyEvent.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>)
val userProperties = IdentifyInterceptorUtil.mergeIdentifyList(events.subList(1, events.size))
identifyEventUserProperties.putAll(userProperties)
identifyEvent.userProperties!!.put(IdentifyOperation.SET.operationType, identifyEventUserProperties)
Expand Down Expand Up @@ -43,7 +44,7 @@ class IdentifyInterceptInMemoryStorageHandler(
val events = eventsData[0]
val userProperties = IdentifyInterceptorUtil.mergeIdentifyList(events)
if (event.userProperties?.contains(IdentifyOperation.SET.operationType) == true) {
userProperties.putAll(event.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>)
userProperties.putAll(filterNonNullValues(event.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>))
}
event.userProperties?.put(IdentifyOperation.SET.operationType, userProperties)
return event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ object IdentifyInterceptorUtil {
fun mergeIdentifyList(events: List<BaseEvent>): MutableMap<String, Any?> {
val userProperties = mutableMapOf<String, Any?>()
events.forEach {
userProperties.putAll(it.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>)
userProperties.putAll(filterNonNullValues(it.userProperties!!.get(IdentifyOperation.SET.operationType) as MutableMap<String, Any?>))
}
return userProperties
}

fun filterNonNullValues(map: MutableMap<String, Any?>): MutableMap<String, Any?> {
return map.filterValues { it != null }.toMutableMap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import java.util.concurrent.TimeUnit

@Disabled
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class IdentifyInterceptTest {
private lateinit var server: MockWebServer
Expand Down

0 comments on commit 3689fc1

Please sign in to comment.