Skip to content

Commit 9a1822f

Browse files
committed
feat: Add PlacementOptions support to Rokt integration
- Add integration start timestamp to the `PlacementOptions` object and pass it down to RoktKit - Add unit tests
1 parent fc6a25d commit 9a1822f

8 files changed

Lines changed: 180 additions & 6 deletions

File tree

android-core/src/main/java/com/mparticle/internal/KitFrameworkWrapper.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.mparticle.identity.IdentityApiRequest;
2727
import com.mparticle.identity.MParticleUser;
2828
import com.mparticle.internal.listeners.InternalListenerManager;
29+
import com.mparticle.rokt.PlacementOptions;
2930
import com.mparticle.rokt.RoktConfig;
3031
import com.mparticle.rokt.RoktEmbeddedView;
3132
import com.mparticle.rokt.RoktOptions;
@@ -685,6 +686,25 @@ public void execute(@NonNull String viewName,
685686
}
686687
}
687688

689+
@Override
690+
public void execute(@NonNull String identifier,
691+
@NonNull Map<String, String> attributes,
692+
@Nullable MpRoktEventCallback mpRoktEventCallback,
693+
@Nullable Map<String, WeakReference<RoktEmbeddedView>> embeddedViews,
694+
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
695+
@Nullable RoktConfig config,
696+
@Nullable PlacementOptions options) {
697+
if (mKitManager != null) {
698+
mKitManager.execute(identifier,
699+
attributes,
700+
mpRoktEventCallback,
701+
embeddedViews,
702+
fontTypefaces,
703+
config,
704+
options);
705+
}
706+
}
707+
688708
@Override
689709
public Flow<RoktEvent> events(@NonNull String identifier) {
690710
if (mKitManager != null) {
@@ -836,4 +856,4 @@ public void onKitApiCalled(String methodName, int kitId, Boolean used, Object...
836856
}
837857
};
838858
}
839-
}
859+
}

android-core/src/main/java/com/mparticle/internal/KitManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.mparticle.consent.ConsentState;
2323
import com.mparticle.identity.IdentityApiRequest;
2424
import com.mparticle.identity.MParticleUser;
25+
import com.mparticle.rokt.PlacementOptions;
2526
import com.mparticle.rokt.RoktConfig;
2627
import com.mparticle.rokt.RoktEmbeddedView;
2728
import com.mparticle.rokt.RoktOptions;
@@ -140,6 +141,14 @@ void execute(@NonNull String identifier,
140141
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
141142
@Nullable RoktConfig config);
142143

144+
void execute(@NonNull String identifier,
145+
@NonNull Map<String, String> attributes,
146+
@Nullable MpRoktEventCallback mpRoktEventCallback,
147+
@Nullable Map<String, WeakReference<RoktEmbeddedView>> embeddedViews,
148+
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
149+
@Nullable RoktConfig config,
150+
@Nullable PlacementOptions options);
151+
143152
Flow<RoktEvent> events(@NonNull String identifier);
144153

145154
void setWrapperSdkVersion(@NonNull WrapperSdkVersion wrapperSdkVersion);

android-core/src/main/kotlin/com/mparticle/Rokt.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.graphics.Typeface
44
import com.mparticle.internal.ConfigManager
55
import com.mparticle.internal.KitManager
66
import com.mparticle.internal.listeners.ApiClass
7+
import com.mparticle.rokt.PlacementOptions
78
import com.mparticle.rokt.RoktConfig
89
import com.mparticle.rokt.RoktEmbeddedView
910
import kotlinx.coroutines.flow.Flow
@@ -22,7 +23,8 @@ class Rokt internal constructor(private val mConfigManager: ConfigManager, priva
2223
config: RoktConfig? = null,
2324
) {
2425
if (mConfigManager.isEnabled) {
25-
mKitManager.execute(identifier, HashMap(attributes), callbacks, embeddedViews, fontTypefaces, config)
26+
val placementOptions = PlacementOptions(integrationStartTimestamp = System.currentTimeMillis())
27+
mKitManager.execute(identifier, HashMap(attributes), callbacks, embeddedViews, fontTypefaces, config, placementOptions)
2628
}
2729
}
2830

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.mparticle.rokt
2+
3+
data class PlacementOptions(var integrationStartTimestamp: Long)

