Skip to content

Commit e557ef4

Browse files
fix: user attributes missing when calling execute call (#86)
1 parent 195cab2 commit e557ef4

File tree

2 files changed

+190
-6
lines changed

2 files changed

+190
-6
lines changed

src/main/kotlin/com/mparticle/kits/RoktKit.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ class RoktKit :
212212
filterUser: FilteredMParticleUser?,
213213
attributes: Map<String, String>,
214214
): Map<String, String> {
215-
val finalAttributes = mutableMapOf<String, String>()
215+
val finalAttributes = filterAttributes(attributes, configuration)
216+
216217
filterUser?.userAttributes?.let { userAttrs ->
217218
for ((key, value) in userAttrs) {
218219
if (value != null) {
@@ -227,13 +228,21 @@ class RoktKit :
227228

228229
addIdentityAttributes(finalAttributes, filterUser)
229230

230-
attributes[ROKT_ATTRIBUTE_SANDBOX_MODE]?.let { value ->
231-
finalAttributes.put(ROKT_ATTRIBUTE_SANDBOX_MODE, value)
232-
}
233231
verifyHashedEmail(finalAttributes)
234232
return finalAttributes
235233
}
236234

235+
private fun filterAttributes(attributes: Map<String, String>, kitConfiguration: KitConfiguration): MutableMap<String, String> {
236+
val userAttributes = mutableMapOf<String, String>()
237+
for ((key, value) in attributes) {
238+
val hashKey = KitUtils.hashForFiltering(key)
239+
if (!kitConfiguration.mUserAttributeFilters.get(hashKey)) {
240+
userAttributes[key] = value
241+
}
242+
}
243+
return userAttributes
244+
}
245+
237246
override fun events(identifier: String): Flow<com.mparticle.RoktEvent> = Rokt.events(identifier).map { event ->
238247
when (event) {
239248
is RoktEvent.HideLoadingIndicator -> com.mparticle.RoktEvent.HideLoadingIndicator

src/test/kotlin/com/mparticle/kits/RoktKitTests.kt

Lines changed: 177 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.mparticle.WrapperSdkVersion
1515
import com.mparticle.identity.IdentityApi
1616
import com.mparticle.internal.CoreCallbacks
1717
import com.mparticle.internal.CoreCallbacks.KitListener
18+
import com.mparticle.kits.mocks.MockKitConfiguration
1819
import com.rokt.roktsdk.FulfillmentAttributes
1920
import com.rokt.roktsdk.Rokt
2021
import com.rokt.roktsdk.RoktEvent
@@ -31,6 +32,7 @@ import kotlinx.coroutines.flow.flowOf
3132
import kotlinx.coroutines.flow.toList
3233
import kotlinx.coroutines.test.runTest
3334
import org.json.JSONArray
35+
import org.json.JSONObject
3436
import org.junit.Assert.assertEquals
3537
import org.junit.Assert.assertFalse
3638
import org.junit.Assert.assertTrue
@@ -85,7 +87,21 @@ class RoktKitTests {
8587
userAttributes["attr_null"] = null
8688
userAttributes["attr_non_string"] = 123
8789
Mockito.`when`(mockFilterUser.userAttributes).thenReturn(userAttributes)
90+
// Set up the configuration with our test filters
91+
val jsonObject = JSONObject()
92+
try {
93+
val filteredKey: String = KitUtils.hashForFiltering("ShouldFilter").toString()
94+
val filteredKey2: String = KitUtils.hashForFiltering("ShouldFilter_key_2").toString()
95+
jsonObject.put(filteredKey, 0)
96+
jsonObject.put(filteredKey2, 1)
97+
} catch (e: Exception) {
98+
println("Exception occurred: ${e.message}")
99+
}
100+
val json = JSONObject()
101+
json.put("ua", jsonObject)
102+
88103

104+
roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", json))
89105
val method: Method = RoktKit::class.java.getDeclaredMethod(
90106
"prepareFinalAttributes",
91107
FilteredMParticleUser::class.java,
@@ -111,9 +127,9 @@ class RoktKitTests {
111127
var attributes = HashMap<String, String>()
112128
var result: AttributionResult? = null
113129
private var error: AttributionError? = null
114-
public override fun getIntegrationAttributes(kitIntegration: KitIntegration): Map<String, String> = attributes
130+
override fun getIntegrationAttributes(kitIntegration: KitIntegration): Map<String, String> = attributes
115131

116-
public override fun setIntegrationAttributes(
132+
override fun setIntegrationAttributes(
117133
kitIntegration: KitIntegration,
118134
integrationAttributes: Map<String, String>,
119135
) {
@@ -693,6 +709,165 @@ class RoktKitTests {
693709
assertFalse(attributes.containsKey("emailsha256"))
694710
}
695711

712+
@Test
713+
fun testFilterAttributes() {
714+
// Create test attributes
715+
val attributes: Map<String, String> = mapOf(
716+
"ShouldFilter" to "shoudl_filter_value",
717+
"ShouldFilter_key_2" to "ShouldFilter_value",
718+
"allowed_key" to "allowed_value",
719+
)
720+
721+
// Get the private filterAttributes method using reflection
722+
val method: Method = RoktKit::class.java.getDeclaredMethod(
723+
"filterAttributes",
724+
Map::class.java,
725+
KitConfiguration::class.java,
726+
)
727+
method.isAccessible = true
728+
729+
// Set up the configuration with our test filters
730+
val jsonObject = JSONObject()
731+
try {
732+
val filteredKey: String = KitUtils.hashForFiltering("ShouldFilter").toString()
733+
val filteredKey2: String = KitUtils.hashForFiltering("ShouldFilter_key_2").toString()
734+
jsonObject.put(filteredKey, 0)
735+
jsonObject.put(filteredKey2, 1)
736+
} catch (e: Exception) {
737+
println("Exception occurred: ${e.message}")
738+
}
739+
740+
val json = JSONObject()
741+
json.put("ua", jsonObject)
742+
743+
roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", json))
744+
745+
// Invoke the method and get the result
746+
val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map<String, String>
747+
748+
// Verify the results
749+
assertEquals(1, result.size)
750+
751+
assertFalse(result.containsKey("ShouldFilter"))
752+
assertFalse(result.containsKey("ShouldFilter_key_2"))
753+
assertTrue(result.containsKey("allowed_key"))
754+
assertEquals("allowed_value", result["allowed_key"])
755+
}
756+
757+
@Test
758+
fun testFilterAttributes_When_kitConfig_User_Attributes_Filtering_IS_NULL() {
759+
// Create test attributes
760+
val attributes: Map<String, String> = mapOf(
761+
"filtered_key" to "filtered_value",
762+
"allowed_key" to "allowed_value",
763+
"another_allowed_key" to "another_allowed_value",
764+
)
765+
766+
// Get the private filterAttributes method using reflection
767+
val method: Method = RoktKit::class.java.getDeclaredMethod(
768+
"filterAttributes",
769+
Map::class.java,
770+
KitConfiguration::class.java,
771+
)
772+
method.isAccessible = true
773+
774+
val json = JSONObject()
775+
776+
roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", json))
777+
778+
// Invoke the method and get the result
779+
val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map<String, String>
780+
781+
assertEquals(3, result.size)
782+
783+
assertTrue(result.containsKey("allowed_key"))
784+
assertTrue(result.containsKey("filtered_key"))
785+
assertTrue(result.containsKey("another_allowed_key"))
786+
assertEquals("another_allowed_value", result["another_allowed_key"])
787+
}
788+
789+
@Test
790+
fun testFilterAttributes_When_Attributes_IS_Empty() {
791+
// Create test attributes
792+
val emptyAttributes: Map<String, String> = emptyMap()
793+
794+
// Get the private filterAttributes method using reflection
795+
val method: Method = RoktKit::class.java.getDeclaredMethod(
796+
"filterAttributes",
797+
Map::class.java,
798+
KitConfiguration::class.java,
799+
)
800+
method.isAccessible = true
801+
802+
// Set up the configuration with our test filters
803+
val jsonObject = JSONObject()
804+
try {
805+
val filteredKey: String = KitUtils.hashForFiltering("filtered_key").toString()
806+
val filteredKey2: String = KitUtils.hashForFiltering("allowed_key").toString()
807+
jsonObject.put(filteredKey, 0)
808+
jsonObject.put(filteredKey2, 1)
809+
} catch (e: Exception) {
810+
println("Exception occurred: ${e.message}")
811+
}
812+
813+
val json = JSONObject()
814+
json.put("aaa", jsonObject)
815+
816+
roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", json))
817+
818+
// Invoke the method and get the result
819+
val result = method.invoke(roktKit, emptyAttributes, roktKit.configuration) as Map<String, String>
820+
821+
assertEquals(0, result.size)
822+
}
823+
824+
@Test
825+
fun testFilterAttributes_Allows_Attributes_To_Be_Set_When_When_Filtered_User_Attributes_Differ() {
826+
// Create test attributes
827+
val attributes: Map<String, String> = mapOf(
828+
"filtered_key" to "filtered_value",
829+
"allowed_key" to "allowed_value",
830+
"another_allowed_key" to "another_allowed_value",
831+
)
832+
833+
// Get the private filterAttributes method using reflection
834+
val method: Method = RoktKit::class.java.getDeclaredMethod(
835+
"filterAttributes",
836+
Map::class.java,
837+
KitConfiguration::class.java,
838+
)
839+
method.isAccessible = true
840+
841+
// Set up the configuration with our test filters
842+
val jsonObject = JSONObject()
843+
try {
844+
val filteredKey: String = KitUtils.hashForFiltering("Test1").toString()
845+
val filteredKey2: String = KitUtils.hashForFiltering("Test2").toString()
846+
jsonObject.put(filteredKey, 0)
847+
jsonObject.put(filteredKey2, 1)
848+
} catch (e: Exception) {
849+
println("Exception occurred: ${e.message}")
850+
}
851+
852+
val json = JSONObject()
853+
json.put("us", jsonObject)
854+
855+
roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", json))
856+
857+
// Invoke the method and get the result
858+
val result = method.invoke(roktKit, attributes, roktKit.configuration) as Map<String, String>
859+
860+
// Verify the results
861+
assertEquals(3, result.size)
862+
863+
assertTrue(result.containsKey("filtered_key"))
864+
assertTrue(result.containsKey("allowed_key"))
865+
assertTrue(result.containsKey("another_allowed_key"))
866+
assertEquals("another_allowed_value", result["another_allowed_key"])
867+
assertEquals("filtered_value", result["filtered_key"])
868+
assertEquals("allowed_value", result["allowed_key"])
869+
}
870+
696871
internal inner class TestCoreCallbacks : CoreCallbacks {
697872
override fun isBackgrounded(): Boolean = false
698873
override fun getUserBucket(): Int = 0

0 commit comments

Comments
 (0)