diff --git a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt index 4616e27..b307d9d 100644 --- a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt +++ b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt @@ -9,7 +9,11 @@ import com.braze.Braze import com.braze.BrazeActivityLifecycleCallbackListener import com.braze.BrazeUser import com.braze.configuration.BrazeConfig -import com.braze.enums.* +import com.braze.enums.BrazeSdkMetadata +import com.braze.enums.Gender +import com.braze.enums.Month +import com.braze.enums.NotificationSubscriptionType +import com.braze.enums.SdkFlavor import com.braze.events.IValueCallback import com.braze.models.outgoing.BrazeProperties import com.braze.push.BrazeFirebaseMessagingService @@ -26,10 +30,16 @@ import com.mparticle.commerce.Promotion import com.mparticle.identity.MParticleUser import com.mparticle.internal.Logger import com.mparticle.kits.CommerceEventUtils.OnAttributeExtracted -import com.mparticle.kits.KitIntegration.* +import com.mparticle.kits.KitIntegration.AttributeListener +import com.mparticle.kits.KitIntegration.CommerceListener +import com.mparticle.kits.KitIntegration.IdentityListener +import com.mparticle.kits.KitIntegration.PushListener import java.math.BigDecimal import java.text.SimpleDateFormat -import java.util.* +import java.util.Calendar +import java.util.Date +import java.util.EnumSet +import java.util.LinkedList /** * mParticle client-side Appboy integration @@ -134,6 +144,19 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, ): List = emptyList() override fun logEvent(event: MPEvent): List { + if (event.customAttributes != null) { + event.customAttributeStrings?.let { + changeUserArray( + it, + event.eventType.value, + event.eventName, false + ) + } + } + return logBrazeEvent(event) + } + + private fun logBrazeEvent(event: MPEvent): List { val newAttributes: MutableMap = HashMap() if (event.customAttributes == null) { Braze.getInstance(context).logCustomEvent(event.eventName) @@ -142,40 +165,55 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, val brazePropertiesSetter = BrazePropertiesSetter(properties, enableTypeDetection) event.customAttributeStrings?.let { it -> for ((key, value) in it) { - newAttributes[key] = brazePropertiesSetter.parseValue(key, value) + try { + newAttributes[key] = brazePropertiesSetter.parseValue(key, value) + } catch (e: Exception) { + Logger.warning("Exception while parsing custom attributes $e") + } } } Braze.getInstance(context).logCustomEvent(event.eventName, properties) - Braze.getInstance(context).getCurrentUser(object : IValueCallback { - override fun onSuccess(value: BrazeUser) { - val userAttributeSetter = UserAttributeSetter(value, enableTypeDetection) - event.customAttributeStrings?.let { it -> - for ((key, attributeValue) in it) { - val hashedKey = - KitUtils.hashForFiltering(event.eventType.value.toString() + event.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) + } + queueDataFlush() + return listOf(ReportingMessage.fromEvent(this, event).setAttributes(newAttributes)) + } + + private fun changeUserArray( + customAttributes: Map, + eventType: Int, + eventName: String?, + isCommerceEvent: Boolean + ) { + Braze.getInstance(context).getCurrentUser(object : IValueCallback { + override fun onSuccess(brazeUser: BrazeUser) { + val userAttributeSetter = UserAttributeSetter(brazeUser, 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 { + brazeUser.addToCustomAttributeArray(it, attributeValue) + } + configuration.eventAttributesRemoveFromUser?.get(hashedKey)?.let { + brazeUser.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? @@ -216,6 +254,15 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, override fun logEvent(event: CommerceEvent): List { val messages: MutableList = LinkedList() + + //For CommerceEvent, Event Name is not required to generate hash. So, it will be always null. + val eventAllAttributes=CommerceEventUtils.convertCommerceEventToMap(event) + eventAllAttributes?.let { + changeUserArray(it, CommerceEventUtils.getEventType(event), null, true) + } + event.customAttributeStrings?.let { + changeUserArray(it, CommerceEventUtils.getEventType(event), null, true) + } if (!KitUtils.isEmpty(event.productAction) && event.productAction.equals( Product.PURCHASE, @@ -249,7 +296,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") @@ -824,6 +871,7 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, return impressionArray } + internal abstract class StringTypeParser(var enableTypeDetection: Boolean) { fun parseValue(key: String, value: String): Any { if (!enableTypeDetection) { diff --git a/src/test/kotlin/com/braze/Braze.kt b/src/test/kotlin/com/braze/Braze.kt index e6fc4ed..33ce6bf 100644 --- a/src/test/kotlin/com/braze/Braze.kt +++ b/src/test/kotlin/com/braze/Braze.kt @@ -51,6 +51,10 @@ class Braze { events.clear() } + fun clearBrazeUser(){ + currentUser.customUserAttributes.clear() + currentUser.customAttributeArray.clear() + } val currentUser = BrazeUser() @JvmStatic diff --git a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt index 1ac3cea..7ec361a 100644 --- a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt @@ -24,7 +24,10 @@ import org.junit.Before import org.junit.Test import org.mockito.Mock 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 @@ -46,6 +49,7 @@ class AppboyKitTests { MockitoAnnotations.initMocks(this) Braze.clearPurchases() Braze.clearEvents() + Braze.clearBrazeUser() MParticle.setInstance(Mockito.mock(MParticle::class.java)) Mockito.`when`(MParticle.getInstance()!!.Identity()).thenReturn( Mockito.mock( @@ -567,6 +571,225 @@ class AppboyKitTests { Assert.assertEquals(emptyAttributes, properties) } + @Test + fun testCustomAttributes() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + + 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() + .setRevenue(product.totalAmount) + + kit.configuration = MockKitConfiguration() + val customAttributes: MutableMap = 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 commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product) + .currency("EUR") + .customAttributes(customAttributes) + .transactionAttributes(txAttributes) + .build() + + val jsonObject = JSONObject() + val mapValue = JSONObject() + mapValue.put("-94160813", "test") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + + kit.logEvent(commerceEvent) + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("test", outputKey) + + } + + @Test + fun testCustomAttributes_log_event() { + 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 eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + val customAttributes: MutableMap = HashMap() + customAttributes["destination"] = "Shop" + val event = MPEvent.Builder("AndroidTEST", MParticle.EventType.Navigation) + .customAttributes(customAttributes) + .build() + val instance = MParticle.getInstance() + instance?.logEvent(event) + kit.logEvent(event) + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("testEvent", outputKey) + } + + @Test + fun testCustomAttributes_remove_attributes() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + kit.configuration = MockKitConfiguration() + val product: Product = Product.Builder("La Enchilada", "13061043670", 12.5) + .quantity(1.0) + .build() + + val txAttributes = TransactionAttributes() + .setRevenue(product.totalAmount) + + + val customAttributes: MutableMap = 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 commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product) + .currency("EUR") + .customAttributes(customAttributes) + .transactionAttributes(txAttributes) + .build() + + + val jsonObject = JSONObject() + val mapValue = JSONObject() + //this is hash for event attribute i.e combination of eventType + eventName + attribute key + mapValue.put("-844012960", "test") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + eassObject.put("ear", mapValue) + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + + kit.logEvent(commerceEvent) + + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(0, currentUser.getCustomAttribute().size.toLong()) + + } + + + + @Test + fun testCustomAttributes_add_customUserAttribute() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + 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() + .setRevenue(product.totalAmount) + + + val customAttributes: MutableMap = 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 commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product) + .currency("EUR") + .customAttributes(customAttributes) + .transactionAttributes(txAttributes) + .build() + + + val jsonObject = JSONObject() + val mapValue = JSONObject() + //this is hash for event attribute i.e combination of eventType + eventName + attribute key + mapValue.put("-94160813", "test") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + eassObject.put("eas", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + + kit.logEvent(commerceEvent) + + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomUserAttribute().size) + + } + // @Test // fun testPromotion() { // val emptyAttributes = HashMap() @@ -1042,4 +1265,349 @@ 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 = 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 = 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 = 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 = 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()) + } + + @Test + fun testChangeUserArray_for_TransactionAttributes() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + + 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() + .setRevenue(product.totalAmount) + + kit.configuration = MockKitConfiguration() + val commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product) + .currency("EUR") + .transactionAttributes(txAttributes) + .build() + + val jsonObject = JSONObject() + val mapValue = JSONObject() + mapValue.put("-94160813", "transactionAttributes") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + + kit.logEvent(commerceEvent) + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("transactionAttributes", outputKey) + } + + @Test + fun testChangeUserArray_for_Impressions() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + + 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() + + kit.configuration = MockKitConfiguration() + val jsonObject = JSONObject() + val mapValue = JSONObject() + mapValue.put("-1186525452", "TestImpressions") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + Impression("Suggested Products List", product).let { + CommerceEvent.Builder(it).build() + }.let { + kit.logEvent(it) + } + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("TestImpressions", outputKey) + } + + @Test + fun testChangeUserArray_for_Promotions() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + kit.configuration = MockKitConfiguration() + val jsonObject = JSONObject() + val mapValue = JSONObject() + mapValue.put("1458842803", "TestImpressions") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + Promotion().apply { + id = "test_1" + creative = "test_button_1" + name = "10% off Sale" + position ="button_center" + }.let { + CommerceEvent.Builder(Promotion.CLICK, it).build() + }.let { + kit.logEvent(it) + } + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("TestImpressions", outputKey) + } + + @Test + fun testChangeUserArray_for_Promotions_with_custom_attribute() { + val kit = MockAppboyKit() + val currentUser = braze.currentUser + kit.configuration = MockKitConfiguration() + val jsonObject = JSONObject() + val mapValue = JSONObject() + mapValue.put("1560179420", "TestImpressions") + val eassObject = JSONObject() + eassObject.put("eaa", mapValue) + + jsonObject.put("hs", eassObject) + val mockSparseBooleanArray = mock(SparseBooleanArray::class.java) + + `when`(mockSparseBooleanArray.size()).thenReturn(0) + `when`(mTypeFilters!!.size()).thenReturn(0) // Example mock behavior + + var kitConfiguration = MockKitConfiguration.createKitConfiguration(jsonObject) + kit.configuration = kitConfiguration + Promotion().apply { + id = "test_1" + creative = "test_button_1" + name = "10% off Sale" + position ="button_center" + }.let { + CommerceEvent.Builder(Promotion.CLICK, it).customAttributes( + mapOf( + "color" to "Red", + "Total Amount" to "150.00" + )).build() + }.let { + kit.logEvent(it) + } + Assert.assertEquals(1, braze.events.size.toLong()) + Assert.assertEquals(1, currentUser.getCustomAttribute().size.toLong()) + var outputKey = "" + for (keys in currentUser.getCustomAttribute().keys) { + outputKey = keys + break + } + Assert.assertEquals("TestImpressions", outputKey) + } + }