Skip to content

Commit 28fec59

Browse files
feat: Handle emailsha256 and other before sending attributes to Rokt Kit (#51)
1 parent 382e74c commit 28fec59

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.content.pm.PackageManager
77
import android.graphics.Typeface
88
import android.os.Build
99
import com.mparticle.BuildConfig
10+
import com.mparticle.MParticle
1011
import com.mparticle.MParticle.IdentityType
1112
import com.mparticle.MpRoktEventCallback
1213
import com.mparticle.UnloadReasons
@@ -188,7 +189,7 @@ class RoktKit : KitIntegration(), CommerceListener, IdentityListener, RoktListen
188189
}?.toMap()
189190

190191
this.mpRoktEventCallback = mpRoktEventCallback
191-
val finalAttributes: HashMap<String, String> = HashMap<String, String>()
192+
val finalAttributes = mutableMapOf<String, String>()
192193
filterUser?.userAttributes?.let { userAttrs ->
193194
for ((key, value) in userAttrs) {
194195
finalAttributes[key] = value.toString()
@@ -206,6 +207,7 @@ class RoktKit : KitIntegration(), CommerceListener, IdentityListener, RoktListen
206207
attributes?.get(SANDBOX_MODE_ROKT)?.let { value ->
207208
finalAttributes.put(SANDBOX_MODE_ROKT, value)
208209
}
210+
verifyHashedEmail(finalAttributes)
209211
val roktConfig = mpRoktConfig?.let { mapToRoktConfig(it) }
210212
Rokt.execute(
211213
viewName,
@@ -318,9 +320,31 @@ class RoktKit : KitIntegration(), CommerceListener, IdentityListener, RoktListen
318320
}
319321
}
320322

323+
private fun verifyHashedEmail(attributes: MutableMap<String, String>?) {
324+
if (attributes == null) return
325+
326+
val emailKey = MParticle.IdentityType.Email.name.lowercase()
327+
val emailShaKey = "emailsha256"
328+
329+
val emailShaValue = attributes.entries.find { it.key.equals(emailShaKey, ignoreCase = true) }?.value
330+
331+
when {
332+
!emailShaValue.isNullOrEmpty() -> {
333+
// If emailsha256 is already present, remove entries with email
334+
val iterator = attributes.entries.iterator()
335+
while (iterator.hasNext()) {
336+
val entry = iterator.next()
337+
if (entry.key.equals(emailKey, ignoreCase = true)) {
338+
iterator.remove()
339+
}
340+
}
341+
}
342+
}
343+
}
344+
321345
private fun getStringForIdentity(identityType: IdentityType): String {
322346
return when (identityType) {
323-
IdentityType.Other -> "other"
347+
IdentityType.Other -> "emailsha256"
324348
IdentityType.CustomerId -> "customerid"
325349
IdentityType.Facebook -> "facebook"
326350
IdentityType.Twitter -> "twitter"

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.toList
2525
import kotlinx.coroutines.test.runTest
2626
import org.json.JSONArray
2727
import org.junit.Assert.assertEquals
28+
import org.junit.Assert.assertFalse
2829
import org.junit.Assert.assertTrue
2930
import org.junit.Before
3031
import org.junit.Test
@@ -238,6 +239,34 @@ class RoktKitTests {
238239
assertTrue(result.containsKey("key3"))
239240
}
240241

242+
@Test
243+
fun test_addIdentityAttributes_When_userIdentities_Contain_other() {
244+
val mockFilterUser = mock(FilteredMParticleUser::class.java)
245+
val userIdentities = HashMap<IdentityType, String>()
246+
userIdentities.put(IdentityType.Email, "[email protected]")
247+
userIdentities.put(IdentityType.Other, "[email protected]")
248+
Mockito.`when`(mockFilterUser.userIdentities).thenReturn(userIdentities)
249+
val attributes: Map<String, String> = mapOf(
250+
"key1" to "value1",
251+
"key2" to "value2",
252+
"key3" to "value3"
253+
)
254+
val method: Method = RoktKit::class.java.getDeclaredMethod(
255+
"addIdentityAttributes",
256+
Map::class.java,
257+
FilteredMParticleUser::class.java
258+
)
259+
method.isAccessible = true
260+
val result = method.invoke(roktKit, attributes, mockFilterUser) as Map<String, String>
261+
assertEquals(5, result.size)
262+
263+
assertTrue(result.containsKey("key1"))
264+
assertTrue(result.containsKey("key2"))
265+
assertTrue(result.containsKey("key3"))
266+
assertTrue(result.containsKey("email"))
267+
assertTrue(result.containsKey("emailsha256"))
268+
}
269+
241270
@Test
242271
fun testSetSdkWrapper_correctlySetsRoktFramework() {
243272
mockkObject(Rokt)
@@ -530,6 +559,44 @@ class RoktKitTests {
530559
unmockkObject(Rokt)
531560
}
532561

562+
@Test
563+
fun TestverifyHashedEmail_removes_when_emailsha256_is_present() {
564+
val attributes = mutableMapOf(
565+
"email" to "[email protected]",
566+
"emailsha256" to "hashed_email_value",
567+
"other" to "Test"
568+
)
569+
val method: Method = RoktKit::class.java.getDeclaredMethod(
570+
"verifyHashedEmail",
571+
MutableMap::class.java
572+
)
573+
method.isAccessible = true
574+
method.invoke(roktKit, attributes)
575+
576+
577+
assertFalse(attributes.containsKey("email"))
578+
assertEquals("hashed_email_value", attributes["emailsha256"])
579+
assertEquals("Test", attributes["other"])
580+
}
581+
582+
583+
@Test
584+
fun TestverifyHashedEmail_removes_when_neither_emailsha256_nor_other_is_present() {
585+
val attributes = mutableMapOf(
586+
"email" to "[email protected]"
587+
)
588+
589+
val method: Method = RoktKit::class.java.getDeclaredMethod(
590+
"verifyHashedEmail",
591+
MutableMap::class.java
592+
)
593+
method.isAccessible = true
594+
method.invoke(roktKit, attributes)
595+
596+
assertEquals("[email protected]", attributes["email"])
597+
assertFalse(attributes.containsKey("emailsha256"))
598+
}
599+
533600
internal inner class TestCoreCallbacks : CoreCallbacks {
534601
override fun isBackgrounded(): Boolean = false
535602
override fun getUserBucket(): Int = 0

0 commit comments

Comments
 (0)