Skip to content

Commit

Permalink
Update the logic based on feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Mansi-mParticle committed Jul 18, 2024
1 parent 44965b6 commit edf1408
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 31 deletions.
82 changes: 53 additions & 29 deletions src/main/kotlin/com/mparticle/kits/AppboyKit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener,
): List<ReportingMessage> = emptyList()

override fun logEvent(event: MPEvent): List<ReportingMessage> {
if (event.customAttributes != null) {
event.customAttributeStrings?.let {
changeUserArray(
it,
event.eventType.value,
event.eventName, false
)
}
}
return logBrazeEvent(event)
}

private fun logBrazeEvent(event: MPEvent): List<ReportingMessage> {
val newAttributes: MutableMap<String, Any?> = HashMap()
if (event.customAttributes == null) {
Braze.getInstance(context).logCustomEvent(event.eventName)
Expand All @@ -150,40 +163,47 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener,
}
}
Braze.getInstance(context).logCustomEvent(event.eventName, properties)
Braze.getInstance(context).getCurrentUser(object : IValueCallback<BrazeUser> {
override fun onSuccess(value: BrazeUser) {
val userAttributeSetter = UserAttributeSetter(value, enableTypeDetection)
event.customAttributeStrings?.let { it ->
for ((key, attributeValue) in it) {
val hashedKey =
if (event.eventName.contains("eCommerce")) {
KitUtils.hashForFiltering(event.eventType.value.toString() + key.trim())
} else {
KitUtils.hashForFiltering(event.eventType.value.toString() + event.eventName.trim() + key.trim())
}

configuration.eventAttributesAddToUser?.get(hashedKey)?.let {
value.addToCustomAttributeArray(it, attributeValue)
}
configuration.eventAttributesRemoveFromUser?.get(hashedKey)?.let {
value.removeFromCustomAttributeArray(it, attributeValue)
}
configuration.eventAttributesSingleItemUser?.get(hashedKey)?.let {
userAttributeSetter.parseValue(it, attributeValue)
}
queueDataFlush()
return listOf(ReportingMessage.fromEvent(this, event).setAttributes(newAttributes))
}

private fun changeUserArray(
customAttributes: Map<String, String>,
eventType: Int,
eventName: String?,
isCommerceEvent: Boolean
) {
Braze.getInstance(context).getCurrentUser(object : IValueCallback<BrazeUser> {
override fun onSuccess(value: BrazeUser) {
val userAttributeSetter = UserAttributeSetter(value, enableTypeDetection)
customAttributes?.let { it ->
for ((key, attributeValue) in it) {
//for commerce event, event name is not required for generate hash
val hashedKey =
if (isCommerceEvent) {
KitUtils.hashForFiltering(eventType.toString() + key)
} else {
KitUtils.hashForFiltering(eventType.toString() + eventName + key)
}
configuration.eventAttributesAddToUser?.get(hashedKey)?.let {
value.addToCustomAttributeArray(it, attributeValue)
}
configuration.eventAttributesRemoveFromUser?.get(hashedKey)?.let {
value.removeFromCustomAttributeArray(it, attributeValue)
}
configuration.eventAttributesSingleItemUser?.get(hashedKey)?.let {
userAttributeSetter.parseValue(it, attributeValue)
}
}
}
}

override fun onError() {
Logger.warning("unable to acquire user to add or remove custom user attributes from events")
}
})
}
queueDataFlush()
return listOf(ReportingMessage.fromEvent(this, event).setAttributes(newAttributes))
override fun onError() {
Logger.warning("unable to acquire user to add or remove custom user attributes from events")
}
})
}

override fun logScreen(
screenName: String,
screenAttributes: Map<String, String>?
Expand Down Expand Up @@ -224,6 +244,10 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener,

override fun logEvent(event: CommerceEvent): List<ReportingMessage> {
val messages: MutableList<ReportingMessage> = LinkedList()
//For CommerceEvent, Event Name is not required to generate hash. So, it will be always null.
event.products?.get(0)?.customAttributes?.let {
changeUserArray(it, CommerceEventUtils.getEventType(event), null, true)
}
if (!KitUtils.isEmpty(event.productAction) &&
event.productAction.equals(
Product.PURCHASE,
Expand Down Expand Up @@ -257,7 +281,7 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener,
for (pair in map) {
e.customAttributes?.put(pair.key, pair.value)
}
logEvent(e)
logBrazeEvent(e)
messages.add(ReportingMessage.fromEvent(this, event))
} catch (e: Exception) {
Logger.warning("Failed to call logCustomEvent to Appboy kit: $e")
Expand Down
187 changes: 185 additions & 2 deletions src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import java.lang.reflect.Method
import java.math.BigDecimal
import java.util.Calendar
import java.util.Locale
Expand Down Expand Up @@ -577,6 +578,13 @@ class AppboyKitTests {

val product: Product = Product.Builder("La Enchilada", "13061043670", 12.5)
.quantity(1.0)
.customAttributes(
mapOf(
"size" to "5",
"color" to "Black",
"Total Amount" to "120.22"
)
)
.build()

val txAttributes = TransactionAttributes()
Expand All @@ -600,7 +608,7 @@ class AppboyKitTests {

val jsonObject = JSONObject()
val mapValue = JSONObject()
mapValue.put("-844012960", "test")
mapValue.put("-94160813", "test")
val eassObject = JSONObject()
eassObject.put("eaa", mapValue)

Expand Down Expand Up @@ -726,6 +734,13 @@ class AppboyKitTests {
kit.configuration = MockKitConfiguration()
val product: Product = Product.Builder("La Enchilada", "13061043670", 12.5)
.quantity(1.0)
.customAttributes(
mapOf(
"size" to "5",
"color" to "Black",
"Total Amount" to "120.22"
)
)
.build()

val txAttributes = TransactionAttributes()
Expand All @@ -741,6 +756,9 @@ class AppboyKitTests {
customAttributes["deviceId"] = "1104442582"
customAttributes["platform"] = "android"
customAttributes["isAuthorized"] = "true"



val commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product)
.currency("EUR")
.customAttributes(customAttributes)
Expand All @@ -751,7 +769,7 @@ class AppboyKitTests {
val jsonObject = JSONObject()
val mapValue = JSONObject()
//this is hash for event attribute i.e combination of eventType + eventName + attribute key
mapValue.put("-844012960", "test")
mapValue.put("-94160813", "test")
val eassObject = JSONObject()
eassObject.put("eaa", mapValue)
eassObject.put("eas", mapValue)
Expand Down Expand Up @@ -1247,4 +1265,169 @@ class AppboyKitTests {
}
Assert.assertEquals("testEvent", outputKey)
}

@Test
fun testChangeUserArray() {
val kit = MockAppboyKit()
val currentUser = braze.currentUser

kit.configuration = MockKitConfiguration()

val jsonObject = JSONObject()
val mapValue = JSONObject()
//this is hash for event attribute i.e combination of eventType + eventName + attribute key
mapValue.put("888169310", "testEvent")
val eaaObject = JSONObject()
eaaObject.put("eaa", mapValue)
jsonObject.put("hs", eaaObject)

Mockito.`when`(mTypeFilters!!.size()).thenReturn(0)

var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject)
kit.configuration = kitConfiguration
val customAttributes: MutableMap<String, String> = HashMap()
customAttributes["destination"] = "Shop"

val method: Method = AppboyKit::class.java.getDeclaredMethod(
"changeUserArray",
Map::class.java,
Int::class.java,
String::class.java,
Boolean::class.java
)
method.isAccessible = true
method.invoke(kit, customAttributes, 1, "AndroidTEST", false)
Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong())
var outputKey = ""
for (keys in currentUser.getCustomAttribute().keys) {
outputKey = keys
break
}
Assert.assertEquals("testEvent", outputKey)
}

@Test
fun testChangeUserArray_for_commerceEvent() {
val kit = MockAppboyKit()
val currentUser = braze.currentUser

val product: Product = Product.Builder("La Enchilada", "13061043670", 12.5)
.quantity(1.0)
.build()

val txAttributes = TransactionAttributes()
.setRevenue(product.totalAmount)

kit.configuration = MockKitConfiguration()
val customAttributes: MutableMap<String, String> = HashMap()
customAttributes["currentLocationLongitude"] = "2.1811267"
customAttributes["country"] = "ES"
customAttributes["deliveryLocationLatitude"] = "41.4035798"
customAttributes["appVersion"] = "5.201.0"
customAttributes["city"] = "BCN"
customAttributes["deviceId"] = "1104442582"
customAttributes["platform"] = "android"
customAttributes["isAuthorized"] = "true"


val jsonObject = JSONObject()
val mapValue = JSONObject()
mapValue.put("-844012960", "test")
val eassObject = JSONObject()
eassObject.put("eaa", mapValue)

jsonObject.put("hs", eassObject)
val mockSparseBooleanArray = Mockito.mock(SparseBooleanArray::class.java)

Mockito.`when`(mockSparseBooleanArray.size()).thenReturn(0)
Mockito.`when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior

var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject)
kit.configuration = kitConfiguration

val method: Method = AppboyKit::class.java.getDeclaredMethod(
"changeUserArray",
Map::class.java,
Int::class.java,
String::class.java,
Boolean::class.java
)
method.isAccessible = true
method.invoke(kit, customAttributes, 10, null, true)
Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong())
var outputKey = ""
for (keys in currentUser.getCustomAttribute().keys) {
outputKey = keys
break
}
Assert.assertEquals("test", outputKey)
}

@Test
fun testChangeUserArray_When_customAttribute_null() {
val kit = MockAppboyKit()
val currentUser = braze.currentUser

kit.configuration = MockKitConfiguration()

val jsonObject = JSONObject()
val mapValue = JSONObject()
//this is hash for event attribute i.e combination of eventType + eventName + attribute key
mapValue.put("888169310", "testEvent")
val eaaObject = JSONObject()
eaaObject.put("eaa", mapValue)
jsonObject.put("hs", eaaObject)

Mockito.`when`(mTypeFilters!!.size()).thenReturn(0)

var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject)
kit.configuration = kitConfiguration
val customAttributes: MutableMap<String, String> = HashMap()
customAttributes["destination"] = "Shop"

val method: Method = AppboyKit::class.java.getDeclaredMethod(
"changeUserArray",
Map::class.java,
Int::class.java,
String::class.java,
Boolean::class.java
)
method.isAccessible = true
method.invoke(kit, null, 1, "AndroidTEST", false)
Assert.assertEquals(0, currentUser.getCustomAttribute().size.toLong())
}

@Test
fun testChangeUserArray_When_EventType_Wrong() {
val kit = MockAppboyKit()
val currentUser = braze.currentUser

kit.configuration = MockKitConfiguration()

val jsonObject = JSONObject()
val mapValue = JSONObject()
//this is hash for event attribute i.e combination of eventType + eventName + attribute key
mapValue.put("888169310", "testEvent")
val eaaObject = JSONObject()
eaaObject.put("eaa", mapValue)
jsonObject.put("hs", eaaObject)

Mockito.`when`(mTypeFilters!!.size()).thenReturn(0)

var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject)
kit.configuration = kitConfiguration
val customAttributes: MutableMap<String, String> = HashMap()
customAttributes["destination"] = "Shop"

val method: Method = AppboyKit::class.java.getDeclaredMethod(
"changeUserArray",
Map::class.java,
Int::class.java,
String::class.java,
Boolean::class.java
)
method.isAccessible = true
method.invoke(kit, customAttributes, 5, "AndroidTEST", false)
Assert.assertEquals(0, currentUser.getCustomAttribute().size.toLong())
}
}

0 comments on commit edf1408

Please sign in to comment.