Skip to content

Commit dc4afe8

Browse files
[FSSDK-10759] feat: make vuid optln (#78)
VUID optln implemented for flutter
1 parent 8598e93 commit dc4afe8

File tree

12 files changed

+91
-15
lines changed

12 files changed

+91
-15
lines changed

.github/workflows/flutter.yml

+25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ on:
55
branches: [ "master" ]
66
pull_request:
77
branches: [ "master" ]
8+
# workflow_dispatch:
9+
# inputs:
10+
# sdk_branch:
11+
# description: "Specify the SDK branch"
12+
# required: false
13+
# default: "master"
14+
# testapp_branch:
15+
# description: "Specify the test app branch"
16+
# required: false
17+
# default: "master"
818

919
jobs:
1020
unit_test_coverage:
@@ -36,6 +46,21 @@ jobs:
3646
repository: 'optimizely/travisci-tools'
3747
path: 'home/runner/travisci-tools'
3848
ref: 'master'
49+
# Set SDK Branch based on input or PR/Push
50+
# - name: Set SDK Branch and Test App Branch
51+
# run: |
52+
# # If manually triggered
53+
# if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
54+
# echo "SDK_BRANCH=${{ github.event.inputs.sdk_branch || 'master' }}" >> $GITHUB_ENV
55+
# echo "TESTAPP_BRANCH=${{ github.event.inputs.testapp_branch || 'master' }}" >> $GITHUB_ENV
56+
# # If triggered by PR
57+
# elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
58+
# echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV
59+
# # If triggered by push
60+
# else
61+
# echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
62+
# echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
63+
# fi
3964
- name: set SDK Branch if PR
4065
env:
4166
HEAD_REF: ${{ github.head_ref }}

android/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ dependencies {
7474
implementation 'org.slf4j:slf4j-api:2.0.7'
7575

7676
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
77-
implementation "com.optimizely.ab:android-sdk:4.0.0"
77+
implementation "com.optimizely.ab:android-sdk:5.0.0"
7878
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
7979
implementation ('com.google.guava:guava:19.0') {
8080
exclude group:'com.google.guava', module:'listenablefuture'

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*;
5757
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.DISABLE_ODP;
58+
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.ENABLE_VUID;
5859
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_SIZE;
5960
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_TIMEOUT_IN_SECONDS;
6061
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.TIMEOUT_FOR_ODP_EVENT_IN_SECONDS;
@@ -144,6 +145,7 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
144145
int timeoutForSegmentFetchInSecs = 10;
145146
int timeoutForOdpEventInSecs = 10;
146147
boolean disableOdp = false;
148+
boolean enableVuid = false;
147149
Map<String, Object> sdkSettings = argumentsParser.getOptimizelySdkSettings();
148150
if (sdkSettings != null) {
149151
if (sdkSettings.containsKey(SEGMENTS_CACHE_SIZE)) {
@@ -161,6 +163,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
161163
if (sdkSettings.containsKey(DISABLE_ODP)) {
162164
disableOdp = (boolean) sdkSettings.get(DISABLE_ODP);
163165
}
166+
if (sdkSettings.containsKey(ENABLE_VUID)) {
167+
enableVuid = (boolean) sdkSettings.get(ENABLE_VUID);
168+
}
164169
}
165170
// Creating new instance
166171
OptimizelyManager.Builder optimizelyManagerBuilder = OptimizelyManager.builder()
@@ -179,6 +184,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
179184
if (disableOdp) {
180185
optimizelyManagerBuilder.withODPDisabled();
181186
}
187+
if (enableVuid) {
188+
optimizelyManagerBuilder.withVuidEnabled();
189+
}
182190
OptimizelyManager optimizelyManager = optimizelyManagerBuilder.build(context);
183191

184192
optimizelyManager.initialize(context, null, (OptimizelyClient client) -> {
@@ -471,7 +479,7 @@ protected void getVuid(ArgumentsParser argumentsParser, @NonNull Result result)
471479
if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) {
472480
return;
473481
}
474-
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), ""));
482+
result.success(createResponse(optimizelyClient.getVuid() != null, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), ""));
475483
}
476484

477485
/// Checks if the user is qualified for the given segment.

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public static class RequestParameterKey {
9696
public static final String TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS = "timeoutForSegmentFetchInSecs";
9797
public static final String TIMEOUT_FOR_ODP_EVENT_IN_SECONDS = "timeoutForOdpEventInSecs";
9898
public static final String DISABLE_ODP = "disableOdp";
99+
public static final String ENABLE_VUID = "enableVuid";
99100
}
100101

