Skip to content

Commit dfdcf2a

Browse files
mnoman09aliabbasrizvi
authored andcommitted
feat(api): Feature variable APIs now return default variable value when featureEnabled property is false. (#276)
1 parent c57b0eb commit dfdcf2a

File tree

3 files changed

+174
-10
lines changed

3 files changed

+174
-10
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ after_success:
2828
- ./gradlew coveralls uploadArchives --console plain
2929
after_failure:
3030
- cat /home/travis/build/optimizely/java-sdk/core-api/build/reports/findbugs/main.html
31+
- cat /home/travis/build/optimizely/java-sdk/core-api/build/reports/findbugs/test.html
3132

3233
# Integration tests need to run first to reset the PR build status to pending
3334
stages:

core-api/src/main/java/com/optimizely/ab/Optimizely.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,12 +650,19 @@ String getFeatureVariableValueForType(@Nonnull String featureKey,
650650
Map<String, ?> copiedAttributes = copyAttributes(attributes);
651651
FeatureDecision featureDecision = decisionService.getVariationForFeature(featureFlag, userId, copiedAttributes);
652652
if (featureDecision.variation != null) {
653-
FeatureVariableUsageInstance featureVariableUsageInstance =
654-
featureDecision.variation.getVariableIdToFeatureVariableUsageInstanceMap().get(variable.getId());
655-
if (featureVariableUsageInstance != null) {
656-
variableValue = featureVariableUsageInstance.getValue();
653+
if (featureDecision.variation.getFeatureEnabled()) {
654+
FeatureVariableUsageInstance featureVariableUsageInstance =
655+
featureDecision.variation.getVariableIdToFeatureVariableUsageInstanceMap().get(variable.getId());
656+
if (featureVariableUsageInstance != null) {
657+
variableValue = featureVariableUsageInstance.getValue();
658+
} else {
659+
variableValue = variable.getDefaultValue();
660+
}
657661
} else {
658-
variableValue = variable.getDefaultValue();
662+
logger.info("Feature \"{}\" for variation \"{}\" was not enabled. " +
663+
"The default value is being returned.",
664+
featureKey, featureDecision.variation.getKey(), variableValue, variableKey
665+
);
659666
}
660667
} else {
661668
logger.info("User \"{}\" was not bucketed into any variation for feature flag \"{}\". " +

core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java

Lines changed: 161 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,19 +3348,18 @@ public void getFeatureVariableValueReturnsDefaultValueWhenFeatureIsAttachedToOne
33483348

33493349
/**
33503350
* Verify {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}
3351-
* returns the variable value of the variation the user is bucketed into
3352-
* if the variation is not null and the variable has a usage within the variation.
3351+
* is called when the variation is not null and feature enabled is false
3352+
* returns the default variable value
33533353
*
33543354
* @throws ConfigParseException
33553355
*/
33563356
@Test
3357-
public void getFeatureVariableValueReturnsVariationValueWhenUserGetsBucketedToVariation() throws ConfigParseException {
3357+
public void getFeatureVariableValueReturnsDefaultValueWhenFeatureEnabledIsFalse() throws ConfigParseException {
33583358
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
33593359

33603360
String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
33613361
String validVariableKey = VARIABLE_FIRST_LETTER_KEY;
3362-
FeatureVariable variable = FEATURE_FLAG_MULTI_VARIATE_FEATURE.getVariableKeyToFeatureVariableMap().get(validVariableKey);
3363-
String expectedValue = VARIATION_MULTIVARIATE_EXPERIMENT_GRED.getVariableIdToFeatureVariableUsageInstanceMap().get(variable.getId()).getValue();
3362+
String expectedValue = VARIABLE_FIRST_LETTER_DEFAULT_VALUE;
33643363
Experiment multivariateExperiment = validProjectConfig.getExperimentKeyMapping().get(EXPERIMENT_MULTIVARIATE_EXPERIMENT_KEY);
33653364

33663365
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
@@ -3383,9 +3382,166 @@ public void getFeatureVariableValueReturnsVariationValueWhenUserGetsBucketedToVa
33833382
FeatureVariable.VariableType.STRING
33843383
);
33853384

3385+
logbackVerifier.expectMessage(
3386+
Level.INFO,
3387+
"Feature \"" + validFeatureKey + "\" for variation \"Gred\" was not enabled. " +
3388+
"The default value is being returned."
3389+
);
3390+
33863391
assertEquals(expectedValue, value);
33873392
}
33883393

3394+
/**
3395+
* Verify that the {@link Optimizely#getFeatureVariableString(String, String, String, Map)}
3396+
* is called when feature is in experiment and feature enabled is true
3397+
* returns variable value
3398+
*/
3399+
@Test
3400+
public void getFeatureVariableUserInExperimentFeatureOn() throws Exception {
3401+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3402+
3403+
final String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
3404+
String validVariableKey = VARIABLE_FIRST_LETTER_KEY;
3405+
String expectedValue = "F";
3406+
3407+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3408+
.withConfig(validProjectConfig)
3409+
.build();
3410+
3411+
assertEquals(optimizely.getFeatureVariableString(
3412+
validFeatureKey,
3413+
validVariableKey,
3414+
testUserId,
3415+
Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE)),
3416+
expectedValue);
3417+
}
3418+
3419+
/**
3420+
* Verify that the {@link Optimizely#getFeatureVariableString(String, String, String, Map)}
3421+
* is called when feature is in experiment and feature enabled is false
3422+
* than default value will gets returned
3423+
*/
3424+
@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION")
3425+
@Test
3426+
public void getFeatureVariableWithListenerUserInExperimentFeatureOff() {
3427+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3428+
3429+
final String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
3430+
String validVariableKey = VARIABLE_FIRST_LETTER_KEY;
3431+
String expectedValue = "H";
3432+
String userID = "Gred";
3433+
3434+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3435+
.withConfig(validProjectConfig)
3436+
.build();
3437+
3438+
assertEquals(optimizely.getFeatureVariableString(
3439+
validFeatureKey,
3440+
validVariableKey,
3441+
userID,
3442+
null),
3443+
expectedValue);
3444+
}
3445+
3446+
/**
3447+
* Verify that the {@link Optimizely#getFeatureVariableString(String, String, String, Map)}
3448+
* is called when feature is in rollout and feature enabled is true
3449+
* returns variable value
3450+
*/
3451+
@Test
3452+
public void getFeatureVariableUserInRollOutFeatureOn() throws Exception {
3453+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3454+
3455+
final String validFeatureKey = FEATURE_SINGLE_VARIABLE_STRING_KEY;
3456+
String validVariableKey = VARIABLE_STRING_VARIABLE_KEY;
3457+
String expectedValue = "lumos";
3458+
3459+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3460+
.withConfig(validProjectConfig)
3461+
.build();
3462+
3463+
assertEquals(optimizely.getFeatureVariableString(
3464+
validFeatureKey,
3465+
validVariableKey,
3466+
genericUserId,
3467+
Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE)),
3468+
expectedValue);
3469+
}
3470+
3471+
/**
3472+
* Verify that the {@link Optimizely#getFeatureVariableBoolean(String, String, String, Map)}
3473+
* is called when feature is not in rollout and feature enabled is false
3474+
* returns default value
3475+
*/
3476+
@Test
3477+
public void getFeatureVariableUserNotInRollOutFeatureOff() {
3478+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3479+
3480+
final String validFeatureKey = FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY;
3481+
String validVariableKey = VARIABLE_BOOLEAN_VARIABLE_KEY;
3482+
Boolean expectedValue = true;
3483+
3484+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3485+
.withConfig(validProjectConfig)
3486+
.build();
3487+
3488+
assertEquals(optimizely.getFeatureVariableBoolean(
3489+
validFeatureKey,
3490+
validVariableKey,
3491+
genericUserId,
3492+
Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE)),
3493+
expectedValue);
3494+
}
3495+
3496+
/**
3497+
* Verify that the {@link Optimizely#getFeatureVariableInteger(String, String, String, Map)}
3498+
* is called when feature is in rollout and feature enabled is true
3499+
* return rollout variable value
3500+
*/
3501+
@Test
3502+
public void getFeatureVariableIntegerUserInRollOutFeatureOn() {
3503+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3504+
3505+
final String validFeatureKey = FEATURE_SINGLE_VARIABLE_INTEGER_KEY;
3506+
String validVariableKey = VARIABLE_INTEGER_VARIABLE_KEY;
3507+
int expectedValue = 7;
3508+
3509+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3510+
.withConfig(validProjectConfig)
3511+
.build();
3512+
3513+
assertEquals((long) optimizely.getFeatureVariableInteger(
3514+
validFeatureKey,
3515+
validVariableKey,
3516+
genericUserId,
3517+
Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE)),
3518+
(long) expectedValue);
3519+
}
3520+
3521+
/**
3522+
* Verify that the {@link Optimizely#getFeatureVariableDouble(String, String, String, Map)}
3523+
* is called when feature is in experiment and feature enabled is true
3524+
* returns variable value
3525+
*/
3526+
@Test
3527+
public void getFeatureVariableDoubleUserInExperimentFeatureOn() throws Exception {
3528+
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
3529+
3530+
final String validFeatureKey = FEATURE_SINGLE_VARIABLE_DOUBLE_KEY;
3531+
String validVariableKey = VARIABLE_DOUBLE_VARIABLE_KEY;
3532+
3533+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
3534+
.withConfig(validProjectConfig)
3535+
.build();
3536+
3537+
assertEquals(optimizely.getFeatureVariableDouble(
3538+
validFeatureKey,
3539+
validVariableKey,
3540+
genericUserId,
3541+
Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_SLYTHERIN_VALUE)),
3542+
Math.PI, 2);
3543+
}
3544+
33893545
/**
33903546
* Verify {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}
33913547
* returns the default value for the feature variable

0 commit comments

Comments
 (0)