From fa44865bf835908f7868ba043d6421f75c773ffa Mon Sep 17 00:00:00 2001 From: Mansi Pandya Date: Thu, 15 May 2025 09:36:45 -0400 Subject: [PATCH 1/2] feat: Add all identities from mp user to rokt attributes --- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 54 ++++- .../kotlin/com/mparticle/kits/RoktKitTests.kt | 205 ++++++------------ 2 files changed, 108 insertions(+), 151 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 849b94d..c1f4235 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -7,6 +7,7 @@ import android.content.pm.PackageManager import android.graphics.Typeface import android.os.Build import com.mparticle.MParticle +import com.mparticle.MParticle.IdentityType import com.mparticle.commerce.CommerceEvent import com.mparticle.identity.MParticleUser import com.mparticle.internal.Logger @@ -139,14 +140,13 @@ class RoktKit : KitIntegration(), CommerceListener, IdentityListener, RoktListen finalAttributes[key] = value.toString() } } - filterAttributes(finalAttributes, configuration).let { - finalAttributes.putAll(it) - } + filterUser?.id?.let { mpid -> finalAttributes.put(MPID, mpid.toString()) } ?: run { Logger.warning("RoktKit: No user ID available for placement") } + addIdentityAttributes(finalAttributes, filterUser) Rokt.execute( viewName, @@ -158,15 +158,49 @@ class RoktKit : KitIntegration(), CommerceListener, IdentityListener, RoktListen ) } - private fun filterAttributes(attributes: Map, kitConfiguration: KitConfiguration): Map { - val userAttributes: MutableMap = HashMap() - for ((key, value) in attributes) { - val hashKey = KitUtils.hashForFiltering(key) - if (!kitConfiguration.mAttributeFilters.get(hashKey)) { - userAttributes[key] = value + + private fun addIdentityAttributes(attributes: MutableMap?, filterUser: FilteredMParticleUser?): MutableMap { + val identityAttributes = mutableMapOf() + if (filterUser != null) { + for ((identityNumberKey, identityValue) in filterUser.userIdentities) { + val identityType = getStringForIdentity(identityNumberKey) + identityAttributes[identityType] = identityValue } } - return userAttributes + if (attributes != null) { + attributes.putAll(identityAttributes) + return attributes + } else { + return identityAttributes + } + } + + private fun getStringForIdentity(identityType: IdentityType): String { + return when (identityType) { + IdentityType.Other -> "other" + IdentityType.CustomerId -> "customerid" + IdentityType.Facebook -> "facebook" + IdentityType.Twitter -> "twitter" + IdentityType.Google -> "google" + IdentityType.Microsoft -> "microsoft" + IdentityType.Yahoo -> "yahoo" + IdentityType.Email -> "email" + IdentityType.Alias -> "alias" + IdentityType.FacebookCustomAudienceId -> "facebookcustomaudienceid" + IdentityType.Other2 -> "other2" + IdentityType.Other3 -> "other3" + IdentityType.Other4 -> "other4" + IdentityType.Other5 -> "other5" + IdentityType.Other6 -> "other6" + IdentityType.Other7 -> "other7" + IdentityType.Other8 -> "other8" + IdentityType.Other9 -> "other9" + IdentityType.Other10 -> "other10" + IdentityType.MobileNumber -> "mobilenumber" + IdentityType.PhoneNumber2 -> "phonenumber2" + IdentityType.PhoneNumber3 -> "phonenumber3" + else -> "" + } } companion object { diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index 8fbf585..c22143a 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -7,6 +7,7 @@ import android.os.Build.VERSION import com.mparticle.AttributionError import com.mparticle.AttributionResult import com.mparticle.MParticle +import com.mparticle.MParticle.IdentityType import com.mparticle.MParticleOptions import com.mparticle.MParticleOptions.DataplanOptions import com.mparticle.identity.IdentityApi @@ -98,186 +99,108 @@ class RoktKitTests { } @Test - fun testFilterAttributes() { - - // Create test attributes + fun test_addIdentityAttributes_When_userIdentities_IS_Null(){ + val mockFilterUser = Mockito.mock(FilteredMParticleUser::class.java) + val userIdentities = HashMap() + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(userIdentities) val attributes: Map = mapOf( - "ShouldFilter" to "shoudl_filter_value", - "ShouldFilter_key_2" to "ShouldFilter_value", - "allowed_key" to "allowed_value" + "key1" to "value1", + "key2" to "value2", + "key3" to "value3" ) - - // Get the private filterAttributes method using reflection val method: Method = RoktKit::class.java.getDeclaredMethod( - "filterAttributes", + "addIdentityAttributes", Map::class.java, - KitConfiguration::class.java + FilteredMParticleUser::class.java ) method.isAccessible = true + val result = method.invoke(roktKit, attributes, mockFilterUser) as Map + assertEquals(3, result.size) - // Set up the configuration with our test filters - val jsonObject = JSONObject() - try { - val filteredKey:String =KitUtils.hashForFiltering("ShouldFilter").toString() - val allowedKey:String = KitUtils.hashForFiltering("ShouldFilter_key_2").toString() - jsonObject.put(filteredKey, 0) - jsonObject.put(allowedKey, 1) - } catch (e: Exception) { - println("Exception occurred: ${e.message}") - } - - val json = JSONObject() - json.put("ea", jsonObject) - - - roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs",json)) - - // Invoke the method and get the result - val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map - - // Verify the results - assertEquals(1, result.size) + assertTrue(result.containsKey("key1")) + assertTrue(result.containsKey("key2")) + assertTrue(result.containsKey("key3")) - assertFalse(result.containsKey("ShouldFilter")) - assertFalse(result.containsKey("ShouldFilter_key_2")) - assertTrue(result.containsKey("allowed_key")) - assertEquals("allowed_value", result["allowed_key"]) } @Test - fun testFilterAttributes_When_kitConfig_Attributes_IS_NULL() { - - // Create test attributes + fun test_addIdentityAttributes_When_userIdentities_Contain_value(){ + val mockFilterUser = Mockito.mock(FilteredMParticleUser::class.java) + val userIdentities = HashMap() + userIdentities.put(IdentityType.Email,"TestEmail@gamil.com") + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(userIdentities) val attributes: Map = mapOf( - "filtered_key" to "filtered_value", - "allowed_key" to "allowed_value", - "another_allowed_key" to "another_allowed_value" + "key1" to "value1", + "key2" to "value2", + "key3" to "value3" ) - - // Get the private filterAttributes method using reflection val method: Method = RoktKit::class.java.getDeclaredMethod( - "filterAttributes", + "addIdentityAttributes", Map::class.java, - KitConfiguration::class.java + FilteredMParticleUser::class.java ) method.isAccessible = true + val result = method.invoke(roktKit, attributes, mockFilterUser) as Map + assertEquals(4, result.size) - // Set up the configuration with our test filters - val jsonObject = JSONObject() - try { - val filteredKey:String =KitUtils.hashForFiltering("filtered_key").toString() - val allowedKey:String = KitUtils.hashForFiltering("allowed_key").toString() - jsonObject.put(filteredKey, 0) - jsonObject.put(allowedKey, 1) - } catch (e: Exception) { - println("Exception occurred: ${e.message}") - } - - val json = JSONObject() - //here is invalid json key for filtering - json.put("aaa", jsonObject) - - - roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs",json)) - - // Invoke the method and get the result - val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map - - assertEquals(3, result.size) + assertTrue(result.containsKey("key1")) + assertTrue(result.containsKey("key2")) + assertTrue(result.containsKey("key3")) + assertTrue(result.containsKey("email")) - assertTrue(result.containsKey("allowed_key")) - assertTrue(result.containsKey("filtered_key")) - assertTrue(result.containsKey("another_allowed_key")) - assertEquals("another_allowed_value", result["another_allowed_key"]) } @Test - fun testFilterAttributes_When_Attributes_IS_Empty() { - - // Create test attributes - val emptyAttributes: Map = emptyMap() - - - // Get the private filterAttributes method using reflection + fun testAddIdentityAttributes_bothNull() { val method: Method = RoktKit::class.java.getDeclaredMethod( - "filterAttributes", + "addIdentityAttributes", Map::class.java, - KitConfiguration::class.java + FilteredMParticleUser::class.java ) method.isAccessible = true - - // Set up the configuration with our test filters - val jsonObject = JSONObject() - try { - val filteredKey:String =KitUtils.hashForFiltering("filtered_key").toString() - val allowedKey:String = KitUtils.hashForFiltering("allowed_key").toString() - jsonObject.put(filteredKey, 0) - jsonObject.put(allowedKey, 1) - } catch (e: Exception) { - println("Exception occurred: ${e.message}") - } - - val json = JSONObject() - json.put("aaa", jsonObject) - - - roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs",json)) - - // Invoke the method and get the result - val result = method.invoke(roktKit, emptyAttributes, roktKit.configuration) as Map - - assertEquals(0, result.size) + val result = method.invoke(roktKit, null, null) as Map + assertTrue(result.isEmpty()) } @Test - fun testFilterAttributes_When_attribute_different_value() { + fun testAddIdentityAttributes_nullAttributes_validUser() { + val mockFilterUser = Mockito.mock(FilteredMParticleUser::class.java) + val userIdentities = HashMap() + userIdentities.put(IdentityType.Email,"TestEmail@gamil.com") + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(userIdentities) + val method: Method = RoktKit::class.java.getDeclaredMethod( + "addIdentityAttributes", + Map::class.java, + FilteredMParticleUser::class.java + ) + method.isAccessible = true + val result = method.invoke(roktKit, null, mockFilterUser) as Map + assertEquals(1, result.size) + assertEquals(mapOf("email" to "TestEmail@gamil.com"), result) + } - // Create test attributes + @Test + fun testAddIdentityAttributes_nullUser_returnsSameAttributes() { val attributes: Map = mapOf( - "filtered_key" to "filtered_value", - "allowed_key" to "allowed_value", - "another_allowed_key" to "another_allowed_value" + "key1" to "value1", + "key2" to "value2", + "key3" to "value3" ) - - // Get the private filterAttributes method using reflection val method: Method = RoktKit::class.java.getDeclaredMethod( - "filterAttributes", + "addIdentityAttributes", Map::class.java, - KitConfiguration::class.java + FilteredMParticleUser::class.java ) method.isAccessible = true - - // Set up the configuration with our test filters - val jsonObject = JSONObject() - try { - val filteredKey:String =KitUtils.hashForFiltering("Test1").toString() - val allowedKey:String = KitUtils.hashForFiltering("Test2").toString() - jsonObject.put(filteredKey, 0) - jsonObject.put(allowedKey, 1) - } catch (e: Exception) { - println("Exception occurred: ${e.message}") - } - - val json = JSONObject() - json.put("ea", jsonObject) - - - roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs",json)) - - // Invoke the method and get the result - val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map - - // Verify the results + val result = method.invoke(roktKit, attributes, null) as Map assertEquals(3, result.size) - - assertTrue(result.containsKey("filtered_key")) - assertTrue(result.containsKey("allowed_key")) - assertTrue(result.containsKey("another_allowed_key")) - assertEquals("another_allowed_value", result["another_allowed_key"]) - assertEquals("filtered_value", result["filtered_key"]) - assertEquals("allowed_value", result["allowed_key"]) + assertTrue(result.containsKey("key1")) + assertTrue(result.containsKey("key2")) + assertTrue(result.containsKey("key3")) } + + internal inner class TestCoreCallbacks : CoreCallbacks { override fun isBackgrounded(): Boolean = false override fun getUserBucket(): Int = 0 From 37aa371cabb9fa60360139757a9cae168ef37533 Mon Sep 17 00:00:00 2001 From: Mansi Pandya Date: Thu, 15 May 2025 15:49:54 -0400 Subject: [PATCH 2/2] Add missing test cases --- .../kotlin/com/mparticle/kits/RoktKitTests.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index c22143a..5b8a34b 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -150,6 +150,42 @@ class RoktKitTests { } + @Test + fun test_addIdentityAttributes_When_userIdentities_And_attributes_contains_same_key(){ + val mockFilterUser = Mockito.mock(FilteredMParticleUser::class.java) + val userIdentities = HashMap() + userIdentities.put(IdentityType.Email,"TestEmail@gamil.com") + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(userIdentities) + val attributes: Map = mapOf( + "key1" to "value1", + "key2" to "value2", + "key3" to "value3", + "email" to "abc@gmail.com" + ) + val method: Method = RoktKit::class.java.getDeclaredMethod( + "addIdentityAttributes", + Map::class.java, + FilteredMParticleUser::class.java + ) + method.isAccessible = true + val result = method.invoke(roktKit, attributes, mockFilterUser) as Map + assertEquals(4, result.size) + + assertTrue(result.containsKey("key1")) + assertTrue(result.containsKey("key2")) + assertTrue(result.containsKey("key3")) + assertTrue(result.containsKey("email")) + assertEquals( + mapOf( + "key1" to "value1", + "key2" to "value2", + "key3" to "value3", + "email" to "TestEmail@gamil.com" + ), + result + ) + } + @Test fun testAddIdentityAttributes_bothNull() { val method: Method = RoktKit::class.java.getDeclaredMethod(