101102
public static class ErrorMessage {

ios/Classes/HelperClasses/Constants.swift

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct RequestParameterKey {
114114
static let timeoutForSegmentFetchInSecs = "timeoutForSegmentFetchInSecs"
115115
static let timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs"
116116
static let disableOdp = "disableOdp"
117+
static let enableVuid = "enableVuid"
117118
static let sdkVersion = "sdkVersion";
118119
}
119120

ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift

+7-3
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
118118
var timeoutForSegmentFetchInSecs: Int = 10
119119
var timeoutForOdpEventInSecs: Int = 10
120120
var disableOdp: Bool = false
121+
var enableVuid: Bool = false
121122
var sdkVersion = parameters[RequestParameterKey.sdkVersion] as? String
122123
var sdkName = Utils.sdkName
123124

@@ -137,8 +138,11 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
137138
if let isOdpDisabled = sdkSettings[RequestParameterKey.disableOdp] as? Bool {
138139
disableOdp = isOdpDisabled
139140
}
141+
if let isEnableVuid = sdkSettings[RequestParameterKey.enableVuid] as? Bool {
142+
enableVuid = isEnableVuid
143+
}
140144
}
141-
let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, sdkName: sdkName, sdkVersion: sdkVersion)
145+
let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, enableVuid: enableVuid, sdkName: sdkName, sdkVersion: sdkVersion)
142146

143147
// Datafile Download Interval
144148
var datafilePeriodicDownloadInterval = 10 * 60 // seconds
@@ -374,7 +378,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
374378
} else {
375379
userContextsTracker[sdkKey] = [userContextId: userContext]
376380
}
377-
result(self.createResponse(success: true, result: [RequestParameterKey.userContextId: userContextId]))
381+
result(self.createResponse(success: userContext != nil, result: [RequestParameterKey.userContextId: userContextId]))
378382
}
379383

380384
/// Returns userId for the user context.
@@ -442,7 +446,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
442446
guard let optimizelyClient = getOptimizelyClient(sdkKey: sdkKey, result: result) else {
443447
return
444448
}
445-
result(self.createResponse(success: true, result: [RequestParameterKey.vuid: optimizelyClient.vuid]))
449+
result(self.createResponse(success: optimizelyClient.vuid != nil, result: [RequestParameterKey.vuid: optimizelyClient.vuid]))
446450
}
447451

448452
/// Checks if the user is qualified for the given segment.

ios/optimizely_flutter_sdk.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.source = { :path => '.' }
1414
s.source_files = 'Classes/**/*'
1515
s.dependency 'Flutter'
16-
s.dependency 'OptimizelySwiftSDK', '4.0.0'
16+
s.dependency 'OptimizelySwiftSDK', '5.0.0'
1717
s.platform = :ios, '10.0'
1818
# Flutter.framework does not contain a i386 slice.
1919
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }

lib/src/data_objects/get_vuid_response.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
1818
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
1919

