Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FSSDK-10759] feat: make vuid optln #78

Merged
merged 9 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/flutter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ on:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
# workflow_dispatch:
# inputs:
# sdk_branch:
# description: "Specify the SDK branch"
# required: false
# default: "master"
# testapp_branch:
# description: "Specify the test app branch"
# required: false
# default: "master"

jobs:
unit_test_coverage:
Expand Down Expand Up @@ -36,6 +46,21 @@ jobs:
repository: 'optimizely/travisci-tools'
path: 'home/runner/travisci-tools'
ref: 'master'
# Set SDK Branch based on input or PR/Push
# - name: Set SDK Branch and Test App Branch
# run: |
# # If manually triggered
# if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# echo "SDK_BRANCH=${{ github.event.inputs.sdk_branch || 'master' }}" >> $GITHUB_ENV
# echo "TESTAPP_BRANCH=${{ github.event.inputs.testapp_branch || 'master' }}" >> $GITHUB_ENV
# # If triggered by PR
# elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
# echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV
# # If triggered by push
# else
# echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
# echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
# fi
- name: set SDK Branch if PR
env:
HEAD_REF: ${{ github.head_ref }}
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ dependencies {
implementation 'org.slf4j:slf4j-api:2.0.7'

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
implementation "com.optimizely.ab:android-sdk:4.0.0"
implementation "com.optimizely.ab:android-sdk:5.0.0"
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
implementation ('com.google.guava:guava:19.0') {
exclude group:'com.google.guava', module:'listenablefuture'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*;
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.DISABLE_ODP;
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.ENABLE_VUID;
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_SIZE;
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_TIMEOUT_IN_SECONDS;
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.TIMEOUT_FOR_ODP_EVENT_IN_SECONDS;
Expand Down Expand Up @@ -144,6 +145,7 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
int timeoutForSegmentFetchInSecs = 10;
int timeoutForOdpEventInSecs = 10;
boolean disableOdp = false;
boolean enableVuid = false;
Map<String, Object> sdkSettings = argumentsParser.getOptimizelySdkSettings();
if (sdkSettings != null) {
if (sdkSettings.containsKey(SEGMENTS_CACHE_SIZE)) {
Expand All @@ -161,6 +163,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
if (sdkSettings.containsKey(DISABLE_ODP)) {
disableOdp = (boolean) sdkSettings.get(DISABLE_ODP);
}
if (sdkSettings.containsKey(ENABLE_VUID)) {
enableVuid = (boolean) sdkSettings.get(ENABLE_VUID);
}
}
// Creating new instance
OptimizelyManager.Builder optimizelyManagerBuilder = OptimizelyManager.builder()
Expand All @@ -179,6 +184,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
if (disableOdp) {
optimizelyManagerBuilder.withODPDisabled();
}
if (enableVuid) {
optimizelyManagerBuilder.withVuidEnabled();
}
OptimizelyManager optimizelyManager = optimizelyManagerBuilder.build(context);

optimizelyManager.initialize(context, null, (OptimizelyClient client) -> {
Expand Down Expand Up @@ -471,7 +479,7 @@ protected void getVuid(ArgumentsParser argumentsParser, @NonNull Result result)
if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) {
return;
}
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), ""));
result.success(createResponse(optimizelyClient.getVuid() != null, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), ""));
}

/// Checks if the user is qualified for the given segment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public static class RequestParameterKey {
public static final String TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS = "timeoutForSegmentFetchInSecs";
public static final String TIMEOUT_FOR_ODP_EVENT_IN_SECONDS = "timeoutForOdpEventInSecs";
public static final String DISABLE_ODP = "disableOdp";
public static final String ENABLE_VUID = "enableVuid";
}

