Skip to content

Commit cbccd13

Browse files
feat: Add sandbox mode to attributes (#559)
1 parent 37298e2 commit cbccd13

3 files changed

Lines changed: 227 additions & 13 deletions

File tree

android-core/src/main/kotlin/com/mparticle/internal/Constants.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ object Constants {
463463

464464
//batch was mutated
465465
const val MODIFIED_BATCH: String = "mb"
466+
467+
//Sandbox mode for Rokt
468+
const val SANDBOX_MODE_ROKT: String = "sandbox"
466469
}
467470
}
468471

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

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.mparticle.identity.MParticleUser;
3939
import com.mparticle.identity.TaskFailureListener;
4040
import com.mparticle.identity.TaskSuccessListener;
41+
import com.mparticle.internal.Constants;
4142
import com.mparticle.internal.CoreCallbacks;
4243
import com.mparticle.internal.KitManager;
4344
import com.mparticle.internal.KitsLoadedCallback;
@@ -60,6 +61,7 @@
6061
import java.util.LinkedList;
6162
import java.util.List;
6263
import java.util.Map;
64+
import java.util.Objects;
6365
import java.util.Set;
6466
import java.util.TreeMap;
6567
import java.util.concurrent.ConcurrentHashMap;
@@ -1340,9 +1342,13 @@ public void execute(String viewName,
13401342
for (KitIntegration provider : providers.values()) {
13411343
try {
13421344
if (provider instanceof KitIntegration.RoktListener && !provider.isDisabled()) {
1345+
if (attributes == null) {
1346+
attributes = new HashMap<>();
1347+
}
13431348
MParticle instance = MParticle.getInstance();
13441349
MParticleUser user = instance.Identity().getCurrentUser();
1345-
String email = attributes != null ? attributes.get("email") : null;
1350+
String email = attributes.get("email");
1351+
Map<String, String> finalAttributes = attributes;
13461352
confirmEmail(email,user,instance.Identity(), () -> {
13471353
JSONArray jsonArray = new JSONArray();
13481354

@@ -1359,18 +1365,27 @@ public void execute(String viewName,
13591365
if (obj == null) continue;
13601366
String mapFrom = obj.optString("map");
13611367
String mapTo = obj.optString("value");
1362-
if (attributes.containsKey(mapFrom)) {
1363-
String value = attributes.remove(mapFrom);
1364-
attributes.put(mapTo, value);
1368+
if (finalAttributes.containsKey(mapFrom)) {
1369+
String value = finalAttributes.remove(mapFrom);
1370+
finalAttributes.put(mapTo, value);
13651371
}
13661372
}
13671373
Map<String, Object> objectAttributes = new HashMap<>();
1368-
for (Map.Entry<String, String> entry : attributes.entrySet()) {
1369-
objectAttributes.put(entry.getKey(), entry.getValue());
1374+
for (Map.Entry<String, String> entry : finalAttributes.entrySet()) {
1375+
if(!entry.getKey().equals(Constants.MessageKey.SANDBOX_MODE_ROKT)) {
1376+
objectAttributes.put(entry.getKey(), entry.getValue());
1377+
}
1378+
}
1379+
if (user != null) {
1380+
user.setUserAttributes(objectAttributes);
13701381
}
1371-
user.setUserAttributes(objectAttributes);
1382+
1383+
if (!finalAttributes.containsKey(Constants.MessageKey.SANDBOX_MODE_ROKT)) {
1384+
finalAttributes.put(Constants.MessageKey.SANDBOX_MODE_ROKT, String.valueOf(Objects.toString(MPUtility.isDevEnv(), "false"))); // Default value is "false" if null
1385+
}
1386+
13721387
((KitIntegration.RoktListener) provider).execute(viewName,
1373-
attributes,
1388+
finalAttributes,
13741389
mpRoktEventCallback,
13751390
placeHolders,
13761391
fontTypefaces,

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

Lines changed: 201 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.mparticle.identity.IdentityApi
1717
import com.mparticle.identity.IdentityApiResult
1818
import com.mparticle.identity.MParticleUser
1919
import com.mparticle.internal.CoreCallbacks
20+
import com.mparticle.internal.MPUtility
2021
import com.mparticle.internal.SideloadedKit
2122
import com.mparticle.kits.KitIntegration.AttributeListener
2223
import com.mparticle.mock.MockContext
@@ -48,7 +49,7 @@ import java.util.LinkedList
4849
import java.util.concurrent.ConcurrentHashMap
4950

5051
@RunWith(PowerMockRunner::class)
51-
@PrepareForTest(Looper::class, SystemClock::class)
52+
@PrepareForTest(Looper::class, SystemClock::class, MPUtility::class)
5253
class KitManagerImplTest {
5354
var mparticle: MParticle? = null
5455
var mockIdentity: IdentityApi? = null
@@ -843,13 +844,15 @@ class KitManagerImplTest {
843844
Pair("customerId", "55555"),
844845
Pair("country", "US")
845846
)
847+
846848
manager.execute("Test", attributes, null, null, null)
847-
Assert.assertEquals(5, attributes.size)
849+
Assert.assertEquals(6, attributes.size)
848850
Assert.assertEquals("(123) 456-9898", attributes["no"])
849851
Assert.assertEquals("55555", attributes["minorcatid"])
850852
Assert.assertEquals("Test1", attributes["lastname"])
851853
Assert.assertEquals("Test", attributes["test"])
852854
Assert.assertEquals("US", attributes["country"])
855+
Assert.assertEquals("false", attributes["sandbox"])
853856
}
854857

855858
@Test
@@ -906,13 +909,16 @@ class KitManagerImplTest {
906909
Pair("postal", "5-45555"),
907910
Pair("country", "US")
908911
)
912+
909913
manager.execute("Test", attributes, null, null, null)
910-
Assert.assertEquals(5, attributes.size)
914+
Assert.assertEquals(6, attributes.size)
915+
911916
Assert.assertEquals("(123) 456-9898", attributes["call"])
912917
Assert.assertEquals("5-45555", attributes["postal"])
913918
Assert.assertEquals("Test1", attributes["lastname"])
914919
Assert.assertEquals("Test", attributes["test"])
915920
Assert.assertEquals("US", attributes["country"])
921+
Assert.assertEquals("false", attributes["sandbox"])
916922
}
917923

918924
@Test
@@ -969,13 +975,15 @@ class KitManagerImplTest {
969975
Pair("minorcatid", "5-45555"),
970976
Pair("country", "US")
971977
)
978+
972979
manager.execute("Test", attributes, null, null, null)
973-
Assert.assertEquals(5, attributes.size)
980+
Assert.assertEquals(6, attributes.size)
974981
Assert.assertEquals("(123) 456-9898", attributes["no"])
975982
Assert.assertEquals("5-45555", attributes["minorcatid"])
976983
Assert.assertEquals("Test1", attributes["lastname"])
977984
Assert.assertEquals("Test", attributes["test"])
978985
Assert.assertEquals("US", attributes["country"])
986+
Assert.assertEquals("false", attributes["sandbox"])
979987
}
980988

981989
@Test
@@ -1031,13 +1039,15 @@ class KitManagerImplTest {
10311039
Pair("customerId", "55555"),
10321040
Pair("country", "US")
10331041
)
1042+
10341043
manager.execute("Test", attributes, null, null, null)
1035-
Assert.assertEquals(5, attributes.size)
1044+
Assert.assertEquals(6, attributes.size)
10361045
Assert.assertEquals("(123) 456-9898", attributes["number"])
10371046
Assert.assertEquals("55555", attributes["customerId"])
10381047
Assert.assertEquals("Test1", attributes["lastname"])
10391048
Assert.assertEquals("Test", attributes["test"])
10401049
Assert.assertEquals("US", attributes["country"])
1050+
Assert.assertEquals("false", attributes["sandbox"])
10411051
}
10421052

10431053
@Test
@@ -1228,6 +1238,192 @@ class KitManagerImplTest {
12281238
Mockito.verify(runnable).run()
12291239
}
12301240

1241+
@Test
1242+
fun testRokt_SandboxMode_When_Default_Environment() {
1243+
val sideloadedKit = Mockito.mock(MPSideloadedKit::class.java)
1244+
val kitId = 6000000
1245+
1246+
val configJSONObj = JSONObject().apply {
1247+
put("id", kitId)
1248+
}
1249+
val mockedKitConfig = KitConfiguration.createKitConfiguration(configJSONObj)
1250+
Mockito.`when`(sideloadedKit.configuration).thenReturn(mockedKitConfig)
1251+
1252+
val settingsMap = hashMapOf(
1253+
"placementAttributesMapping" to """
1254+
[]
1255+
""".trimIndent()
1256+
)
1257+
val field = KitConfiguration::class.java.getDeclaredField("settings")
1258+
field.isAccessible = true
1259+
field.set(mockedKitConfig, settingsMap)
1260+
1261+
val mockedProvider = mockProvider(mockedKitConfig)
1262+
1263+
val options = MParticleOptions.builder(MockContext())
1264+
.sideloadedKits(mutableListOf(sideloadedKit) as List<SideloadedKit>).build()
1265+
val manager: KitManagerImpl = MockKitManagerImpl(options)
1266+
val factory = Mockito.mock(KitIntegrationFactory::class.java)
1267+
manager.setKitFactory(factory)
1268+
1269+
Mockito.`when`(factory.isSupported(Mockito.anyInt())).thenReturn(true)
1270+
val supportedKit = mutableSetOf(kitId)
1271+
Mockito.`when`(manager.supportedKits).thenReturn(supportedKit)
1272+
Mockito.`when`(sideloadedKit.isDisabled).thenReturn(false)
1273+
Mockito.`when`(
1274+
factory.createInstance(
1275+
Mockito.any(
1276+
KitManagerImpl::class.java
1277+
),
1278+
Mockito.any(KitConfiguration::class.java)
1279+
)
1280+
).thenReturn(sideloadedKit)
1281+
manager.providers = ConcurrentHashMap<Int, KitIntegration>().apply {
1282+
put(42, mockedProvider)
1283+
}
1284+
1285+
val attributes = hashMapOf(
1286+
Pair("test", "Test"),
1287+
Pair("lastname", "Test1"),
1288+
Pair("number", "(123) 456-9898"),
1289+
Pair("customerId", "55555"),
1290+
Pair("country", "US")
1291+
)
1292+
manager.execute("Test", attributes, null, null, null)
1293+
Assert.assertEquals(6, attributes.size)
1294+
Assert.assertEquals("(123) 456-9898", attributes["number"])
1295+
Assert.assertEquals("55555", attributes["customerId"])
1296+
Assert.assertEquals("Test1", attributes["lastname"])
1297+
Assert.assertEquals("Test", attributes["test"])
1298+
Assert.assertEquals("US", attributes["country"])
1299+
Assert.assertEquals("false", attributes["sandbox"])
1300+
}
1301+
1302+
@Test
1303+
fun testRokt_SandboxMode_When_Environment_IS_Development() {
1304+
val sideloadedKit = Mockito.mock(MPSideloadedKit::class.java)
1305+
val kitId = 6000000
1306+
1307+
val configJSONObj = JSONObject().apply {
1308+
put("id", kitId)
1309+
}
1310+
val mockedKitConfig = KitConfiguration.createKitConfiguration(configJSONObj)
1311+
1312+
val settingsMap = hashMapOf(
1313+
"placementAttributesMapping" to """
1314+
[]
1315+
""".trimIndent()
1316+
)
1317+
val field = KitConfiguration::class.java.getDeclaredField("settings")
1318+
field.isAccessible = true
1319+
field.set(mockedKitConfig, settingsMap)
1320+
1321+
val mockedProvider = mockProvider(mockedKitConfig)
1322+
1323+
val options = MParticleOptions.builder(MockContext())
1324+
.sideloadedKits(mutableListOf(sideloadedKit) as List<SideloadedKit>).build()
1325+
val manager: KitManagerImpl = MockKitManagerImpl(options)
1326+
val factory = Mockito.mock(KitIntegrationFactory::class.java)
1327+
manager.setKitFactory(factory)
1328+
1329+
Mockito.`when`(factory.isSupported(Mockito.anyInt())).thenReturn(true)
1330+
PowerMockito.mockStatic(MPUtility::class.java)
1331+
Mockito.`when`(MPUtility.isDevEnv()).thenReturn(true)
1332+
val supportedKit = mutableSetOf(kitId)
1333+
Mockito.`when`(manager.supportedKits).thenReturn(supportedKit)
1334+
Mockito.`when`(sideloadedKit.isDisabled).thenReturn(false)
1335+
Mockito.`when`(
1336+
factory.createInstance(
1337+
Mockito.any(
1338+
KitManagerImpl::class.java
1339+
),
1340+
Mockito.any(KitConfiguration::class.java)
1341+
)
1342+
).thenReturn(sideloadedKit)
1343+
manager.providers = ConcurrentHashMap<Int, KitIntegration>().apply {
1344+
put(42, mockedProvider)
1345+
}
1346+
1347+
val attributes = hashMapOf(
1348+
Pair("test", "Test"),
1349+
Pair("lastname", "Test1"),
1350+
Pair("number", "(123) 456-9898"),
1351+
Pair("customerId", "55555"),
1352+
Pair("country", "US")
1353+
)
1354+
manager.execute("Test", attributes, null, null, null)
1355+
Assert.assertEquals(6, attributes.size)
1356+
Assert.assertEquals("(123) 456-9898", attributes["number"])
1357+
Assert.assertEquals("55555", attributes["customerId"])
1358+
Assert.assertEquals("Test1", attributes["lastname"])
1359+
Assert.assertEquals("Test", attributes["test"])
1360+
Assert.assertEquals("US", attributes["country"])
1361+
Assert.assertEquals("true", attributes["sandbox"])
1362+
}
1363+
1364+
@Test
1365+
fun testRokt_SandboxMode_When_SandBox_is_Pass_In_Attributes_And_Environment_Is_DEV() {
1366+
val sideloadedKit = Mockito.mock(MPSideloadedKit::class.java)
1367+
val kitId = 6000000
1368+
1369+
val configJSONObj = JSONObject().apply {
1370+
put("id", kitId)
1371+
}
1372+
val mockedKitConfig = KitConfiguration.createKitConfiguration(configJSONObj)
1373+
1374+
val settingsMap = hashMapOf(
1375+
"placementAttributesMapping" to """
1376+
[]
1377+
""".trimIndent()
1378+
)
1379+
val field = KitConfiguration::class.java.getDeclaredField("settings")
1380+
field.isAccessible = true
1381+
field.set(mockedKitConfig, settingsMap)
1382+
1383+
val mockedProvider = mockProvider(mockedKitConfig)
1384+
1385+
val options = MParticleOptions.builder(MockContext())
1386+
.sideloadedKits(mutableListOf(sideloadedKit) as List<SideloadedKit>).build()
1387+
val manager: KitManagerImpl = MockKitManagerImpl(options)
1388+
val factory = Mockito.mock(KitIntegrationFactory::class.java)
1389+
manager.setKitFactory(factory)
1390+
1391+
Mockito.`when`(factory.isSupported(Mockito.anyInt())).thenReturn(true)
1392+
PowerMockito.mockStatic(MPUtility::class.java)
1393+
Mockito.`when`(MPUtility.isDevEnv()).thenReturn(true)
1394+
val supportedKit = mutableSetOf(kitId)
1395+
Mockito.`when`(manager.supportedKits).thenReturn(supportedKit)
1396+
Mockito.`when`(sideloadedKit.isDisabled).thenReturn(false)
1397+
Mockito.`when`(
1398+
factory.createInstance(
1399+
Mockito.any(
1400+
KitManagerImpl::class.java
1401+
),
1402+
Mockito.any(KitConfiguration::class.java)
1403+
)
1404+
).thenReturn(sideloadedKit)
1405+
manager.providers = ConcurrentHashMap<Int, KitIntegration>().apply {
1406+
put(42, mockedProvider)
1407+
}
1408+
1409+
val attributes = hashMapOf(
1410+
Pair("test", "Test"),
1411+
Pair("lastname", "Test1"),
1412+
Pair("number", "(123) 456-9898"),
1413+
Pair("customerId", "55555"),
1414+
Pair("country", "US"),
1415+
Pair("sandbox", "false")
1416+
)
1417+
manager.execute("Test", attributes, null, null, null)
1418+
Assert.assertEquals(6, attributes.size)
1419+
Assert.assertEquals("(123) 456-9898", attributes["number"])
1420+
Assert.assertEquals("55555", attributes["customerId"])
1421+
Assert.assertEquals("Test1", attributes["lastname"])
1422+
Assert.assertEquals("Test", attributes["test"])
1423+
Assert.assertEquals("US", attributes["country"])
1424+
Assert.assertEquals("false", attributes["sandbox"])
1425+
}
1426+
12311427
internal inner class mockProvider(val config: KitConfiguration) : KitIntegration(), KitIntegration.RoktListener {
12321428
override fun isDisabled(): Boolean = false
12331429
override fun getName(): String = "FakeProvider"

0 commit comments

Comments
 (0)