11package ly .count .android .sdk ;
22
33import androidx .test .ext .junit .runners .AndroidJUnit4 ;
4+ import java .util .Arrays ;
45import java .util .HashMap ;
6+ import java .util .List ;
57import java .util .Map ;
68import java .util .concurrent .ConcurrentHashMap ;
79import ly .count .android .sdk .messaging .ModulePush ;
1416import org .junit .Test ;
1517import org .junit .runner .RunWith ;
1618import org .mockito .ArgumentCaptor ;
19+ import org .mockito .Mockito ;
20+ import org .mockito .internal .util .collections .Sets ;
1721
1822import static org .mockito .ArgumentMatchers .any ;
1923import static org .mockito .ArgumentMatchers .eq ;
@@ -336,7 +340,7 @@ public void recordEventInternalProcessedTest() {
336340
337341 segm1 .put ("4" , 45.4f );
338342 segm1 .put ("41" , new Object ());
339- segm1 .put ("42" , new int [] { 1 , 2 });
343+ segm1 .put ("42" , new int [][] { { 1 , 2 , 3 }, { 4 , 5 , 6 } });
340344 segm1 .put ("asd" , "123" );
341345 segm1 .put ("1" , 1234 );
342346 segm1 .put ("2" , 1234.55d );
@@ -466,6 +470,8 @@ public void internalLimits_recordEvent_segmentation() throws JSONException {
466470
467471 @ Test
468472 public void recordEvent_validateFromRQ () throws JSONException {
473+ int [] arr = new int [] { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
474+ List <String > list = Arrays .asList ("1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" );
469475 CountlyConfig countlyConfig = TestUtils .createBaseConfig ();
470476 countlyConfig .setEventQueueSizeToSend (1 );
471477 Countly countly = new Countly ().init (countlyConfig );
@@ -478,7 +484,8 @@ public void recordEvent_validateFromRQ() throws JSONException {
478484 "float" , 1.5f ,
479485 "long" , Long .MAX_VALUE ,
480486 "object" , new Object (),
481- "array" , new int [] { 1 , 2 , 3 },
487+ "array" , arr ,
488+ "list" , list ,
482489 "null" , null
483490 );
484491
@@ -490,7 +497,9 @@ public void recordEvent_validateFromRQ() throws JSONException {
490497 "string" , "string" ,
491498 "boolean" , true ,
492499 "float" , 1.5 ,
493- "long" , Long .MAX_VALUE
500+ "long" , Long .MAX_VALUE ,
501+ "array" , new JSONArray (arr ),
502+ "list" , new JSONArray (list )
494503 );
495504
496505 validateEventInRQ ("key" , expectedSegmentation , 1 , 1.0d , 1.0d , 0 );
@@ -571,6 +580,197 @@ public void internalLimits_recordEventInternal_maxValueSizeKeyLength() throws JS
571580 validateEventInRQ ("rn" , TestUtils .map ("a" , 1 , "bb" , "dd" ), 1 , 1.1d , 1.1d , 0 );
572581 }
573582
583+ /**
584+ * "recordEvent" with Array segmentations
585+ * Validate that all primitive types arrays are successfully recorded
586+ * And validate that Object arrays are not recorded
587+ * But Generic type of Object array which its values are only primitive types are recorded
588+ *
589+ * @throws JSONException if the JSON is not valid
590+ */
591+ @ Test
592+ public void recordEvent_validateSupportedArrays () throws JSONException {
593+ int [] arr = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
594+ boolean [] arrB = { true , false , true , false , true , false , true , false , true , false };
595+ String [] arrS = { "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" };
596+ long [] arrL = { Long .MAX_VALUE , Long .MIN_VALUE };
597+ double [] arrD = { Double .MAX_VALUE , Double .MIN_VALUE };
598+ Long [] arrLO = { Long .MAX_VALUE , Long .MIN_VALUE };
599+ Double [] arrDO = { Double .MAX_VALUE , Double .MIN_VALUE };
600+ Boolean [] arrBO = { Boolean .TRUE , Boolean .FALSE };
601+ Integer [] arrIO = { Integer .MAX_VALUE , Integer .MIN_VALUE };
602+ Object [] arrObj = { "1" , 1 , 1.1d , true , 1.1f , Long .MAX_VALUE };
603+ Object [] arrObjStr = { "1" , "1" , "1.1d" , "true" , "1.1f" , "Long.MAX_VALUE" };
604+
605+ CountlyConfig countlyConfig = TestUtils .createBaseConfig ();
606+ countlyConfig .setEventQueueSizeToSend (1 );
607+ Countly countly = new Countly ().init (countlyConfig );
608+
609+ Map <String , Object > segmentation = TestUtils .map (
610+ "arr" , arr ,
611+ "arrB" , arrB ,
612+ "arrS" , arrS ,
613+ "arrL" , arrL ,
614+ "arrD" , arrD ,
615+ "arrLO" , arrLO ,
616+ "arrDO" , arrDO ,
617+ "arrBO" , arrBO ,
618+ "arrIO" , arrIO ,
619+ "arrObj" , arrObj ,
620+ "arrObjStr" , arrObjStr
621+ );
622+
623+ countly .events ().recordEvent ("key" , segmentation , 1 , 1.0d , 1.0d );
624+
625+ Map <String , Object > expectedSegmentation = TestUtils .map (
626+ "arr" , new JSONArray (arr ),
627+ "arrB" , new JSONArray (arrB ),
628+ "arrS" , new JSONArray (arrS ),
629+ "arrL" , new JSONArray (arrL ),
630+ "arrD" , new JSONArray (arrD ),
631+ "arrLO" , new JSONArray (arrLO ),
632+ "arrDO" , new JSONArray (arrDO ),
633+ "arrBO" , new JSONArray (arrBO ),
634+ "arrIO" , new JSONArray (arrIO )
635+ );
636+
637+ validateEventInRQ ("key" , expectedSegmentation , 1 , 1.0d , 1.0d , 0 );
638+ }
639+
640+ /**
641+ * "recordEvent" with List segmentations
642+ * Validate that all primitive types Lists are successfully recorded
643+ * And validate that List of Objects is not recorded
644+ * But Generic type of Object list which its values are only primitive types are recorded
645+ *
646+ * @throws JSONException if the JSON is not valid
647+ */
648+ @ Test
649+ public void recordEvent_validateSupportedLists () throws JSONException {
650+ List <Integer > arr = Arrays .asList (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 );
651+ List <Boolean > arrB = Arrays .asList (true , false , true , false , true , false , true , false , true , false );
652+ List <String > arrS = Arrays .asList ("1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" );
653+ List <Long > arrLO = Arrays .asList (Long .MAX_VALUE , Long .MIN_VALUE );
654+ List <Double > arrDO = Arrays .asList (Double .MAX_VALUE , Double .MIN_VALUE );
655+ List <Boolean > arrBO = Arrays .asList (Boolean .TRUE , Boolean .FALSE );
656+ List <Integer > arrIO = Arrays .asList (Integer .MAX_VALUE , Integer .MIN_VALUE );
657+ List <Object > arrObj = Arrays .asList ("1" , 1 , 1.1d , true , Long .MAX_VALUE );
658+ List <Object > arrObjStr = Arrays .asList ("1" , "1" , "1.1d" , "true" , "Long.MAX_VALUE" );
659+
660+ CountlyConfig countlyConfig = TestUtils .createBaseConfig ();
661+ countlyConfig .setEventQueueSizeToSend (1 );
662+ Countly countly = new Countly ().init (countlyConfig );
663+
664+ // Create segmentation using maps with lists
665+ Map <String , Object > segmentation = TestUtils .map (
666+ "arr" , arr ,
667+ "arrB" , arrB ,
668+ "arrS" , arrS ,
669+ "arrLO" , arrLO ,
670+ "arrDO" , arrDO ,
671+ "arrBO" , arrBO ,
672+ "arrIO" , arrIO ,
673+ "arrObj" , arrObj ,
674+ "arrObjStr" , arrObjStr
675+ );
676+
677+ // Record event with the created segmentation
678+ countly .events ().recordEvent ("key" , segmentation , 1 , 1.0d , 1.0d );
679+
680+ // Prepare expected segmentation with JSONArrays
681+ Map <String , Object > expectedSegmentation = TestUtils .map (
682+ "arr" , new JSONArray (arr ),
683+ "arrB" , new JSONArray (arrB ),
684+ "arrS" , new JSONArray (arrS ),
685+ "arrLO" , new JSONArray (arrLO ),
686+ "arrDO" , new JSONArray (arrDO ),
687+ "arrBO" , new JSONArray (arrBO ),
688+ "arrIO" , new JSONArray (arrIO ),
689+ "arrObjStr" , new JSONArray (arrObjStr )
690+ );
691+
692+ // Validate the recorded event with expected segmentation
693+ validateEventInRQ ("key" , expectedSegmentation , 1 , 1.0d , 1.0d , 0 );
694+ }
695+
696+ /**
697+ * "recordEvent" with JSONArray segmentations
698+ * Validate that all primitive types JSONArrays are successfully recorded
699+ * And validate and JSONArray of Objects is not recorded
700+ *
701+ * @throws JSONException if the JSON is not valid
702+ */
703+ @ Test
704+ public void recordEvent_validateSupportedJSONArrays () throws JSONException {
705+ JSONArray arr = new JSONArray (Arrays .asList (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ));
706+ JSONArray arrB = new JSONArray (Arrays .asList (true , false , true , false , true , false , true , false , true , false ));
707+ JSONArray arrS = new JSONArray (Arrays .asList ("1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" ));
708+ JSONArray arrL = new JSONArray (Arrays .asList (Long .MAX_VALUE , Long .MIN_VALUE ));
709+ JSONArray arrD = new JSONArray (Arrays .asList (Double .MAX_VALUE , Double .MIN_VALUE ));
710+ JSONArray arrBO = new JSONArray (Arrays .asList (Boolean .TRUE , Boolean .FALSE ));
711+ JSONArray arrIO = new JSONArray (Arrays .asList (Integer .MAX_VALUE , Integer .MIN_VALUE ));
712+ JSONArray arrObj = new JSONArray (Arrays .asList ("1" , 1 , 1.1d , true , Long .MAX_VALUE ));
713+
714+ CountlyConfig countlyConfig = TestUtils .createBaseConfig ();
715+ countlyConfig .setEventQueueSizeToSend (1 );
716+ Countly countly = new Countly ().init (countlyConfig );
717+
718+ // Create segmentation using maps with lists
719+ Map <String , Object > segmentation = TestUtils .map (
720+ "arr" , arr ,
721+ "arrB" , arrB ,
722+ "arrS" , arrS ,
723+ "arrL" , arrL ,
724+ "arrD" , arrD ,
725+ "arrBO" , arrBO ,
726+ "arrIO" , arrIO ,
727+ "arrObj" , arrObj
728+ );
729+
730+ // Record event with the created segmentation
731+ countly .events ().recordEvent ("key" , segmentation , 1 , 1.0d , 1.0d );
732+
733+ // Prepare expected segmentation with JSONArrays
734+ Map <String , Object > expectedSegmentation = TestUtils .map (
735+ "arr" , arr ,
736+ "arrB" , arrB ,
737+ "arrS" , arrS ,
738+ "arrL" , arrL ,
739+ "arrD" , arrD ,
740+ "arrBO" , arrBO ,
741+ "arrIO" , arrIO
742+ );
743+
744+ // Validate the recorded event with expected segmentation
745+ validateEventInRQ ("key" , expectedSegmentation , 1 , 1.0d , 1.0d , 0 );
746+ }
747+
748+ /**
749+ * "recordHandledException" with invalid data types
750+ * Validate that unsupported data types are not recorded
751+ *
752+ * @throws JSONException if the JSON is not valid
753+ */
754+ @ Test
755+ public void recordEvent_unsupportedDataTypesSegmentation () throws JSONException {
756+ CountlyConfig countlyConfig = TestUtils .createBaseConfig ();
757+ countlyConfig .setEventQueueSizeToSend (1 );
758+ Countly countly = new Countly ().init (countlyConfig );
759+
760+ Map <String , Object > segmentation = TestUtils .map (
761+ "a" , TestUtils .map (),
762+ "b" , TestUtils .json (),
763+ "c" , new Object (),
764+ "d" , Sets .newSet (),
765+ "e" , Mockito .mock (ModuleLog .class )
766+ );
767+
768+ // Record event with the created segmentation
769+ countly .events ().recordEvent ("key" , segmentation , 1 , 1.0d , 1.0d );
770+
771+ validateEventInRQ ("key" , TestUtils .map (), 1 , 1.0d , 1.0d , 0 );
772+ }
773+
574774 protected static JSONObject validateEventInRQ (String deviceId , String eventName , int count , double sum , double duration , int idx , int eventIdx , int eventCount , int rqCount ) throws JSONException {
575775 Map <String , String >[] RQ = TestUtils .getCurrentRQ ();
576776 if (rqCount > -1 ) {
@@ -589,10 +789,12 @@ protected static JSONObject validateEventInRQ(String deviceId, String eventName,
589789
590790 protected static void validateEventInRQ (String eventName , Map <String , Object > expectedSegmentation , int count , double sum , double duration , int idx ) throws JSONException {
591791 JSONObject event = validateEventInRQ (TestUtils .commonDeviceId , eventName , count , sum , duration , idx , 0 , 1 , idx + 1 );
592- JSONObject segmentation = event .getJSONObject ("segmentation" );
593- Assert .assertEquals (expectedSegmentation .size (), segmentation .length ());
594- for (Map .Entry <String , Object > entry : expectedSegmentation .entrySet ()) {
595- Assert .assertEquals (entry .getValue (), segmentation .get (entry .getKey ()));
792+ if (!expectedSegmentation .isEmpty ()) {
793+ JSONObject segmentation = event .getJSONObject ("segmentation" );
794+ Assert .assertEquals (expectedSegmentation .size (), segmentation .length ());
795+ for (Map .Entry <String , Object > entry : expectedSegmentation .entrySet ()) {
796+ Assert .assertEquals (entry .getValue (), segmentation .get (entry .getKey ()));
797+ }
596798 }
597799 Assert .assertEquals (count , event .getInt ("count" ));
598800 Assert .assertEquals (sum , event .optDouble ("sum" , 0.0d ), 0.0001 );
0 commit comments