android-core/src/test/kotlin/com/mparticle/RoktTest.kt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.os.Looper
55
import android.os.SystemClock
66
import com.mparticle.internal.ConfigManager
77
import com.mparticle.internal.KitManager
8+
import com.mparticle.rokt.PlacementOptions
89
import com.mparticle.rokt.RoktConfig
910
import com.mparticle.rokt.RoktEmbeddedView
1011
import kotlinx.coroutines.flow.Flow
@@ -14,7 +15,10 @@ import kotlinx.coroutines.test.runTest
1415
import org.junit.Before
1516
import org.junit.Test
1617
import org.junit.runner.RunWith
18+
import org.mockito.ArgumentCaptor
1719
import org.mockito.ArgumentMatchers.any
20+
import org.mockito.ArgumentMatchers.eq
21+
import org.mockito.ArgumentMatchers.isNull
1822
import org.mockito.Mock
1923
import org.mockito.Mockito.never
2024
import org.mockito.Mockito.verify
@@ -81,7 +85,7 @@ class RoktTest {
8185
config = config,
8286
)
8387

84-
verify(kitManager)?.execute("testView", attributes, callbacks, placeholders, fonts, config)
88+
verify(kitManager)?.execute(eq("testView"), eq(attributes), eq(callbacks), eq(placeholders), eq(fonts), eq(config), any())
8589
}
8690

8791
@Test
@@ -93,7 +97,7 @@ class RoktTest {
9397

9498
rokt.selectPlacements(attributes = attributes, identifier = "basicView")
9599

96-
verify(kitManager).execute("basicView", attributes, null, null, null, null)
100+
verify(kitManager).execute(eq("basicView"), eq(attributes), isNull(), isNull(), isNull(), isNull(), any())
97101
}
98102

99103
@Test
@@ -105,7 +109,7 @@ class RoktTest {
105109
attributes = HashMap(),
106110
)
107111

108-
verify(kitManager, never()).execute(any(), any(), any(), any(), any(), any())
112+
verify(kitManager, never()).execute(any(), any(), any(), any(), any(), any(), any())
109113
}
110114

111115
@Test
@@ -169,4 +173,30 @@ class RoktTest {
169173
assertTrue(elements.isEmpty())
170174
}
171175
}
176+
177+
@Test
178+
fun testSelectPlacements_withOptions_whenEnabled() {
179+
`when`(configManager.isEnabled).thenReturn(true)
180+
val currentTimeMillis = System.currentTimeMillis()
181+
182+
val attributes = mutableMapOf<String, String>()
183+
184+
rokt.selectPlacements(
185+
identifier = "testView",
186+
attributes = attributes,
187+
)
188+
189+
// Verify call is forwarded
190+
val optionsCaptor = ArgumentCaptor.forClass(PlacementOptions::class.java)
191+
verify(kitManager).execute(
192+
eq("testView"),
193+
eq(HashMap(attributes)),
194+
isNull(),
195+
isNull(),
196+
isNull(),
197+
isNull(),
198+
optionsCaptor.capture(),
199+
)
200+
assertTrue(optionsCaptor.value.integrationStartTimestamp >= currentTimeMillis)
201+
}
172202
}

android-kit-base/src/main/java/com/mparticle/kits/KitIntegration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.mparticle.commerce.CommerceEvent;
2222
import com.mparticle.consent.ConsentState;
2323
import com.mparticle.identity.MParticleUser;
24+
import com.mparticle.rokt.PlacementOptions;
2425
import com.mparticle.rokt.RoktConfig;
2526
import com.mparticle.rokt.RoktEmbeddedView;
2627

