diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java index ce218ed9d..8edb135aa 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java @@ -108,10 +108,10 @@ public void identifyUser(@Nullable String vuid, @Nullable String userId) { identifiers.put(ODPUserKey.VUID.getKeyString(), vuid); } if (userId != null) { - if (isVuid(userId)) { - identifiers.put(ODPUserKey.VUID.getKeyString(), userId); + if (ODPManager.isVuid(userId)) { + identifiers.put(ODPUserKey.VUID.getKeyString(), userId); } else { - identifiers.put(ODPUserKey.FS_USER_ID.getKeyString(), userId); + identifiers.put(ODPUserKey.FS_USER_ID.getKeyString(), userId); } } ODPEvent event = new ODPEvent("fullstack", "identified", identifiers, null); @@ -153,10 +153,6 @@ protected Map augmentCommonIdentifiers(Map sourc return identifiers; } - private boolean isVuid(String userId) { - return userId.startsWith("vuid_"); - } - private void processEvent(ODPEvent event) { if (!isRunning) { logger.warn("Failed to Process ODP Event. ODPEventManager is not running"); diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java index cacbcad0d..4f1ddc52d 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java @@ -68,6 +68,10 @@ public void close() { eventManager.stop(); } + public static boolean isVuid(String userId) { + return userId.startsWith("vuid_"); + } + public static Builder builder() { return new Builder(); } diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java index 275c45ee1..ce1aaffd3 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java @@ -52,11 +52,15 @@ public ODPSegmentManager(ODPApiManager apiManager, Integer cacheSize, Integer ca this.segmentsCache = new DefaultLRUCache<>(cacheSize, cacheTimeoutSeconds); } - public List getQualifiedSegments(String fsUserId) { - return getQualifiedSegments(ODPUserKey.FS_USER_ID, fsUserId, Collections.emptyList()); - } - public List getQualifiedSegments(String fsUserId, List options) { - return getQualifiedSegments(ODPUserKey.FS_USER_ID, fsUserId, options); + public List getQualifiedSegments(String userId) { + return getQualifiedSegments(userId, Collections.emptyList()); + } + public List getQualifiedSegments(String userId, List options) { + if (ODPManager.isVuid(userId)) { + return getQualifiedSegments(ODPUserKey.VUID, userId, options); + } else { + return getQualifiedSegments(ODPUserKey.FS_USER_ID, userId, options); + } } public List getQualifiedSegments(ODPUserKey userKey, String userValue) { diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java index 27de838f3..0c1c01a2c 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java @@ -211,6 +211,64 @@ public void prepareCorrectPayloadForIdentifyUser() throws InterruptedException { } } + @Test + public void identifyUserWithVuidAndUserId() throws InterruptedException { + ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager)); + ArgumentCaptor captor = ArgumentCaptor.forClass(ODPEvent.class); + + eventManager.identifyUser("vuid_123", "test-user"); + verify(eventManager, times(1)).sendEvent(captor.capture()); + + ODPEvent event = captor.getValue(); + Map identifiers = event.getIdentifiers(); + assertEquals(identifiers.size(), 2); + assertEquals(identifiers.get("vuid"), "vuid_123"); + assertEquals(identifiers.get("fs_user_id"), "test-user"); + } + + @Test + public void identifyUserWithVuidOnly() throws InterruptedException { + ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager)); + ArgumentCaptor captor = ArgumentCaptor.forClass(ODPEvent.class); + + eventManager.identifyUser("vuid_123", null); + verify(eventManager, times(1)).sendEvent(captor.capture()); + + ODPEvent event = captor.getValue(); + Map identifiers = event.getIdentifiers(); + assertEquals(identifiers.size(), 1); + assertEquals(identifiers.get("vuid"), "vuid_123"); + } + + @Test + public void identifyUserWithUserIdOnly() throws InterruptedException { + ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager)); + ArgumentCaptor captor = ArgumentCaptor.forClass(ODPEvent.class); + + eventManager.identifyUser(null, "test-user"); + verify(eventManager, times(1)).sendEvent(captor.capture()); + + ODPEvent event = captor.getValue(); + Map identifiers = event.getIdentifiers(); + assertEquals(identifiers.size(), 1); + assertEquals(identifiers.get("fs_user_id"), "test-user"); + } + + @Test + public void identifyUserWithVuidAsUserId() throws InterruptedException { + ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager)); + ArgumentCaptor captor = ArgumentCaptor.forClass(ODPEvent.class); + + eventManager.identifyUser(null, "vuid_123"); + verify(eventManager, times(1)).sendEvent(captor.capture()); + + ODPEvent event = captor.getValue(); + Map identifiers = event.getIdentifiers(); + assertEquals(identifiers.size(), 1); + // SDK will convert userId to vuid when userId has a valid vuid format. + assertEquals(identifiers.get("vuid"), "vuid_123"); + } + @Test public void applyUpdatedODPConfigWhenAvailable() throws InterruptedException { Mockito.reset(mockApiManager); diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java index 9673bfa69..1e1f59f29 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java @@ -121,4 +121,12 @@ public void shouldGetSegmentManager() { odpManager = ODPManager.builder().withApiManager(mockApiManager).build(); assertNotNull(odpManager.getSegmentManager()); } + + @Test + public void isVuid() { + assertTrue(ODPManager.isVuid("vuid_123")); + assertFalse(ODPManager.isVuid("vuid123")); + assertFalse(ODPManager.isVuid("any_123")); + assertFalse(ODPManager.isVuid("")); + } } diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java index 2e6aa611e..3d71f0d2c 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java @@ -398,4 +398,20 @@ public void noSegmentsInProjectAsync() throws InterruptedException { logbackVerifier.expectMessage(Level.DEBUG, "No Segments are used in the project, Not Fetching segments. Returning empty list"); } + + @Test + public void getQualifiedSegmentsWithUserId() { + ODPSegmentManager segmentManager = spy(new ODPSegmentManager(mockApiManager, mockCache)); + segmentManager.getQualifiedSegments("test-user"); + verify(segmentManager).getQualifiedSegments(ODPUserKey.FS_USER_ID, "test-user", Collections.emptyList()); + } + + @Test + public void getQualifiedSegmentsWithVuid() { + ODPSegmentManager segmentManager = spy(new ODPSegmentManager(mockApiManager, mockCache)); + segmentManager.getQualifiedSegments("vuid_123"); + // SDK will convert userId to vuid when userId has a valid vuid format. + verify(segmentManager).getQualifiedSegments(ODPUserKey.VUID, "vuid_123", Collections.emptyList()); + } + }