Skip to content

Commit c649dea

Browse files
committed
fix cmab endpoint config
1 parent b127a64 commit c649dea

File tree

8 files changed

+148
-39
lines changed

8 files changed

+148
-39
lines changed

android-sdk/src/androidTest/java/com/optimizely/ab/android/sdk/OptimizelyClientTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ public OptimizelyClientTest(int datafileVersion,String datafile){
132132

133133
// set to return DecisionResponse with null variation by default (instead of null DecisionResponse)
134134
when(bucketer.bucket(any(), any(), any())).thenReturn(DecisionResponse.nullNoReasons());
135+
when(bucketer.bucket(any(), any(), any(), any())).thenReturn(DecisionResponse.nullNoReasons());
135136

136137
if(datafileVersion==3) {
137138
Variation variation = optimizely.getProjectConfig().getExperiments().get(0).getVariations().get(0);

android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.optimizely.ab.android.event_handler.EventDispatcher;
4040
import com.optimizely.ab.android.odp.DefaultODPApiManager;
4141
import com.optimizely.ab.android.odp.VuidManager;
42+
import com.optimizely.ab.android.sdk.cmab.CmabClientHelperAndroid;
4243
import com.optimizely.ab.android.sdk.cmab.DefaultCmabClient;
4344
import com.optimizely.ab.android.shared.Client;
4445
import com.optimizely.ab.android.shared.DatafileConfig;
@@ -803,6 +804,7 @@ public static class Builder {
803804

804805
private int cmabCacheSize = 100;
805806
private int cmabCacheTimeoutInSecs = 30*60;
807+
private String cmabPredictionEndpoint = null;
806808

807809
private String customSdkName = null;
808810
private String customSdkVersion = null;
@@ -1094,11 +1096,28 @@ public Builder withCmabCacheTimeout(int interval, TimeUnit timeUnit) {
10941096
return this;
10951097
}
10961098

1099+
/**
1100+
* Override the default {@link CmabClient} implementation for CMAB operations.
1101+
*
1102+
* @param cmabClient The {@link CmabClient} instance to use.
1103+
* @return this {@link Builder} instance
1104+
*/
10971105
public Builder withCmabClient(CmabClient cmabClient) {
10981106
this.cmabClient = cmabClient;
10991107
return this;
11001108
}
11011109

1110+
/**
1111+
* Override the default prediction endpoint for the CMAB client.
1112+
*
1113+
* @param endpoint The prediction endpoint as an integer.
1114+
* @return this {@link Builder} instance
1115+
*/
1116+
public Builder withCmabPredictionEndpoint(String endpoint) {
1117+
this.cmabPredictionEndpoint = endpoint;
1118+
return this;
1119+
}
1120+
11021121
/**
11031122
* Get a new {@link Builder} instance to create {@link OptimizelyManager} with.
11041123
* @param context the application context used to create default service if not provided.
@@ -1203,7 +1222,13 @@ public OptimizelyManager build(Context context) {
12031222

12041223
DefaultCmabService.Builder cmabBuilder = DefaultCmabService.builder();
12051224
if (cmabClient == null) {
1206-
cmabClient = new DefaultCmabClient(context);
1225+
if (cmabPredictionEndpoint == null) {
1226+
cmabClient = new DefaultCmabClient(context);
1227+
} else {
1228+
CmabClientHelperAndroid cmabHelper = new CmabClientHelperAndroid();
1229+
cmabHelper.setCmabPredictionEndpoint(cmabPredictionEndpoint);
1230+
cmabClient = new DefaultCmabClient(context, cmabHelper);
1231+
}
12071232
}
12081233
cmabBuilder.withClient(cmabClient);
12091234
cmabBuilder.withCmabCacheSize(cmabCacheSize);

android-sdk/src/main/java/com/optimizely/ab/android/sdk/cmab/DefaultCmabClient.kt

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,24 @@ open class DefaultCmabClient : CmabClient {
3131
private val cmabClientHelper: CmabClientHelperAndroid
3232
private val logger = LoggerFactory.getLogger(DefaultCmabClient::class.java)
3333

34-
constructor(context: Context) {
35-
this.client =
36-
Client(OptlyStorage(context), LoggerFactory.getLogger(OptlyStorage::class.java))
37-
this.cmabClientHelper = CmabClientHelperAndroid()
34+
@VisibleForTesting
35+
fun getCmabClientHelper(): CmabClientHelperAndroid {
36+
return cmabClientHelper
3837
}
3938

40-
constructor(context: Context, cmabClientHelper: CmabClientHelperAndroid) {
39+
constructor(context: Context) : this(context, null)
40+
41+
constructor(context: Context, cmabClientHelper: CmabClientHelperAndroid?) {
4142
this.client =
4243
Client(OptlyStorage(context), LoggerFactory.getLogger(OptlyStorage::class.java))
43-
this.cmabClientHelper = cmabClientHelper
44+
this.cmabClientHelper = cmabClientHelper ?: CmabClientHelperAndroid()
4445
}
4546

46-
constructor(client: Client) {
47-
this.client = client
48-
this.cmabClientHelper = CmabClientHelperAndroid()
49-
}
47+
constructor(client: Client) : this(client, null)
5048

51-
constructor(client: Client, cmabClientHelper: CmabClientHelperAndroid) {
49+
constructor(client: Client, cmabClientHelper: CmabClientHelperAndroid?) {
5250
this.client = client
53-
this.cmabClientHelper = cmabClientHelper
51+
this.cmabClientHelper = cmabClientHelper ?: CmabClientHelperAndroid()
5452
}
5553

5654
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)

android-sdk/src/test/java/com/optimizely/ab/android/sdk/OptimizelyManagerBuilderTest.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.optimizely.ab.android.odp.ODPEventClient;
2626
import com.optimizely.ab.android.odp.ODPSegmentClient;
2727
import com.optimizely.ab.android.odp.VuidManager;
28+
import com.optimizely.ab.android.sdk.cmab.CmabClientHelperAndroid;
2829
import com.optimizely.ab.android.sdk.cmab.DefaultCmabClient;
2930
import com.optimizely.ab.android.shared.Client;
3031
import com.optimizely.ab.android.shared.DatafileConfig;
@@ -43,6 +44,7 @@
4344
import com.optimizely.ab.odp.ODPSegmentManager;
4445

4546
import org.junit.After;
47+
import org.junit.Assert;
4648
import org.junit.Before;
4749
import org.junit.Test;
4850
import org.junit.runner.RunWith;
@@ -544,7 +546,52 @@ public void testCmabServiceConfigurationValidation() throws Exception {
544546

545547
assertNotNull("Manager should be created successfully", manager);
546548
}
547-
549+
//
550+
// @Test
551+
// public void testCmabServiceConfigurationValidation_2() throws Exception {
552+
// // Custom configuration for cmab endpoint
553+
// String customCmabEndpoint = "https://google.com";
554+
//
555+
// // Mock the builder and its static method
556+
//
557+
// DefaultCmabService.Builder mockBuilder = getMockDefaultCmabServiceBuilder();
558+
// mockStatic(DefaultCmabService.class);
559+
// when(DefaultCmabService.builder()).thenReturn(mockBuilder);
560+
// DefaultCmabService mockDefaultCmabService = mock(DefaultCmabService.class);
561+
// when(mockBuilder.build()).thenReturn(mockDefaultCmabService);
562+
//
563+
// // Prevent the real OptimizelyManager from being constructed
564+
// whenNew(OptimizelyManager.class).withAnyArguments().thenReturn(mock(OptimizelyManager.class));
565+
//
566+
// // Spy on the real DefaultCmabClient constructor.
567+
//
568+
// final DefaultCmabClient[] clientSpyContainer = new DefaultCmabClient[1];
569+
// whenNew(DefaultCmabClient.class).withAnyArguments().thenAnswer(invocation -> {
570+
// // Create a REAL spy of the object that was about to be created.
571+
// DefaultCmabClient realClient = (DefaultCmabClient) invocation.callRealMethod();
572+
// DefaultCmabClient clientSpy = spy(realClient);
573+
// clientSpyContainer[0] = clientSpy; // Store the spy in a container to access it later
574+
// return clientSpy;
575+
// });
576+
//
577+
// // Build the manager with the custom endpoint
578+
//
579+
// OptimizelyManager manager = OptimizelyManager.builder(testProjectId)
580+
// .withCmabPredictionEndpoint(customCmabEndpoint)
581+
// .build(mockContext);
582+
//
583+
// // Assert
584+
//
585+
// DefaultCmabClient capturedClient = clientSpyContainer[0];
586+
// assertNotNull("The DefaultCmabClient spy should have been captured", capturedClient);
587+
//
588+
// CmabClientHelperAndroid helper = capturedClient.getCmabClientHelper();
589+
// Assert.assertEquals("The helper endpoint should have been updated", customCmabEndpoint, helper.getCmabPredictionEndpoint());
590+
//
591+
// verify(mockBuilder).withClient(eq(capturedClient));
592+
// verify(mockBuilder).build();
593+
// }
594+
//
548595
@Test
549596
public void testCmabServiceDefaultConfigurationValidation() throws Exception {
550597
// Default configuration values

android-sdk/src/test/java/com/optimizely/ab/android/sdk/cmab/DefaultCmabClientTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,36 @@ public void setup() {
5757
testAttributes.put("country", "US");
5858
}
5959

60+
@Test
61+
public void testConstructorWithClientOnly() {
62+
Client client = mock(Client.class);
63+
DefaultCmabClient cmabClient = new DefaultCmabClient(client);
64+
assertNotNull(cmabClient);
65+
}
66+
67+
@Test
68+
public void testConstructorWithClientAndHelper() {
69+
Client client = mock(Client.class);
70+
CmabClientHelperAndroid helper = mock(CmabClientHelperAndroid.class);
71+
DefaultCmabClient cmabClient = new DefaultCmabClient(client, helper);
72+
assertNotNull(cmabClient);
73+
}
74+
75+
@Test
76+
public void testConstructorWithContextOnly() {
77+
android.content.Context mockContext = mock(android.content.Context.class);
78+
DefaultCmabClient cmabClient = new DefaultCmabClient(mockContext);
79+
assertNotNull(cmabClient);
80+
}
81+
82+
@Test
83+
public void testConstructorWithContextAndHelper() {
84+
android.content.Context mockContext = mock(android.content.Context.class);
85+
CmabClientHelperAndroid helper = mock(CmabClientHelperAndroid.class);
86+
DefaultCmabClient cmabClient = new DefaultCmabClient(mockContext, helper);
87+
assertNotNull(cmabClient);
88+
}
89+
6090
@Test
6191
public void testFetchDecisionSuccess() throws Exception {
6292
HttpURLConnection mockUrlConnection = mock(HttpURLConnection.class);

build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ allprojects {
6666
}
6767

6868
repositories {
69+
mavenLocal()
70+
6971
google()
7072
mavenCentral()
7173
// SNAPSHOT support
@@ -95,7 +97,10 @@ ext {
9597
build_tools_version = "35.0.0"
9698
min_sdk_version = 21
9799
target_sdk_version = 35
98-
java_core_ver = "4.2.2"
100+
101+
//java_core_ver = "4.2.2"
102+
java_core_ver = "3.1.0-SNAPSHOT"
103+
99104
android_logger_ver = "1.3.6"
100105
jacksonversion= "2.11.2"
101106
annotations_ver = "1.2.0"

test-app/src/main/java/com/optimizely/ab/android/test_app/Samples/APISamplesInJava.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public class APISamplesInJava {
7474
static public void samplesAll(Context context) {
7575
samplesForCmab(context);
7676
samplesForCmabConfig(context);
77-
samplesForCmabConfig2(context);
77+
samplesForCmabConfig_endpoint(context);
7878

7979
samplesForDecide(context);
8080
samplesForInitialization(context);
@@ -176,10 +176,12 @@ static public void samplesForCmabConfig(Context context) {
176176

177177
// we use cmab test project=4552646833471488 datafile for this testing
178178

179+
CmabClient customCmabClient = new DefaultCmabClient(context);
179180
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
180181
.withSDKKey("4ft9p1vSXYM5hLATwWdRc")
181182
.withCmabCacheSize(50)
182183
.withCmabCacheTimeout(10, TimeUnit.SECONDS)
184+
.withCmabClient(customCmabClient)
183185
.build(context);
184186
// we use raw datafile for this testing
185187
OptimizelyClient optimizelyClient = optimizelyManager.initialize(context, R.raw.datafile_full);
@@ -217,19 +219,16 @@ static public void samplesForCmabConfig(Context context) {
217219
}
218220
}
219221

220-
static public void samplesForCmabConfig2(Context context) {
222+
static public void samplesForCmabConfig_endpoint(Context context) {
221223
List<OptimizelyDecideOption> options = Arrays.asList(
222224
OptimizelyDecideOption.INCLUDE_REASONS,
223225
OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE,
224226
OptimizelyDecideOption.IGNORE_CMAB_CACHE
225227
);
226228

227-
// custom CmabClient
228-
229-
CmabClientHelperAndroid cmabHelper = new CmabClientHelperAndroid();
230-
cmabHelper.setCmabPredictionEndpoint("https://prediction.cmab.optimizely.com/predict/%s");
231-
CmabClient customCmabClient = new DefaultCmabClient(context, cmabHelper);
229+
// custom Cmab Endpoint
232230

231+
CmabClient customCmabClient = new DefaultCmabClient(context);
233232
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
234233
.withSDKKey("4ft9p1vSXYM5hLATwWdRc")
235234
.withCmabClient(customCmabClient)

test-app/src/main/java/com/optimizely/ab/android/test_app/SplashScreenActivity.kt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,27 @@ class SplashScreenActivity : AppCompatActivity() {
4545
override fun onStart() {
4646
super.onStart()
4747

48-
val INITIALIZE_ASYNCHRONOUSLY = true
49-
50-
// with the new Android O differences, you need to register the service for the intent filter you desire in code instead of
51-
// in the manifest.
52-
val eventRescheduler = EventRescheduler()
53-
applicationContext.registerReceiver(eventRescheduler, IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
54-
55-
if (INITIALIZE_ASYNCHRONOUSLY) {
56-
optimizelyManager!!.initialize(this, R.raw.datafile) { _ ->
57-
addNotificationListeners()
58-
startVariation()
59-
}
60-
} else {
61-
optimizelyManager!!.initialize(this, R.raw.datafile)
62-
addNotificationListeners()
63-
startVariation()
64-
}
48+
APISamplesInJava.samplesForCmab(this)
49+
APISamplesInJava.samplesForCmabConfig(this)
50+
APISamplesInJava.samplesForCmabConfig_endpoint(this)
51+
52+
// val INITIALIZE_ASYNCHRONOUSLY = true
53+
//
54+
// // with the new Android O differences, you need to register the service for the intent filter you desire in code instead of
55+
// // in the manifest.
56+
// val eventRescheduler = EventRescheduler()
57+
// applicationContext.registerReceiver(eventRescheduler, IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
58+
//
59+
// if (INITIALIZE_ASYNCHRONOUSLY) {
60+
// optimizelyManager!!.initialize(this, R.raw.datafile) { _ ->
61+
// addNotificationListeners()
62+
// startVariation()
63+
// }
64+
// } else {
65+
// optimizelyManager!!.initialize(this, R.raw.datafile)
66+
// addNotificationListeners()
67+
// startVariation()
68+
// }
6569

6670
}
6771

0 commit comments

Comments
 (0)