diff --git a/splitio_android/android/src/main/java/io/split/splitio/Constants.java b/splitio_android/android/src/main/java/io/split/splitio/Constants.java index 4537843..eae5404 100644 --- a/splitio_android/android/src/main/java/io/split/splitio/Constants.java +++ b/splitio_android/android/src/main/java/io/split/splitio/Constants.java @@ -41,6 +41,7 @@ static class Argument { static final String SDK_CONFIGURATION = "sdkConfiguration"; static final String SPLIT_NAME = "splitName"; static final String ATTRIBUTES = "attributes"; + static final String EVALUATION_OPTIONS = "evaluationOptions"; static final String EVENT_TYPE = "eventType"; static final String TRAFFIC_TYPE = "trafficType"; static final String VALUE = "value"; diff --git a/splitio_android/android/src/main/java/io/split/splitio/EvaluationWrapper.java b/splitio_android/android/src/main/java/io/split/splitio/EvaluationWrapper.java index 62ed6d0..8f50160 100644 --- a/splitio_android/android/src/main/java/io/split/splitio/EvaluationWrapper.java +++ b/splitio_android/android/src/main/java/io/split/splitio/EvaluationWrapper.java @@ -3,22 +3,23 @@ import java.util.List; import java.util.Map; +import io.split.android.client.EvaluationOptions; import io.split.android.client.SplitResult; interface EvaluationWrapper { - String getTreatment(String matchingKey, String bucketingKey, String splitName, Map attributes); + String getTreatment(String matchingKey, String bucketingKey, String splitName, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatments(String matchingKey, String bucketingKey, List splitNames, Map attributes); + Map getTreatments(String matchingKey, String bucketingKey, List splitNames, Map attributes, EvaluationOptions evaluationOptions); - SplitResult getTreatmentWithConfig(String matchingKey, String bucketingKey, String splitName, Map attributes); + SplitResult getTreatmentWithConfig(String matchingKey, String bucketingKey, String splitName, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatmentsWithConfig(String matchingKey, String bucketingKey, List splitNames, Map attributes); + Map getTreatmentsWithConfig(String matchingKey, String bucketingKey, List splitNames, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatmentsByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes); + Map getTreatmentsByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatmentsByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes); + Map getTreatmentsByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatmentsWithConfigByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes); + Map getTreatmentsWithConfigByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes, EvaluationOptions evaluationOptions); - Map getTreatmentsWithConfigByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes); + Map getTreatmentsWithConfigByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes, EvaluationOptions evaluationOptions); } diff --git a/splitio_android/android/src/main/java/io/split/splitio/SplitMethodParserImpl.java b/splitio_android/android/src/main/java/io/split/splitio/SplitMethodParserImpl.java index 7631b13..1f4d248 100644 --- a/splitio_android/android/src/main/java/io/split/splitio/SplitMethodParserImpl.java +++ b/splitio_android/android/src/main/java/io/split/splitio/SplitMethodParserImpl.java @@ -4,6 +4,7 @@ import static io.split.splitio.Constants.Argument.ATTRIBUTES; import static io.split.splitio.Constants.Argument.ATTRIBUTE_NAME; import static io.split.splitio.Constants.Argument.BUCKETING_KEY; +import static io.split.splitio.Constants.Argument.EVALUATION_OPTIONS; import static io.split.splitio.Constants.Argument.EVENT_TYPE; import static io.split.splitio.Constants.Argument.FLAG_SET; import static io.split.splitio.Constants.Argument.FLAG_SETS; @@ -57,9 +58,11 @@ import java.util.Map; import io.flutter.plugin.common.MethodChannel; +import io.split.android.client.EvaluationOptions; import io.split.android.client.SplitClient; import io.split.android.client.SplitResult; import io.split.android.client.api.SplitView; +import io.split.android.client.dtos.Prerequisite; import io.split.android.client.events.SplitEvent; import io.split.android.client.events.SplitEventTask; @@ -115,56 +118,64 @@ public void onMethodCall(String methodName, Object arguments, @NonNull MethodCha mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringArgument(SPLIT_NAME, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS: result.success(getTreatments( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringListArgument(SPLIT_NAME, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENT_WITH_CONFIG: result.success(getTreatmentWithConfig( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringArgument(SPLIT_NAME, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS_WITH_CONFIG: result.success(getTreatmentsWithConfig( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringListArgument(SPLIT_NAME, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS_BY_FLAG_SET: result.success(getTreatmentsByFlagSet( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringArgument(FLAG_SET, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS_BY_FLAG_SETS: result.success(getTreatmentsByFlagSets( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringListArgument(FLAG_SETS, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET: result.success(getTreatmentsWithConfigByFlagSet( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringArgument(FLAG_SET, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS: result.success(getTreatmentsWithConfigByFlagSets( mArgumentParser.getStringArgument(MATCHING_KEY, arguments), mArgumentParser.getStringArgument(BUCKETING_KEY, arguments), mArgumentParser.getStringListArgument(FLAG_SETS, arguments), - mArgumentParser.getMapArgument(ATTRIBUTES, arguments))); + mArgumentParser.getMapArgument(ATTRIBUTES, arguments), + buildEvaluationOptions(mArgumentParser.getMapArgument(EVALUATION_OPTIONS, arguments)))); break; case TRACK: result.success(track( @@ -277,23 +288,26 @@ private SplitClient getClient(String matchingKey, String bucketingKey) { private String getTreatment(String matchingKey, String bucketingKey, String splitName, - Map attributes) { - return mSplitWrapper.getTreatment(matchingKey, bucketingKey, splitName, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + return mSplitWrapper.getTreatment(matchingKey, bucketingKey, splitName, attributes, evaluationOptions); } private Map getTreatments(String matchingKey, String bucketingKey, List splitNames, - Map attributes) { - return mSplitWrapper.getTreatments(matchingKey, bucketingKey, splitNames, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + return mSplitWrapper.getTreatments(matchingKey, bucketingKey, splitNames, attributes, evaluationOptions); } private Map> getTreatmentWithConfig( String matchingKey, String bucketingKey, String splitName, - Map attributes) { - SplitResult treatment = mSplitWrapper.getTreatmentWithConfig(matchingKey, bucketingKey, splitName, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + SplitResult treatment = mSplitWrapper.getTreatmentWithConfig(matchingKey, bucketingKey, splitName, attributes, evaluationOptions); return Collections.singletonMap(splitName, getSplitResultMap(treatment)); } @@ -302,8 +316,9 @@ private Map> getTreatmentsWithConfig( String matchingKey, String bucketingKey, List splitNames, - Map attributes) { - Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfig(matchingKey, bucketingKey, splitNames, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfig(matchingKey, bucketingKey, splitNames, attributes, evaluationOptions); return mapToSplitResults(treatmentsWithConfig); } @@ -311,24 +326,27 @@ private Map getTreatmentsByFlagSet( String matchingKey, String bucketingKey, String flagSet, - Map attributes) { - return mSplitWrapper.getTreatmentsByFlagSet(matchingKey, bucketingKey, flagSet, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + return mSplitWrapper.getTreatmentsByFlagSet(matchingKey, bucketingKey, flagSet, attributes, evaluationOptions); } private Map getTreatmentsByFlagSets( String matchingKey, String bucketingKey, List flagSets, - Map attributes) { - return mSplitWrapper.getTreatmentsByFlagSets(matchingKey, bucketingKey, flagSets, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + return mSplitWrapper.getTreatmentsByFlagSets(matchingKey, bucketingKey, flagSets, attributes, evaluationOptions); } private Map> getTreatmentsWithConfigByFlagSet( String matchingKey, String bucketingKey, String flagSet, - Map attributes) { - Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfigByFlagSet(matchingKey, bucketingKey, flagSet, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfigByFlagSet(matchingKey, bucketingKey, flagSet, attributes, evaluationOptions); return mapToSplitResults(treatmentsWithConfig); } @@ -336,8 +354,9 @@ private Map> getTreatmentsWithConfigByFlagSets( String matchingKey, String bucketingKey, List flagSets, - Map attributes) { - Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfigByFlagSets(matchingKey, bucketingKey, flagSets, attributes); + Map attributes, + EvaluationOptions evaluationOptions) { + Map treatmentsWithConfig = mSplitWrapper.getTreatmentsWithConfigByFlagSets(matchingKey, bucketingKey, flagSets, attributes, evaluationOptions); return mapToSplitResults(treatmentsWithConfig); } @@ -474,8 +493,31 @@ private static Map getSplitViewAsMap(@Nullable SplitView splitVi splitViewMap.put("configs", splitView.configs); splitViewMap.put("defaultTreatment", splitView.defaultTreatment); splitViewMap.put("sets", splitView.sets); + splitViewMap.put("prerequisites", getPrerequisiteMap(splitView.prerequisites)); splitViewMap.put("impressionsDisabled", splitView.impressionsDisabled); return splitViewMap; } + + private static List> getPrerequisiteMap(List prerequisites) { + List> prerequisiteList = new ArrayList<>(); + + for (Prerequisite prerequisite : prerequisites) { + Map prerequisiteMap = new HashMap<>(); + prerequisiteMap.put("n", prerequisite.getFlagName()); + prerequisiteMap.put("t", prerequisite.getTreatments()); + prerequisiteList.add(prerequisiteMap); + } + + return prerequisiteList; + } + + @Nullable + private EvaluationOptions buildEvaluationOptions(Map properties) { + if (properties == null || properties.isEmpty()) { + return null; + } + + return new EvaluationOptions(properties); + } } diff --git a/splitio_android/android/src/main/java/io/split/splitio/SplitWrapperImpl.java b/splitio_android/android/src/main/java/io/split/splitio/SplitWrapperImpl.java index 1adef4e..83be8bb 100644 --- a/splitio_android/android/src/main/java/io/split/splitio/SplitWrapperImpl.java +++ b/splitio_android/android/src/main/java/io/split/splitio/SplitWrapperImpl.java @@ -11,6 +11,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import io.split.android.client.EvaluationOptions; import io.split.android.client.SplitClient; import io.split.android.client.SplitFactory; import io.split.android.client.SplitResult; @@ -78,17 +79,17 @@ public boolean track(String matchingKey, @Nullable String bucketingKey, String e } @Override - public String getTreatment(String matchingKey, String bucketingKey, String splitName, Map attributes) { + public String getTreatment(String matchingKey, String bucketingKey, String splitName, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return Treatments.CONTROL; } - return client.getTreatment(splitName, attributes); + return client.getTreatment(splitName, attributes, evaluationOptions); } @Override - public Map getTreatments(String matchingKey, String bucketingKey, List splitNames, Map attributes) { + public Map getTreatments(String matchingKey, String bucketingKey, List splitNames, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { Map defaultResult = new HashMap<>(); @@ -99,21 +100,21 @@ public Map getTreatments(String matchingKey, String bucketingKey return defaultResult; } - return client.getTreatments(splitNames, attributes); + return client.getTreatments(splitNames, attributes, evaluationOptions); } @Override - public SplitResult getTreatmentWithConfig(String matchingKey, String bucketingKey, String splitName, Map attributes) { + public SplitResult getTreatmentWithConfig(String matchingKey, String bucketingKey, String splitName, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return new SplitResult(Treatments.CONTROL); } - return client.getTreatmentWithConfig(splitName, attributes); + return client.getTreatmentWithConfig(splitName, attributes, evaluationOptions); } @Override - public Map getTreatmentsWithConfig(String matchingKey, String bucketingKey, List splitNames, Map attributes) { + public Map getTreatmentsWithConfig(String matchingKey, String bucketingKey, List splitNames, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { Map defaultResult = new HashMap<>(); @@ -124,47 +125,47 @@ public Map getTreatmentsWithConfig(String matchingKey, Stri return defaultResult; } - return client.getTreatmentsWithConfig(splitNames, attributes); + return client.getTreatmentsWithConfig(splitNames, attributes, evaluationOptions); } @Override - public Map getTreatmentsByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes) { + public Map getTreatmentsByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return new HashMap<>(); } - return client.getTreatmentsByFlagSet(flagSet, attributes); + return client.getTreatmentsByFlagSet(flagSet, attributes, evaluationOptions); } @Override - public Map getTreatmentsByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes) { + public Map getTreatmentsByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return new HashMap<>(); } - return client.getTreatmentsByFlagSets(flagSets, attributes); + return client.getTreatmentsByFlagSets(flagSets, attributes, evaluationOptions); } @Override - public Map getTreatmentsWithConfigByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes) { + public Map getTreatmentsWithConfigByFlagSet(String matchingKey, String bucketingKey, String flagSet, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return new HashMap<>(); } - return client.getTreatmentsWithConfigByFlagSet(flagSet, attributes); + return client.getTreatmentsWithConfigByFlagSet(flagSet, attributes, evaluationOptions); } @Override - public Map getTreatmentsWithConfigByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes) { + public Map getTreatmentsWithConfigByFlagSets(String matchingKey, String bucketingKey, List flagSets, Map attributes, EvaluationOptions evaluationOptions) { SplitClient client = getInitializedClient(matchingKey, bucketingKey); if (client == null) { return new HashMap<>(); } - return client.getTreatmentsWithConfigByFlagSets(flagSets, attributes); + return client.getTreatmentsWithConfigByFlagSets(flagSets, attributes, evaluationOptions); } @Override diff --git a/splitio_android/android/src/test/java/io/split/splitio/SplitMethodParserImplTest.java b/splitio_android/android/src/test/java/io/split/splitio/SplitMethodParserImplTest.java index 7f7a225..d4e804a 100644 --- a/splitio_android/android/src/test/java/io/split/splitio/SplitMethodParserImplTest.java +++ b/splitio_android/android/src/test/java/io/split/splitio/SplitMethodParserImplTest.java @@ -1,5 +1,7 @@ package io.split.splitio; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -8,19 +10,29 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; +import androidx.annotation.NonNull; + import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import io.flutter.plugin.common.MethodChannel; +import io.split.android.client.EvaluationOptions; import io.split.android.client.SplitClient; import io.split.android.client.SplitResult; +import io.split.android.client.api.SplitView; +import io.split.android.client.dtos.Prerequisite; public class SplitMethodParserImplTest { @@ -55,7 +67,7 @@ public void successfulGetClient() { mMethodParser.onMethodCall("getClient", map, mResult); verify(mResult).success(null); - verify(mSplitWrapper).getClient("user-key", "bucketing-key"); + verify(mSplitWrapper).getClient(eq("user-key"), eq("bucketing-key")); } @Test @@ -127,11 +139,13 @@ public void getTreatmentWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn(null); when(mArgumentParser.getStringArgument("splitName", map)).thenReturn("split-name"); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatment(any(), any(), any(), any())).thenReturn("on"); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatment(any(), any(), any(), any(), any())).thenReturn("on"); mMethodParser.onMethodCall("getTreatment", map, mResult); - verify(mSplitWrapper).getTreatment("user-key", null, "split-name", Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatment(eq("user-key"), eq((String) null), eq("split-name"), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success("on"); } @@ -150,11 +164,13 @@ public void getTreatmentsWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn(null); when(mArgumentParser.getStringListArgument("splitName", map)).thenReturn(Arrays.asList("split1", "split2")); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatments(any(), any(), any(), any())).thenReturn(expectedResponse); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatments(any(), any(), any(), any(), any())).thenReturn(expectedResponse); mMethodParser.onMethodCall("getTreatments", map, mResult); - verify(mSplitWrapper).getTreatments("user-key", null, Arrays.asList("split1", "split2"), Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatments(eq("user-key"), eq((String) null), eq(Arrays.asList("split1", "split2")), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(expectedResponse); } @@ -184,11 +200,13 @@ public void getTreatmentsWithConfigWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringListArgument("splitName", map)).thenReturn(Arrays.asList("split1", "split2")); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentsWithConfig(any(), any(), any(), any())).thenReturn(mockResult); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentsWithConfig(any(), any(), any(), any(), any())).thenReturn(mockResult); mMethodParser.onMethodCall("getTreatmentsWithConfig", map, mResult); - verify(mSplitWrapper).getTreatmentsWithConfig("user-key", "bucketing-key", Arrays.asList("split1", "split2"), Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentsWithConfig(eq("user-key"), eq("bucketing-key"), eq(Arrays.asList("split1", "split2")), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(finalResultMap); } @@ -204,11 +222,13 @@ public void getTreatmentWithConfigWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringArgument("splitName", map)).thenReturn("split-name"); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentWithConfig(any(), any(), any(), any())).thenReturn(new SplitResult("on", "{config}")); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentWithConfig(any(), any(), any(), any(), any())).thenReturn(new SplitResult("on", "{config}")); mMethodParser.onMethodCall("getTreatmentWithConfig", map, mResult); - verify(mSplitWrapper).getTreatmentWithConfig("user-key", "bucketing-key", "split-name", Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentWithConfig(eq("user-key"), eq("bucketing-key"), eq("split-name"), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); Map resultMap = new HashMap<>(); resultMap.put("treatment", "on"); resultMap.put("config", "{config}"); @@ -231,7 +251,7 @@ public void trackWithValue() { mMethodParser.onMethodCall("track", map, mResult); - verify(mSplitWrapper).track("user-key", "bucketing-key", "my-event", null, 25.20, Collections.emptyMap()); + verify(mSplitWrapper).track(eq("user-key"), eq("bucketing-key"), eq("my-event"), eq((String) null), eq(25.20), eq(Collections.emptyMap())); } @Test @@ -249,7 +269,7 @@ public void trackWithInvalidValue() { mMethodParser.onMethodCall("track", map, mResult); - verify(mSplitWrapper).track("user-key", "bucketing-key", "my-event", null, null, Collections.emptyMap()); + verify(mSplitWrapper).track(eq("user-key"), eq("bucketing-key"), eq("my-event"), eq((String) null), eq((Double) null), eq(Collections.emptyMap())); } @Test @@ -269,7 +289,7 @@ public void trackWithValueAndProperties() { mMethodParser.onMethodCall("track", map, mResult); - verify(mSplitWrapper).track("user-key", "bucketing-key", "my-event", null, 25.20, Collections.singletonMap("age", 50)); + verify(mSplitWrapper).track(eq("user-key"), eq("bucketing-key"), eq("my-event"), eq((String) null), eq(25.20), eq(Collections.singletonMap("age", 50))); } @Test @@ -291,7 +311,7 @@ public void trackWithEverything() { mMethodParser.onMethodCall("track", map, mResult); - verify(mSplitWrapper).track("user-key", "bucketing-key", "my-event", "account", 25.20, Collections.singletonMap("age", 50)); + verify(mSplitWrapper).track(eq("user-key"), eq("bucketing-key"), eq("my-event"), eq("account"), eq(25.20), eq(Collections.singletonMap("age", 50))); } @Test @@ -307,7 +327,7 @@ public void getSingleAttribute() { mMethodParser.onMethodCall("getAttribute", map, mResult); - verify(mSplitWrapper).getAttribute("user-key", "bucketing-key", "my_attribute"); + verify(mSplitWrapper).getAttribute(eq("user-key"), eq("bucketing-key"), eq("my_attribute")); } @Test @@ -321,7 +341,7 @@ public void getAllAttributes() { mMethodParser.onMethodCall("getAllAttributes", map, mResult); - verify(mSplitWrapper).getAllAttributes("user-key", "bucketing-key"); + verify(mSplitWrapper).getAllAttributes(eq("user-key"), eq("bucketing-key")); } @Test @@ -339,7 +359,7 @@ public void setSingleAttribute() { mMethodParser.onMethodCall("setAttribute", map, mResult); - verify(mSplitWrapper).setAttribute("user-key", "bucketing-key", "my_attr", "attr_value"); + verify(mSplitWrapper).setAttribute(eq("user-key"), eq("bucketing-key"), eq("my_attr"), eq("attr_value")); } @Test @@ -361,7 +381,7 @@ public void setMultipleAttributes() { mMethodParser.onMethodCall("setAttributes", map, mResult); - verify(mSplitWrapper).setAttributes("user-key", "bucketing-key", attributesMap); + verify(mSplitWrapper).setAttributes(eq("user-key"), eq("bucketing-key"), eq(attributesMap)); } @Test @@ -377,7 +397,7 @@ public void removeAttribute() { mMethodParser.onMethodCall("removeAttribute", map, mResult); - verify(mSplitWrapper).removeAttribute("user-key", "bucketing-key", "my_attr"); + verify(mSplitWrapper).removeAttribute(eq("user-key"), eq("bucketing-key"), eq("my_attr")); } @Test @@ -391,7 +411,7 @@ public void clearAttributes() { mMethodParser.onMethodCall("clearAttributes", map, mResult); - verify(mSplitWrapper).clearAttributes("user-key", "bucketing-key"); + verify(mSplitWrapper).clearAttributes(eq("user-key"), eq("bucketing-key")); } @Test @@ -405,7 +425,7 @@ public void flush() { mMethodParser.onMethodCall("flush", map, mResult); - verify(mSplitWrapper).flush("user-key", "bucketing-key"); + verify(mSplitWrapper).flush(eq("user-key"), eq("bucketing-key")); verify(mResult).success(null); } @@ -420,22 +440,89 @@ public void destroy() { mMethodParser.onMethodCall("destroy", map, mResult); - verify(mSplitWrapper).destroy("user-key", "bucketing-key"); + verify(mSplitWrapper).destroy(eq("user-key"), eq("bucketing-key")); verify(mResult).success(null); } @Test - public void splitNames() { - mMethodParser.onMethodCall("splitNames", Collections.emptyMap(), mResult); - - verify(mSplitWrapper).splitNames(); + public void splitViews() { + Prerequisite prerequisite1 = mock(Prerequisite.class); + when(prerequisite1.getFlagName()).thenReturn("flag1"); + when(prerequisite1.getTreatments()).thenReturn(new HashSet<>(Arrays.asList("on", "true"))); + + Prerequisite prerequisite2 = mock(Prerequisite.class); + when(prerequisite2.getFlagName()).thenReturn("flag2"); + when(prerequisite2.getTreatments()).thenReturn(new HashSet<>(Arrays.asList("on", "true"))); + + List prerequisites = Arrays.asList(prerequisite1, prerequisite2); + + SplitView splitView = mock(SplitView.class); + splitView.name = "test_split"; + splitView.trafficType = "user"; + splitView.killed = false; + splitView.treatments = Arrays.asList("on", "off"); + splitView.changeNumber = 123L; + splitView.configs = Collections.singletonMap("on", "{\"color\": \"blue\"}"); + splitView.defaultTreatment = "off"; + splitView.sets = Arrays.asList("set1", "set2"); + splitView.prerequisites = prerequisites; + splitView.impressionsDisabled = true; + + when(mSplitWrapper.splits()).thenReturn(Arrays.asList(splitView)); + + mMethodParser.onMethodCall("splits", Collections.emptyMap(), mResult); + + verify(mSplitWrapper).splits(); + + // Verify that the result includes the correctly formatted prerequisites + ArgumentCaptor>> captor = ArgumentCaptor.forClass(List.class); + verify(mResult).success(captor.capture()); + + List> result = captor.getValue(); + assertEquals(1, result.size()); + + Map splitViewMap = result.get(0); + + // Verify all SplitView fields are correctly mapped + assertEquals("test_split", splitViewMap.get("name")); + assertEquals("user", splitViewMap.get("trafficType")); + assertEquals(false, splitViewMap.get("killed")); + assertEquals(Arrays.asList("on", "off"), splitViewMap.get("treatments")); + assertEquals(123L, splitViewMap.get("changeNumber")); + assertEquals(Collections.singletonMap("on", "{\"color\": \"blue\"}"), splitViewMap.get("configs")); + assertEquals("off", splitViewMap.get("defaultTreatment")); + assertEquals(Arrays.asList("set1", "set2"), splitViewMap.get("sets")); + assertEquals(true, splitViewMap.get("impressionsDisabled")); + + // Verify prerequisites + assertTrue(splitViewMap.containsKey("prerequisites")); + + @SuppressWarnings("unchecked") + List> prerequisitesResult = (List>) splitViewMap.get("prerequisites"); + assertEquals(2, prerequisitesResult.size()); + + // Verify first prerequisite + Map prereq1 = prerequisitesResult.get(0); + assertEquals("flag1", prereq1.get("n")); + Set treatments = (Set) prereq1.get("t"); + assertEquals(2, treatments.size()); + assertTrue(treatments.contains("on")); + assertTrue(treatments.contains("true")); + + // Verify second prerequisite + Map prereq2 = prerequisitesResult.get(1); + assertEquals("flag2", prereq2.get("n")); + Set treatments1 = (Set) prereq2.get("t"); + assertEquals(2, treatments1.size()); + assertTrue(treatments1.contains("on")); + assertTrue(treatments1.contains("true")); } @Test - public void splits() { - mMethodParser.onMethodCall("splits", Collections.emptyMap(), mResult); + public void splitNames() { + mMethodParser.onMethodCall("splitNames", Collections.emptyMap(), mResult); - verify(mSplitWrapper).splits(); + verify(mSplitWrapper).splitNames(); } @Test @@ -444,7 +531,7 @@ public void split() { mMethodParser.onMethodCall("split", Collections.singletonMap("splitName", "my_split"), mResult); - verify(mSplitWrapper).split("my_split"); + verify(mSplitWrapper).split(eq("my_split")); } @Test @@ -492,7 +579,7 @@ public void setUserConsentEnabled() { mMethodParser.onMethodCall("setUserConsent", Collections.singletonMap("value", true), mResult); verify(mResult).success(null); - verify(mSplitWrapper).setUserConsent(true); + verify(mSplitWrapper).setUserConsent(eq(true)); } @Test @@ -502,7 +589,7 @@ public void setUserConsentDisabled() { mMethodParser.onMethodCall("setUserConsent", Collections.singletonMap("value", false), mResult); verify(mResult).success(null); - verify(mSplitWrapper).setUserConsent(false); + verify(mSplitWrapper).setUserConsent(eq(false)); } @Test @@ -517,11 +604,13 @@ public void getTreatmentsByFlagSetWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringArgument("flagSet", map)).thenReturn("set_1"); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentsByFlagSet(any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", "on")); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentsByFlagSet(any(), any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", "on")); mMethodParser.onMethodCall("getTreatmentsByFlagSet", map, mResult); - verify(mSplitWrapper).getTreatmentsByFlagSet("user-key", "bucketing-key", "set_1", Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentsByFlagSet(eq("user-key"), eq("bucketing-key"), eq("set_1"), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(Collections.singletonMap("flag_1", "on")); } @@ -537,11 +626,13 @@ public void getTreatmentsByFlagSetsWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringListArgument("flagSets", map)).thenReturn(Arrays.asList("set_1", "set_2")); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentsByFlagSets(any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", "on")); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentsByFlagSets(any(), any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", "on")); mMethodParser.onMethodCall("getTreatmentsByFlagSets", map, mResult); - verify(mSplitWrapper).getTreatmentsByFlagSets("user-key", "bucketing-key", Arrays.asList("set_1", "set_2"), Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentsByFlagSets(eq("user-key"), eq("bucketing-key"), eq(Arrays.asList("set_1", "set_2")), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(Collections.singletonMap("flag_1", "on")); } @@ -561,11 +652,13 @@ public void getTreatmentsWithConfigByFlagSetWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringArgument("flagSet", map)).thenReturn("set_1"); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentsWithConfigByFlagSet(any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", new SplitResult("on", "{config}"))); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentsWithConfigByFlagSet(any(), any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", new SplitResult("on", "{config}"))); mMethodParser.onMethodCall("getTreatmentsWithConfigByFlagSet", map, mResult); - verify(mSplitWrapper).getTreatmentsWithConfigByFlagSet("user-key", "bucketing-key", "set_1", Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentsWithConfigByFlagSet(eq("user-key"), eq("bucketing-key"), eq("set_1"), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(Collections.singletonMap("flag_1", resultMap1)); } @@ -585,11 +678,18 @@ public void getTreatmentsWithConfigByFlagSetsWorksCorrectly() { when(mArgumentParser.getStringArgument("bucketingKey", map)).thenReturn("bucketing-key"); when(mArgumentParser.getStringListArgument("flagSets", map)).thenReturn(Arrays.asList("set_1", "set_2")); when(mArgumentParser.getMapArgument("attributes", map)).thenReturn(Collections.singletonMap("age", 10)); - when(mSplitWrapper.getTreatmentsWithConfigByFlagSets(any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", new SplitResult("on", "{config}"))); + when(mArgumentParser.getMapArgument("evaluationOptions", map)).thenReturn(Collections.singletonMap("boolean", true)); + when(mSplitWrapper.getTreatmentsWithConfigByFlagSets(any(), any(), any(), any(), any())).thenReturn(Collections.singletonMap("flag_1", new SplitResult("on", "{config}"))); mMethodParser.onMethodCall("getTreatmentsWithConfigByFlagSets", map, mResult); - verify(mSplitWrapper).getTreatmentsWithConfigByFlagSets("user-key", "bucketing-key", Arrays.asList("set_1", "set_2"), Collections.singletonMap("age", 10)); + verify(mSplitWrapper).getTreatmentsWithConfigByFlagSets(eq("user-key"), eq("bucketing-key"), eq(Arrays.asList("set_1", "set_2")), eq(Collections.singletonMap("age", 10)), + argThat(evaluationOptionsPropertiesMatcher())); verify(mResult).success(Collections.singletonMap("flag_1", resultMap1)); } + + @NonNull + private static ArgumentMatcher evaluationOptionsPropertiesMatcher() { + return options -> options != null && options.getProperties().size() == 1 && options.getProperties().containsKey("boolean") && (Boolean) options.getProperties().get("boolean"); + } } diff --git a/splitio_android/android/src/test/java/io/split/splitio/SplitWrapperImplTest.java b/splitio_android/android/src/test/java/io/split/splitio/SplitWrapperImplTest.java index 733fb31..42ae794 100644 --- a/splitio_android/android/src/test/java/io/split/splitio/SplitWrapperImplTest.java +++ b/splitio_android/android/src/test/java/io/split/splitio/SplitWrapperImplTest.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Set; +import io.split.android.client.EvaluationOptions; import io.split.android.client.SplitClient; import io.split.android.client.SplitFactory; import io.split.android.client.SplitManager; @@ -60,9 +61,10 @@ public void testGetTreatment() { when(mSplitFactory.client("key", null)).thenReturn(clientMock); when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); - mSplitWrapper.getTreatment("key", null, "split-name", Collections.singletonMap("age", 50)); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatment("key", null, "split-name", Collections.singletonMap("age", 50), evaluationOptions); - verify(clientMock).getTreatment("split-name", Collections.singletonMap("age", 50)); + verify(clientMock).getTreatment("split-name", Collections.singletonMap("age", 50), evaluationOptions); } @Test @@ -72,9 +74,10 @@ public void testGetTreatments() { when(mSplitFactory.client("key", null)).thenReturn(clientMock); when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); - mSplitWrapper.getTreatments("key", null, Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50)); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatments("key", null, Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50), evaluationOptions); - verify(clientMock).getTreatments(Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50)); + verify(clientMock).getTreatments(Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50), evaluationOptions); } @Test @@ -84,9 +87,10 @@ public void testGetTreatmentWithConfig() { when(mSplitFactory.client("key", null)).thenReturn(clientMock); when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); - mSplitWrapper.getTreatmentWithConfig("key", null, "split-name", Collections.singletonMap("age", 50)); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentWithConfig("key", null, "split-name", Collections.singletonMap("age", 50), evaluationOptions); - verify(clientMock).getTreatmentWithConfig("split-name", Collections.singletonMap("age", 50)); + verify(clientMock).getTreatmentWithConfig("split-name", Collections.singletonMap("age", 50), evaluationOptions); } @Test @@ -96,9 +100,10 @@ public void testGetTreatmentsWithConfig() { when(mSplitFactory.client("key", null)).thenReturn(clientMock); when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); - mSplitWrapper.getTreatmentsWithConfig("key", null, Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50)); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentsWithConfig("key", null, Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50), evaluationOptions); - verify(clientMock).getTreatmentsWithConfig(Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50)); + verify(clientMock).getTreatmentsWithConfig(Arrays.asList("split1", "split2"), Collections.singletonMap("age", 50), evaluationOptions); } @Test @@ -108,9 +113,10 @@ public void testGetTreatmentsByFlagSet() { when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); Map attrs = Collections.singletonMap("age", 50); - mSplitWrapper.getTreatmentsByFlagSet("key", null, "flag-set", attrs); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentsByFlagSet("key", null, "flag-set", attrs, evaluationOptions); - verify(clientMock).getTreatmentsByFlagSet("flag-set", attrs); + verify(clientMock).getTreatmentsByFlagSet("flag-set", attrs, evaluationOptions); } @Test @@ -121,9 +127,10 @@ public void testGetTreatmentsByFlagSets() { Map attrs = Collections.singletonMap("age", 50); List sets = Arrays.asList("set_1", "set_2"); - mSplitWrapper.getTreatmentsByFlagSets("key", null, sets, attrs); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentsByFlagSets("key", null, sets, attrs, evaluationOptions); - verify(clientMock).getTreatmentsByFlagSets(sets, attrs); + verify(clientMock).getTreatmentsByFlagSets(sets, attrs, evaluationOptions); } @Test @@ -133,9 +140,10 @@ public void testGetTreatmentsWithConfigByFlagSet() { when(mUsedKeys.contains(new Key("key", null))).thenReturn(true); Map attrs = Collections.singletonMap("age", 50); - mSplitWrapper.getTreatmentsWithConfigByFlagSet("key", null,"set_1", attrs); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentsWithConfigByFlagSet("key", null,"set_1", attrs, evaluationOptions); - verify(clientMock).getTreatmentsWithConfigByFlagSet("set_1", attrs); + verify(clientMock).getTreatmentsWithConfigByFlagSet("set_1", attrs, evaluationOptions); } @Test @@ -146,9 +154,10 @@ public void testGetTreatmentsWithConfigByFlagSets() { Map attrs = Collections.singletonMap("age", 50); List sets = Arrays.asList("set_1", "set_2"); - mSplitWrapper.getTreatmentsWithConfigByFlagSets("key", null, sets, attrs); + EvaluationOptions evaluationOptions = new EvaluationOptions(Collections.singletonMap("boolean", true)); + mSplitWrapper.getTreatmentsWithConfigByFlagSets("key", null, sets, attrs, evaluationOptions); - verify(clientMock).getTreatmentsWithConfigByFlagSets(sets, attrs); + verify(clientMock).getTreatmentsWithConfigByFlagSets(sets, attrs, evaluationOptions); } @Test diff --git a/splitio_android/pubspec.yaml b/splitio_android/pubspec.yaml index 79bcfb8..05d4e96 100644 --- a/splitio_android/pubspec.yaml +++ b/splitio_android/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_android description: The official Android implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_android -version: 0.2.0 +version: 1.0.0-rc.1 environment: sdk: ">=2.16.2 <4.0.0" @@ -19,7 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: # ^1.5.0 + splitio_platform_interface: # ^2.0.0-rc.1 path: ../splitio_platform_interface dev_dependencies: diff --git a/splitio_android/test/splitio_android_test.dart b/splitio_android/test/splitio_android_test.dart index 554d4cd..7cecd3d 100644 --- a/splitio_android/test/splitio_android_test.dart +++ b/splitio_android/test/splitio_android_test.dart @@ -502,14 +502,20 @@ void main() { apiKey: 'api-key', matchingKey: 'matching-key', bucketingKey: 'bucketing-key', - sdkConfiguration: - SplitConfiguration(logLevel: SplitLogLevel.error, streamingEnabled: false, readyTimeout: 1)); + sdkConfiguration: SplitConfiguration( + logLevel: SplitLogLevel.error, + streamingEnabled: false, + readyTimeout: 1)); expect(methodName, 'init'); expect(methodArguments, { 'apiKey': 'api-key', 'matchingKey': 'matching-key', 'bucketingKey': 'bucketing-key', - 'sdkConfiguration': {'logLevel': 'error', 'streamingEnabled': false, 'readyTimeout': 1}, + 'sdkConfiguration': { + 'logLevel': 'error', + 'streamingEnabled': false, + 'readyTimeout': 1 + }, }); }); }); @@ -631,6 +637,7 @@ void main() { expect(impression.appliedRule, 'appliedRule'); expect(impression.changeNumber, 200); expect(impression.attributes, {}); + expect(impression.properties, {}); }), ); _simulateMethodInvocation('impressionLog', key: 'matching-key', arguments: { @@ -641,7 +648,8 @@ void main() { 'time': 3000, 'appliedRule': 'appliedRule', 'changeNumber': 200, - 'attributes': {} + 'attributes': {}, + 'properties': {}, }); }); diff --git a/splitio_ios/ios/Classes/Extensions.swift b/splitio_ios/ios/Classes/Extensions.swift index fdad567..490d398 100644 --- a/splitio_ios/ios/Classes/Extensions.swift +++ b/splitio_ios/ios/Classes/Extensions.swift @@ -9,7 +9,8 @@ extension Impression { "time": time, "appliedRule": label, "changeNumber": changeNumber, - "attributes": attributes] + "attributes": attributes, + "properties": "properties"] // TODO } } @@ -26,6 +27,7 @@ extension SplitView { "defaultTreatment": splitView.defaultTreatment, "sets": splitView.sets, "impressionsDisabled": splitView.impressionsDisabled, + "properties": "" // TODO ] } else { return [:] diff --git a/splitio_ios/pubspec.yaml b/splitio_ios/pubspec.yaml index 06849c8..ae0269e 100644 --- a/splitio_ios/pubspec.yaml +++ b/splitio_ios/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_ios description: The official iOS implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_ios -version: 0.2.0 +version: 1.0.0-rc.1 environment: sdk: ">=2.16.2 <4.0.0" @@ -18,7 +18,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: # ^1.5.0 + splitio_platform_interface: # ^2.0.0-rc.1 path: ../splitio_platform_interface dev_dependencies: diff --git a/splitio_ios/test/splitio_ios_test.dart b/splitio_ios/test/splitio_ios_test.dart index ab04f62..df312aa 100644 --- a/splitio_ios/test/splitio_ios_test.dart +++ b/splitio_ios/test/splitio_ios_test.dart @@ -190,7 +190,6 @@ void main() { }); }); - test('getTreatmentsByFlagSet without attributes', () async { _platform.getTreatmentsByFlagSet( matchingKey: 'matching-key', @@ -503,14 +502,20 @@ void main() { apiKey: 'api-key', matchingKey: 'matching-key', bucketingKey: 'bucketing-key', - sdkConfiguration: - SplitConfiguration(logLevel: SplitLogLevel.error, streamingEnabled: false, readyTimeout: 1)); + sdkConfiguration: SplitConfiguration( + logLevel: SplitLogLevel.error, + streamingEnabled: false, + readyTimeout: 1)); expect(methodName, 'init'); expect(methodArguments, { 'apiKey': 'api-key', 'matchingKey': 'matching-key', 'bucketingKey': 'bucketing-key', - 'sdkConfiguration': {'logLevel': 'error', 'streamingEnabled': false, 'readyTimeout': 1}, + 'sdkConfiguration': { + 'logLevel': 'error', + 'streamingEnabled': false, + 'readyTimeout': 1 + }, }); }); }); @@ -632,6 +637,7 @@ void main() { expect(impression.appliedRule, 'appliedRule'); expect(impression.changeNumber, 200); expect(impression.attributes, {}); + expect(impression.properties, {}); }), ); _simulateMethodInvocation('impressionLog', key: 'matching-key', arguments: { @@ -642,11 +648,11 @@ void main() { 'time': 3000, 'appliedRule': 'appliedRule', 'changeNumber': 200, - 'attributes': {} + 'attributes': {}, + 'properties': {} }); }); - group('userConsent', () { test('get user consent', () async { UserConsent userConsent = await _platform.getUserConsent(); diff --git a/splitio_platform_interface/lib/split_impression.dart b/splitio_platform_interface/lib/split_impression.dart index 6deec0b..5a5b712 100644 --- a/splitio_platform_interface/lib/split_impression.dart +++ b/splitio_platform_interface/lib/split_impression.dart @@ -7,9 +7,10 @@ class Impression { final String? appliedRule; final num? changeNumber; final Map attributes; + final Map properties; Impression(this.key, this.bucketingKey, this.split, this.treatment, this.time, - this.appliedRule, this.changeNumber, this.attributes); + this.appliedRule, this.changeNumber, this.attributes, this.properties); static Impression fromMap(Map map) { return Impression( @@ -20,11 +21,12 @@ class Impression { map['time'] as num?, map['appliedRule'] as String?, map['changeNumber'] as num?, - Map.from(map['attributes'] as Map)); + Map.from(map['attributes'] as Map), + Map.from(map['properties'] as Map)); } @override String toString() { - return 'Impression = {"key":$key, "bucketingKey":$bucketingKey, "split":$split, "treatment":$treatment, "time":$time, "appliedRule": $appliedRule, "changeNumber":$changeNumber, "attributes":$attributes}'; + return 'Impression = {"key":$key, "bucketingKey":$bucketingKey, "split":$split, "treatment":$treatment, "time":$time, "appliedRule": $appliedRule, "changeNumber":$changeNumber, "attributes":$attributes, "properties":$properties}'; } } diff --git a/splitio_platform_interface/test/method_channel_platform_test.dart b/splitio_platform_interface/test/method_channel_platform_test.dart index 5c4b57c..3692397 100644 --- a/splitio_platform_interface/test/method_channel_platform_test.dart +++ b/splitio_platform_interface/test/method_channel_platform_test.dart @@ -814,6 +814,7 @@ void main() { expect(impression.appliedRule, 'appliedRule'); expect(impression.changeNumber, 200); expect(impression.attributes, {}); + expect(impression.properties, {'prop1': 'value1', 'prop2': 'value2'}); }), ); _simulateMethodInvocation('impressionLog', key: 'matching-key', arguments: { @@ -824,7 +825,8 @@ void main() { 'time': 3000, 'appliedRule': 'appliedRule', 'changeNumber': 200, - 'attributes': {} + 'attributes': {}, + 'properties': {'prop1': 'value1', 'prop2': 'value2'} }); }); diff --git a/splitio_platform_interface/test/split_impression_test.dart b/splitio_platform_interface/test/split_impression_test.dart index b993d2a..689599d 100644 --- a/splitio_platform_interface/test/split_impression_test.dart +++ b/splitio_platform_interface/test/split_impression_test.dart @@ -12,6 +12,7 @@ void main() { 'appliedRule': 'appliedRule', 'changeNumber': 12512512, 'attributes': {'good': true}, + 'properties': {'bad': false, 'number': 10.5}, }; Impression expectedImpression = Impression( @@ -23,6 +24,7 @@ void main() { 'appliedRule', 12512512, {'good': true}, + {'bad': false, 'number': 10.5}, ); Impression impression = Impression.fromMap(sourceMap); @@ -34,5 +36,6 @@ void main() { expect(impression.appliedRule, expectedImpression.appliedRule); expect(impression.changeNumber, expectedImpression.changeNumber); expect(impression.attributes, expectedImpression.attributes); + expect(impression.properties, expectedImpression.properties); }); }