2020
class GetVuidResponse extends BaseResponse {
21-
String vuid = "";
21+
String? vuid;
2222

2323
GetVuidResponse(Map<String, dynamic> json) : super(json) {
2424
if (json[Constants.responseResult] is Map<dynamic, dynamic>) {

lib/src/data_objects/sdk_settings.dart

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class SDKSettings {
2525
final int timeoutForOdpEventInSecs;
2626
// Set this flag to true (default = false) to disable ODP features
2727
final bool disableOdp;
28+
// Set this flag to true (default = false) to enable VUID feature
29+
final bool enableVuid;
2830

2931
const SDKSettings({
3032
this.segmentsCacheSize = 100, // Default segmentsCacheSize
@@ -33,5 +35,6 @@ class SDKSettings {
3335
10, // Default timeoutForSegmentFetchInSecs
3436
this.timeoutForOdpEventInSecs = 10, // Default timeoutForOdpEventInSecs
3537
this.disableOdp = false, // Default disableOdp
38+
this.enableVuid = false, // Default disableVuid
3639
});
3740
}

lib/src/optimizely_client_wrapper.dart

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class OptimizelyClientWrapper {
9090
sdkSettings.timeoutForSegmentFetchInSecs,
9191
Constants.timeoutForOdpEventInSecs: sdkSettings.timeoutForOdpEventInSecs,
9292
Constants.disableOdp: sdkSettings.disableOdp,
93+
Constants.enableVuid: sdkSettings.enableVuid,
9394
};
9495
requestDict[Constants.optimizelySdkSettings] = optimizelySdkSettings;
9596

lib/src/utils/constants.dart

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class Constants {
131131
"timeoutForSegmentFetchInSecs";
132132
static const String timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs";
133133
static const String disableOdp = "disableOdp";
134+
static const String enableVuid = "enableVuid";
134135

135136
// Response keys
136137
static const String responseSuccess = "success";

test/optimizely_flutter_sdk_test.dart

+40-8
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ void main() {
5656
SDKSettings sdkSettings = const SDKSettings();
5757
int datafilePeriodicDownloadInterval = 0;
5858
String defaultLogLevel = "error";
59-
6059
const MethodChannel channel = MethodChannel("optimizely_flutter_sdk");
6160
dynamic mockOptimizelyConfig;
6261

@@ -106,6 +105,7 @@ void main() {
106105
timeoutForOdpEventInSecs:
107106
settings[Constants.timeoutForOdpEventInSecs],
108107
disableOdp: settings[Constants.disableOdp],
108+
enableVuid: settings[Constants.enableVuid],
109109
);
110110
}
111111

@@ -175,17 +175,27 @@ void main() {
175175
};
176176
case Constants.createUserContextMethod:
177177
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
178-
if (methodCall.arguments[Constants.userId] != null) {
178+
var resultUserId = userContextId;
179+
if (methodCall.arguments[Constants.userId] == null) {
180+
if (sdkSettings.enableVuid) {
181+
resultUserId = vuid;
182+
} else {
183+
return {
184+
Constants.responseSuccess: false,
185+
};
186+
}
187+
} else if (methodCall.arguments[Constants.userId] != null) {
179188
expect(methodCall.arguments[Constants.userId], equals(userId));
180189
}
190+
181191
if (methodCall.arguments[Constants.attributes]["abc"] != null) {
182192
expect(methodCall.arguments[Constants.attributes]["abc"],
183193
equals(attributes["abc"]));
184194
}
185195
expect(methodCall.arguments[Constants.userContextId], isNull);
186196
return {
187197
Constants.responseSuccess: true,
188-
Constants.responseResult: {Constants.userContextId: userContextId},
198+
Constants.responseResult: {Constants.userContextId: resultUserId},
189199
};
190200
case Constants.getUserIdMethod:
191201
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
@@ -266,6 +276,8 @@ void main() {
266276
case Constants.getVuidMethod:
267277
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
268278
expect(methodCall.arguments[Constants.userContextId], isNull);
279+
expect(methodCall.arguments[Constants.vuid], isNull);
280+
var vuid = sdkSettings.enableVuid ? "vuid_123" : null;
269281
return {
270282
Constants.responseSuccess: true,
271283
Constants.responseResult: {Constants.vuid: vuid},
@@ -376,6 +388,7 @@ void main() {
376388

377389
tearDown(() {
378390
tester?.setMockMethodCallHandler(channel, null);
391+
sdkSettings = const SDKSettings();
379392
});
380393

381394
group("Integration: OptimizelyFlutterSdk MethodChannel", () {
@@ -650,8 +663,17 @@ void main() {
650663
expect(userContext, isNotNull);
651664
});
652665

653-
test("should succeed null userId", () async {
666+
test("should fail when disable vuid and userId null", () async {
654667
var sdk = OptimizelyFlutterSdk(testSDKKey);
668+
sdk.initializeClient();
669+
var userContext = await sdk.createUserContext(attributes: attributes);
670+
expect(userContext, isNull);
671+
});
672+
673+
test("should succed when enable vuid and userId null", () async {
674+
const settings = SDKSettings(enableVuid: true);
675+
var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings);
676+
sdk.initializeClient();
655677
var userContext = await sdk.createUserContext(attributes: attributes);
656678
expect(userContext, isNotNull);
657679
});
@@ -662,10 +684,11 @@ void main() {
662684
expect(userContext, isNotNull);
663685
});
664686

665-
test("should succeed null userId and attributes", () async {
687+
test("should not succeed null userId and attributes", () async {
666688
var sdk = OptimizelyFlutterSdk(testSDKKey);
689+
sdk.initializeClient();
667690
var userContext = await sdk.createUserContext();
668-
expect(userContext, isNotNull);
691+
expect(userContext, isNull);
669692
});
670693
});
671694

@@ -769,11 +792,20 @@ void main() {
769792
});
770793

771794
group("getVuid()", () {
772-
test("should succeed", () async {
795+
test("by default should return null vuid", () async {
773796
var sdk = OptimizelyFlutterSdk(testSDKKey);
797+
sdk.initializeClient();
798+
var response = await sdk.getVuid();
799+
expect(response.success, isTrue);
800+
expect(response.vuid, isNull);
801+
});
802+
test("should return vuid when enableVuid true", () async {
803+
const settings = SDKSettings(enableVuid: true);
804+
var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings);
805+
sdk.initializeClient();
774806
var response = await sdk.getVuid();
775807
expect(response.success, isTrue);
776-
expect(response.vuid, equals(vuid));
808+
expect(response.vuid, "vuid_123");
777809
});
778810
});
779811

0 commit comments

Comments
 (0)