public static class ErrorMessage {
Expand Down
1 change: 1 addition & 0 deletions ios/Classes/HelperClasses/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct RequestParameterKey {
static let timeoutForSegmentFetchInSecs = "timeoutForSegmentFetchInSecs"
static let timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs"
static let disableOdp = "disableOdp"
static let enableVuid = "enableVuid"
static let sdkVersion = "sdkVersion";
}

Expand Down
10 changes: 7 additions & 3 deletions ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
var timeoutForSegmentFetchInSecs: Int = 10
var timeoutForOdpEventInSecs: Int = 10
var disableOdp: Bool = false
var enableVuid: Bool = false
var sdkVersion = parameters[RequestParameterKey.sdkVersion] as? String
var sdkName = Utils.sdkName

Expand All @@ -137,8 +138,11 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
if let isOdpDisabled = sdkSettings[RequestParameterKey.disableOdp] as? Bool {
disableOdp = isOdpDisabled
}
if let isEnableVuid = sdkSettings[RequestParameterKey.enableVuid] as? Bool {
enableVuid = isEnableVuid
}
}
let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, sdkName: sdkName, sdkVersion: sdkVersion)
let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, enableVuid: enableVuid, sdkName: sdkName, sdkVersion: sdkVersion)

// Datafile Download Interval
var datafilePeriodicDownloadInterval = 10 * 60 // seconds
Expand Down Expand Up @@ -374,7 +378,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
} else {
userContextsTracker[sdkKey] = [userContextId: userContext]
}
result(self.createResponse(success: true, result: [RequestParameterKey.userContextId: userContextId]))
result(self.createResponse(success: userContext != nil, result: [RequestParameterKey.userContextId: userContextId]))
}

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

/// Checks if the user is qualified for the given segment.
Expand Down
2 changes: 1 addition & 1 deletion ios/optimizely_flutter_sdk.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.dependency 'OptimizelySwiftSDK', '4.0.0'
s.dependency 'OptimizelySwiftSDK', '5.0.0'
s.platform = :ios, '10.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
Expand Down
2 changes: 1 addition & 1 deletion lib/src/data_objects/get_vuid_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';

