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
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,17 @@ static void setCustomValue(Map<String, Object> customData, String key, Value val
*
* @param ctx A context to load a targeting key and user data from
* @return An initialized DevCycleUser with data from the context
* @throws TargetingKeyMissingError if the targeting key or user_id attribute is not set
* @throws TargetingKeyMissingError if none of the targeting key, user_id, or userId attributes are set or valid
*/
public static DevCycleUser fromEvaluationContext(EvaluationContext ctx) {
String userId = "";

if (ctx != null && ctx.getTargetingKey() != null && !ctx.getTargetingKey().isEmpty()) {
userId = ctx.getTargetingKey();
} else if (ctx != null && ctx.getValue("user_id") != null) {
} else if (ctx != null && ctx.getValue("user_id") != null && ctx.getValue("user_id").isString()) {
userId = ctx.getValue("user_id").asString();
} else if (ctx != null && ctx.getValue("userId") != null && ctx.getValue("userId").isString()) {
userId = ctx.getValue("userId").asString();
}

if (userId == null || userId.isEmpty()) {
Expand All @@ -160,7 +162,7 @@ public static DevCycleUser fromEvaluationContext(EvaluationContext ctx) {
Map<String, Object> privateCustomData = new LinkedHashMap<>();

for (String key : ctx.keySet()) {
if (key.equals("user_id") || key.equals("targetingKey")) {
if (key.equals("user_id") || key.equals("targetingKey") || key.equals("userId")) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,113 @@ public void testCreateUserOnlyUserId() {
Assert.assertEquals(user.getUserId(), "user-4567");
}

@Test
public void testFromEvaluationContextWithUserId() {
Map<String, Value> apiAttrs = new LinkedHashMap();
apiAttrs.put("userId", new Value("test-userId-123"));

// ensure fallback to userId when target key and user_id are null
EvaluationContext ctx = new MutableContext(null, apiAttrs);
DevCycleUser user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "test-userId-123");

// ensure fallback to userId when target key and user_id are empty
ctx = new MutableContext("", apiAttrs);
user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "test-userId-123");
}

@Test
public void testFromEvaluationContextUserIdPriorityOrder() {
Map<String, Value> apiAttrs = new LinkedHashMap();
apiAttrs.put("user_id", new Value("user_id_value"));
apiAttrs.put("userId", new Value("userId_value"));

// Test priority: targetingKey > user_id > userId
// When all three are present, targetingKey should win
EvaluationContext ctx = new MutableContext("targetingKey_value", apiAttrs);
DevCycleUser user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "targetingKey_value");

// When targetingKey is null, user_id should win over userId
ctx = new MutableContext(null, apiAttrs);
user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "user_id_value");

// When targetingKey is empty, user_id should win over userId
ctx = new MutableContext("", apiAttrs);
user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "user_id_value");

// When only userId is present, it should be used
Map<String, Value> userIdOnlyAttrs = new LinkedHashMap();
userIdOnlyAttrs.put("userId", new Value("userId_only_value"));
ctx = new MutableContext(null, userIdOnlyAttrs);
user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "userId_only_value");
}

@Test
public void testFromEvaluationContextUserIdExcludedFromCustomData() {
Map<String, Value> apiAttrs = new LinkedHashMap();
apiAttrs.put("userId", new Value("test-userId-123"));
apiAttrs.put("customField", new Value("customValue"));

// When userId is used as the user ID, it should be excluded from custom data
EvaluationContext ctx = new MutableContext(null, apiAttrs);
DevCycleUser user = DevCycleUser.fromEvaluationContext(ctx);

Assert.assertEquals(user.getUserId(), "test-userId-123");
Assert.assertNotNull(user.getCustomData());
Assert.assertEquals(user.getCustomData().size(), 1);
Assert.assertEquals(user.getCustomData().get("customField"), "customValue");
Assert.assertFalse(user.getCustomData().containsKey("userId"));
}

@Test
public void testFromEvaluationContextAllUserIdFieldsExcludedFromCustomData() {
Map<String, Value> apiAttrs = new LinkedHashMap();
apiAttrs.put("user_id", new Value("user_id_value"));
apiAttrs.put("userId", new Value("userId_value"));
apiAttrs.put("customField", new Value("customValue"));

// All user ID fields should be excluded from custom data regardless of which is used
EvaluationContext ctx = new MutableContext(null, apiAttrs);
DevCycleUser user = DevCycleUser.fromEvaluationContext(ctx);

Assert.assertEquals(user.getUserId(), "user_id_value");
Assert.assertNotNull(user.getCustomData());
Assert.assertEquals(user.getCustomData().size(), 1);
Assert.assertEquals(user.getCustomData().get("customField"), "customValue");
Assert.assertFalse(user.getCustomData().containsKey("userId"));
Assert.assertFalse(user.getCustomData().containsKey("user_id"));
Assert.assertFalse(user.getCustomData().containsKey("targetingKey"));
}

@Test
public void testFromEvaluationContextInvalidUserIdTypes() {
Map<String, Value> apiAttrs = new LinkedHashMap();

// Test with non-string userId value - should be ignored
apiAttrs.put("userId", new Value(123));
EvaluationContext ctx = new MutableContext(null, apiAttrs);

try {
DevCycleUser.fromEvaluationContext(ctx);
Assert.fail("Expected TargetingKeyMissingError");
} catch (TargetingKeyMissingError e) {
// expected
}

// Test with non-string user_id value but valid userId string - should use userId
apiAttrs.put("user_id", new Value(456));
apiAttrs.put("userId", new Value("valid-userId"));
ctx = new MutableContext(null, apiAttrs);

DevCycleUser user = DevCycleUser.fromEvaluationContext(ctx);
Assert.assertEquals(user.getUserId(), "valid-userId");
}

@Test
public void testCreateUserWithAttributes() {
Map<String, Value> apiAttrs = new LinkedHashMap();
Expand Down
Loading