From a13045bfcb02e26750f80f5891843df84f53019a Mon Sep 17 00:00:00 2001 From: Mansi Pandya Date: Wed, 7 Jan 2026 16:10:28 -0500 Subject: [PATCH 1/3] feat: Add custom event logging for selectplacements --- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 6 ++ .../kotlin/com/mparticle/kits/RoktKitTests.kt | 89 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 44642cc..6d27286 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.BuildConfig +import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.MpRoktEventCallback @@ -231,6 +232,11 @@ class RoktKit : addIdentityAttributes(finalAttributes, filterUser) verifyHashedEmail(finalAttributes) + + val event = MPEvent.Builder("selectplacements", MParticle.EventType.Other) + .customAttributes(finalAttributes) + .build() + MParticle.getInstance()?.logEvent(event) return finalAttributes } diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index a992766..f32c68e 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -6,6 +6,7 @@ import android.net.Uri import android.os.Build.VERSION import com.mparticle.AttributionError import com.mparticle.AttributionResult +import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.MParticleOptions @@ -39,6 +40,7 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test +import org.mockito.ArgumentCaptor import org.mockito.Mockito import org.mockito.Mockito.mock import java.lang.ref.WeakReference @@ -1281,6 +1283,93 @@ class RoktKitTests { field[null] = newValue } } + @Test + fun test_prepareFinalAttributes_logs_attributes_event() { + val mParticleMock = MParticle.getInstance()!! + val method: Method = RoktKit::class.java.getDeclaredMethod( + "prepareFinalAttributes", + FilteredMParticleUser::class.java, + Map::class.java, + ) + method.isAccessible = true + + val mockFilterUser = mock(FilteredMParticleUser::class.java) + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(HashMap()) + Mockito.`when`(mockFilterUser.id).thenReturn(9876L) + val userAttributes = hashMapOf("user_key" to "user_val") + Mockito.`when`(mockFilterUser.userAttributes).thenReturn(userAttributes) + + roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", JSONObject())) + val attributes: Map = mapOf("attr1" to "val1") + + method.invoke(roktKit, mockFilterUser, attributes) + + val eventCaptor = ArgumentCaptor.forClass(MPEvent::class.java) + Mockito.verify(mParticleMock).logEvent(eventCaptor.capture()) + + val loggedEvent = eventCaptor.value + assertEquals("selectplacements", loggedEvent.eventName) + assertEquals(MParticle.EventType.Other, loggedEvent.eventType) + assertEquals( + mapOf( + "user_key" to "user_val", + "attr1" to "val1", + "mpid" to "9876", + ), + loggedEvent.customAttributes, + ) + } + + @Test + fun test_execute_logsMPEventWhenMParticleInstanceIsNull() { + // Arrange + mockkObject(Rokt) + every { + Rokt.execute( + any(), + any>(), + any(), + any(), + any(), + any(), + ) + } just runs + + val mockFilterUser = mock(FilteredMParticleUser::class.java) + Mockito.`when`(mockFilterUser.userIdentities).thenReturn(HashMap()) + Mockito.`when`(mockFilterUser.id).thenReturn(12345L) + Mockito.`when`(mockFilterUser.userAttributes).thenReturn(HashMap()) + + roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", JSONObject())) + + val testAttributes = mapOf("key1" to "value1") + + // Set MParticle instance to null + MParticle.setInstance(null) + + roktKit.execute( + viewName = "test_view", + attributes = testAttributes, + mpRoktEventCallback = null, + placeHolders = null, + fontTypefaces = null, + filterUser = mockFilterUser, + mpRoktConfig = null, + ) + + verify(exactly = 1) { + Rokt.execute( + any(), + any>(), + any(), + any(), + any(), + any(), + ) + } + + unmockkObject(Rokt) + } private var emptyCoreCallbacks: CoreCallbacks = object : CoreCallbacks { var activity = Activity() From b21f0a1e8f685bb8674ddcb31edffb274a9da623 Mon Sep 17 00:00:00 2001 From: Mansi Pandya Date: Tue, 13 Jan 2026 17:37:05 -0500 Subject: [PATCH 2/3] Addres review comments --- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 6d27286..1e38119 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -233,10 +233,7 @@ class RoktKit : verifyHashedEmail(finalAttributes) - val event = MPEvent.Builder("selectplacements", MParticle.EventType.Other) - .customAttributes(finalAttributes) - .build() - MParticle.getInstance()?.logEvent(event) + logSelectPlacementEvent(finalAttributes) return finalAttributes } @@ -386,6 +383,13 @@ class RoktKit : } } + private fun logSelectPlacementEvent(attributes: Map) { + val event = MPEvent.Builder(EVENT_NAME_SELECT_PLACEMENTS, MParticle.EventType.Other) + .customAttributes(attributes) + .build() + MParticle.getInstance()?.logEvent(event) + } + private fun getStringForIdentity(identityType: IdentityType): String = when (identityType) { IdentityType.Other -> "other" IdentityType.CustomerId -> "customerid" @@ -425,6 +429,7 @@ class RoktKit : const val ROKT_ACCOUNT_ID = "accountId" const val HASHED_EMAIL_USER_IDENTITY_TYPE = "hashedEmailUserIdentityType" const val MPID = "mpid" + const val EVENT_NAME_SELECT_PLACEMENTS = "selectplacements" const val NO_ROKT_ACCOUNT_ID = "No Rokt account ID provided, can't initialize kit." const val NO_APP_VERSION_FOUND = "No App version found, can't initialize kit." } From 61595efd39018eabbe2f9e51af045a73eb2a3d6c Mon Sep 17 00:00:00 2001 From: Mansi Pandya Date: Thu, 29 Jan 2026 10:54:01 -0500 Subject: [PATCH 3/3] Address review comment --- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 2 +- src/test/kotlin/com/mparticle/kits/RoktKitTests.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 1e38119..f9a8aa6 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -429,7 +429,7 @@ class RoktKit : const val ROKT_ACCOUNT_ID = "accountId" const val HASHED_EMAIL_USER_IDENTITY_TYPE = "hashedEmailUserIdentityType" const val MPID = "mpid" - const val EVENT_NAME_SELECT_PLACEMENTS = "selectplacements" + const val EVENT_NAME_SELECT_PLACEMENTS = "selectPlacements" const val NO_ROKT_ACCOUNT_ID = "No Rokt account ID provided, can't initialize kit." const val NO_APP_VERSION_FOUND = "No App version found, can't initialize kit." } diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index f32c68e..c532f40 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -1283,6 +1283,7 @@ class RoktKitTests { field[null] = newValue } } + @Test fun test_prepareFinalAttributes_logs_attributes_event() { val mParticleMock = MParticle.getInstance()!! @@ -1308,7 +1309,7 @@ class RoktKitTests { Mockito.verify(mParticleMock).logEvent(eventCaptor.capture()) val loggedEvent = eventCaptor.value - assertEquals("selectplacements", loggedEvent.eventName) + assertEquals("selectPlacements", loggedEvent.eventName) assertEquals(MParticle.EventType.Other, loggedEvent.eventType) assertEquals( mapOf(