Skip to content
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
23 changes: 23 additions & 0 deletions core-api/src/main/java/com/optimizely/ab/Optimizely.java
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,29 @@ else if (userId == null) {
return variableValue;
}

/**
* Get the list of features that are enabled for the user.
* @param userId The ID of the user.
* @param attributes The user's attributes.
* @return List of the feature keys that are enabled for the user if the userId is empty it will
* return Empty List.
*/
public List<String> getEnabledFeatures(@Nonnull String userId,@Nonnull Map<String, String> attributes) {
List<String> enabledFeaturesList = new ArrayList<String>();

if (!validateUserId(userId)){
return enabledFeaturesList;
}

for (FeatureFlag featureFlag : projectConfig.getFeatureFlags()){
String featureKey = featureFlag.getKey();
if(isFeatureEnabled(featureKey, userId, attributes))
enabledFeaturesList.add(featureKey);
}

return enabledFeaturesList;
}

//======== getVariation calls ========//

public @Nullable
Expand Down
63 changes: 63 additions & 0 deletions core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3615,6 +3615,69 @@ public void isFeatureEnabledReturnsTrueAndDispatchesEventWhenUserIsBucketedIntoA
verify(mockEventHandler, times(1)).dispatchEvent(any(LogEvent.class));
}

/**
* Verify {@link Optimizely#getEnabledFeatures(String, Map)} calls into
* {@link Optimizely#isFeatureEnabled(String, String, Map)} for each featureFlag
* return List of FeatureFlags that are enabled
*/
@Test
public void getEnabledFeatureWithValidUserId() throws ConfigParseException{
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));

Optimizely spyOptimizely = spy(Optimizely.builder(validDatafile, mockEventHandler)
.withConfig(validProjectConfig)
.build());
ArrayList<String> featureFlags = (ArrayList<String>) spyOptimizely.getEnabledFeatures(genericUserId,
new HashMap<String, String>());
assertFalse(featureFlags.isEmpty());

}


/**
* Verify {@link Optimizely#getEnabledFeatures(String, Map)} calls into
* {@link Optimizely#isFeatureEnabled(String, String, Map)} for each featureFlag sending
* userId as empty string
* return empty List of FeatureFlags without checking further.
*/
@Test
public void getEnabledFeatureWithEmptyUserId() throws ConfigParseException{
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));

Optimizely spyOptimizely = spy(Optimizely.builder(validDatafile, mockEventHandler)
.withConfig(validProjectConfig)
.build());
ArrayList<String> featureFlags = (ArrayList<String>) spyOptimizely.getEnabledFeatures("",
new HashMap<String, String>());
logbackVerifier.expectMessage(Level.ERROR, "Non-empty user ID required");
assertTrue(featureFlags.isEmpty());

}

/**
* Verify {@link Optimizely#getEnabledFeatures(String, Map)} calls into
* {@link Optimizely#isFeatureEnabled(String, String, Map)} for each featureFlag sending
* userId and emptyMap and Mocked {@link Optimizely#isFeatureEnabled(String, String, Map)}
* to return false so {@link Optimizely#getEnabledFeatures(String, Map)} will
* return empty List of FeatureFlags.
*/
@Test
public void getEnabledFeatureWithMockIsFeatureEnabledToReturnFalse() throws ConfigParseException{
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));

Optimizely spyOptimizely = spy(Optimizely.builder(validDatafile, mockEventHandler)
.withConfig(validProjectConfig)
.build());
doReturn(false).when(spyOptimizely).isFeatureEnabled(
any(String.class),
eq(genericUserId),
eq(Collections.<String, String>emptyMap())
);
ArrayList<String> featureFlags = (ArrayList<String>) spyOptimizely.getEnabledFeatures(genericUserId,
Collections.<String, String>emptyMap());
assertTrue(featureFlags.isEmpty());
}

/**
* Verify {@link Optimizely#getFeatureVariableString(String, String, String)}
* calls through to {@link Optimizely#getFeatureVariableString(String, String, String, Map)}
Expand Down