@@ -626,6 +627,15 @@ void execute(@NonNull String viewName,
626627
@Nullable FilteredMParticleUser user,
627628
@Nullable RoktConfig config);
628629

630+
void execute(@NonNull String viewName,
631+
@NonNull Map<String, String> attributes,
632+
@Nullable MpRoktEventCallback mpRoktEventCallback,
633+
@Nullable Map<String, WeakReference<RoktEmbeddedView>> placeHolders,
634+
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
635+
@Nullable FilteredMParticleUser user,
636+
@Nullable RoktConfig config,
637+
@Nullable PlacementOptions options);
638+
629639
Flow<RoktEvent> events(@NonNull String identifier);
630640

631641
void enrichAttributes(

android-kit-base/src/main/java/com/mparticle/kits/KitManagerImpl.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.mparticle.internal.MPUtility;
4646
import com.mparticle.internal.ReportingManager;
4747
import com.mparticle.kits.mappings.CustomMapping;
48+
import com.mparticle.rokt.PlacementOptions;
4849
import com.mparticle.rokt.RoktConfig;
4950
import com.mparticle.rokt.RoktEmbeddedView;
5051
import com.mparticle.rokt.RoktOptions;
@@ -1353,6 +1354,17 @@ public void execute(@NonNull String viewName,
13531354
@Nullable Map<String, WeakReference<RoktEmbeddedView>> placeHolders,
13541355
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
13551356
@Nullable RoktConfig config) {
1357+
execute(viewName, attributes, mpRoktEventCallback, placeHolders, fontTypefaces, config, null);
1358+
}
1359+
1360+
@Override
1361+
public void execute(@NonNull String viewName,
1362+
@NonNull Map<String, String> attributes,
1363+
@Nullable MpRoktEventCallback mpRoktEventCallback,
1364+
@Nullable Map<String, WeakReference<RoktEmbeddedView>> placeHolders,
1365+
@Nullable Map<String, WeakReference<Typeface>> fontTypefaces,
1366+
@Nullable RoktConfig config,
1367+
@Nullable PlacementOptions options) {
13561368
for (KitIntegration provider : providers.values()) {
13571369
try {
13581370
if (provider instanceof KitIntegration.RoktListener && !provider.isDisabled()) {
@@ -1374,7 +1386,8 @@ public void execute(@NonNull String viewName,
13741386
placeHolders,
13751387
fontTypefaces,
13761388
FilteredMParticleUser.getInstance(user.getId(), provider),
1377-
config);
1389+
config,
1390+
options);
13781391
});
13791392
}
13801393
} catch (Exception e) {

android-kit-base/src/test/kotlin/com/mparticle/kits/KitManagerImplTest.kt

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.mparticle.mock.MockContext
2929
import com.mparticle.mock.MockKitConfiguration
3030
import com.mparticle.mock.MockKitManagerImpl
3131
import com.mparticle.mock.MockMParticle
32+
import com.mparticle.rokt.PlacementOptions
3233
import com.mparticle.rokt.RoktConfig
3334
import com.mparticle.rokt.RoktEmbeddedView
3435
import com.mparticle.testutils.TestingUtils
@@ -43,10 +44,12 @@ import org.json.JSONException
4344
import org.json.JSONObject
4445
import org.junit.Assert
4546
import org.junit.Assert.assertNull
47+
import org.junit.Assert.assertSame
4648
import org.junit.Assert.assertTrue
4749
import org.junit.Before
4850
import org.junit.Test
4951
import org.junit.runner.RunWith
52+
import org.mockito.ArgumentCaptor
5053
import org.mockito.ArgumentMatchers.any
5154
import org.mockito.Mockito
5255
import org.mockito.Mockito.mock
@@ -1848,6 +1851,77 @@ class KitManagerImplTest {
18481851
Assert.assertEquals("false", attributes["sandbox"])
18491852
}
18501853

1854+
@Test
1855+
fun testRokt_execute_with_PlacementOptions() {
1856+
val mockUser = mock(MParticleUser::class.java)
1857+
`when`(mockIdentity!!.currentUser).thenReturn(mockUser)
1858+
1859+
val manager: KitManagerImpl = MockKitManagerImpl()
1860+
val roktListener =
1861+
mock(
1862+
KitIntegration::class.java,
1863+
withSettings().extraInterfaces(KitIntegration.RoktListener::class.java),
1864+
)
1865+
`when`(roktListener.isDisabled).thenReturn(false)
1866+
manager.providers =
1867+
ConcurrentHashMap<Int, KitIntegration>().apply {
1868+
put(1, roktListener)
1869+
}
1870+
1871+
val attributes = hashMapOf<String, String>()
1872+
val placementOptions = PlacementOptions(integrationStartTimestamp = 123L)
1873+
1874+
manager.execute("Test", attributes, null, null, null, null, placementOptions)
1875+
1876+
val optionsCaptor = ArgumentCaptor.forClass(PlacementOptions::class.java)
1877+
verify(roktListener as KitIntegration.RoktListener).execute(
1878+
any(),
1879+
any(),
1880+
any(),
1881+
any(),
1882+
any(),
1883+
any(),
1884+
any(),
1885+
optionsCaptor.capture(),
1886+
)
1887+
assertSame(placementOptions, optionsCaptor.value)
1888+
}
1889+
1890+
@Test
1891+
fun testRokt_execute_without_PlacementOptions() {
1892+
val mockUser = mock(MParticleUser::class.java)
1893+
`when`(mockIdentity!!.currentUser).thenReturn(mockUser)
1894+
1895+
val manager: KitManagerImpl = MockKitManagerImpl()
1896+
val roktListener =
1897+
mock(
1898+
KitIntegration::class.java,
1899+
withSettings().extraInterfaces(KitIntegration.RoktListener::class.java),
1900+
)
1901+
`when`(roktListener.isDisabled).thenReturn(false)
1902+
manager.providers =
1903+
ConcurrentHashMap<Int, KitIntegration>().apply {
1904+
put(1, roktListener)
1905+
}
1906+
1907+
val attributes = hashMapOf<String, String>()
1908+
1909+
manager.execute("Test", attributes, null, null, null, null)
1910+
1911+
val optionsCaptor = ArgumentCaptor.forClass(PlacementOptions::class.java)
1912+
verify(roktListener as KitIntegration.RoktListener).execute(
1913+
any(),
1914+
any(),
1915+
any(),
1916+
any(),
1917+
any(),
1918+
any(),
1919+
any(),
1920+
optionsCaptor.capture(),
1921+
)
1922+
assertNull(optionsCaptor.value)
1923+
}
1924+
18511925
@Test
18521926
fun testRokt_SandboxMode_When_Environment_IS_Development() {
18531927
val sideloadedKit = mock(MPSideloadedKit::class.java)
@@ -2265,6 +2339,19 @@ class KitManagerImplTest {
22652339
Logger.info("Executed with $attributes")
22662340
}
22672341

2342+
override fun execute(
2343+
viewName: String,
2344+
attributes: MutableMap<String, String>,
2345+
mpRoktEventCallback: MpRoktEventCallback?,
2346+
placeHolders: MutableMap<String, WeakReference<RoktEmbeddedView>>?,
2347+
fontTypefaces: MutableMap<String, WeakReference<Typeface>>?,
2348+
user: FilteredMParticleUser?,
2349+
config: RoktConfig?,
2350+
options: PlacementOptions?,
2351+
) {
2352+
Logger.info("Executed with $attributes and options $options")
2353+
}
2354+
22682355
override fun events(identifier: String): Flow<RoktEvent> {
22692356
Logger.info("events called with identfier: $identifier")
22702357
return flowOf()

0 commit comments

Comments
 (0)