class GetVuidResponse extends BaseResponse {
String vuid = "";
String? vuid;

GetVuidResponse(Map<String, dynamic> json) : super(json) {
if (json[Constants.responseResult] is Map<dynamic, dynamic>) {
Expand Down
3 changes: 3 additions & 0 deletions lib/src/data_objects/sdk_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class SDKSettings {
final int timeoutForOdpEventInSecs;
// Set this flag to true (default = false) to disable ODP features
final bool disableOdp;
// Set this flag to true (default = false) to enable VUID feature
final bool enableVuid;

const SDKSettings({
this.segmentsCacheSize = 100, // Default segmentsCacheSize
Expand All @@ -33,5 +35,6 @@ class SDKSettings {
10, // Default timeoutForSegmentFetchInSecs
this.timeoutForOdpEventInSecs = 10, // Default timeoutForOdpEventInSecs
this.disableOdp = false, // Default disableOdp
this.enableVuid = false, // Default disableVuid
});
}
1 change: 1 addition & 0 deletions lib/src/optimizely_client_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class OptimizelyClientWrapper {
sdkSettings.timeoutForSegmentFetchInSecs,
Constants.timeoutForOdpEventInSecs: sdkSettings.timeoutForOdpEventInSecs,
Constants.disableOdp: sdkSettings.disableOdp,
Constants.enableVuid: sdkSettings.enableVuid,
};
requestDict[Constants.optimizelySdkSettings] = optimizelySdkSettings;

Expand Down
1 change: 1 addition & 0 deletions lib/src/utils/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class Constants {
"timeoutForSegmentFetchInSecs";
static const String timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs";
static const String disableOdp = "disableOdp";
static const String enableVuid = "enableVuid";

// Response keys
static const String responseSuccess = "success";
Expand Down
48 changes: 40 additions & 8 deletions test/optimizely_flutter_sdk_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ void main() {
SDKSettings sdkSettings = const SDKSettings();
int datafilePeriodicDownloadInterval = 0;
String defaultLogLevel = "error";

const MethodChannel channel = MethodChannel("optimizely_flutter_sdk");
dynamic mockOptimizelyConfig;

Expand Down Expand Up @@ -106,6 +105,7 @@ void main() {
timeoutForOdpEventInSecs:
settings[Constants.timeoutForOdpEventInSecs],
disableOdp: settings[Constants.disableOdp],
enableVuid: settings[Constants.enableVuid],
);
}

Expand Down Expand Up @@ -175,17 +175,27 @@ void main() {
};
case Constants.createUserContextMethod:
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
if (methodCall.arguments[Constants.userId] != null) {
var resultUserId = userContextId;
if (methodCall.arguments[Constants.userId] == null) {
if (sdkSettings.enableVuid) {
resultUserId = vuid;
} else {
return {
Constants.responseSuccess: false,
};
}
} else if (methodCall.arguments[Constants.userId] != null) {
expect(methodCall.arguments[Constants.userId], equals(userId));
}

if (methodCall.arguments[Constants.attributes]["abc"] != null) {
expect(methodCall.arguments[Constants.attributes]["abc"],
equals(attributes["abc"]));
}
expect(methodCall.arguments[Constants.userContextId], isNull);
return {
Constants.responseSuccess: true,
Constants.responseResult: {Constants.userContextId: userContextId},
Constants.responseResult: {Constants.userContextId: resultUserId},
};
case Constants.getUserIdMethod:
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
Expand Down Expand Up @@ -266,6 +276,8 @@ void main() {
case Constants.getVuidMethod:
expect(methodCall.arguments[Constants.sdkKey], isNotEmpty);
expect(methodCall.arguments[Constants.userContextId], isNull);
expect(methodCall.arguments[Constants.vuid], isNull);
var vuid = sdkSettings.enableVuid ? "vuid_123" : null;
return {
Constants.responseSuccess: true,
Constants.responseResult: {Constants.vuid: vuid},
Expand Down Expand Up @@ -376,6 +388,7 @@ void main() {

tearDown(() {
tester?.setMockMethodCallHandler(channel, null);
sdkSettings = const SDKSettings();
});

group("Integration: OptimizelyFlutterSdk MethodChannel", () {
Expand Down Expand Up @@ -650,8 +663,17 @@ void main() {
expect(userContext, isNotNull);
});

test("should succeed null userId", () async {
test("should fail when disable vuid and userId null", () async {
var sdk = OptimizelyFlutterSdk(testSDKKey);
sdk.initializeClient();
var userContext = await sdk.createUserContext(attributes: attributes);
expect(userContext, isNull);
});

test("should succed when enable vuid and userId null", () async {
const settings = SDKSettings(enableVuid: true);
var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings);
sdk.initializeClient();
var userContext = await sdk.createUserContext(attributes: attributes);
expect(userContext, isNotNull);
});
Expand All @@ -662,10 +684,11 @@ void main() {
expect(userContext, isNotNull);
});

test("should succeed null userId and attributes", () async {
test("should not succeed null userId and attributes", () async {
var sdk = OptimizelyFlutterSdk(testSDKKey);
sdk.initializeClient();
var userContext = await sdk.createUserContext();
expect(userContext, isNotNull);
expect(userContext, isNull);
});
});

Expand Down Expand Up @@ -769,11 +792,20 @@ void main() {
});

group("getVuid()", () {
test("should succeed", () async {
test("by default should return null vuid", () async {
var sdk = OptimizelyFlutterSdk(testSDKKey);
sdk.initializeClient();
var response = await sdk.getVuid();
expect(response.success, isTrue);
expect(response.vuid, isNull);
});
test("should return vuid when enableVuid true", () async {
const settings = SDKSettings(enableVuid: true);
var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings);
sdk.initializeClient();
var response = await sdk.getVuid();
expect(response.success, isTrue);
expect(response.vuid, equals(vuid));
expect(response.vuid, "vuid_123");
});
});

Expand Down