Skip to content

Commit d353c7c

Browse files
committed
New API methods integration
1 parent 27fd69f commit d353c7c

2 files changed

Lines changed: 234 additions & 12 deletions

File tree

events-domain/src/main/java/io/split/android/client/events/SplitEventsManager.java

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,30 +145,74 @@ public void run() {
145145
}
146146

147147
private EventHandler<SplitEvent, EventMetadata> createBackgroundHandler(final SplitEventTask task) {
148-
return new EventHandler<SplitEvent, EventMetadata>() {
148+
return createEventHandler(task, "background", new TaskMethodCaller() {
149149
@Override
150-
public void handle(SplitEvent event, EventMetadata metadata) {
151-
try {
152-
task.onPostExecution(mResources.getSplitClient());
153-
} catch (SplitEventTaskMethodNotImplementedException e) {
154-
// Method not implemented by client, ignore
155-
} catch (Exception e) {
156-
Logger.e("Error executing background event task: " + e.getMessage());
157-
}
150+
public void callWithMetadata(EventMetadata metadata) {
151+
task.onPostExecution(mResources.getSplitClient(), metadata);
158152
}
159-
};
153+
154+
@Override
155+
public void callWithoutMetadata() {
156+
task.onPostExecution(mResources.getSplitClient());
157+
}
158+
});
160159
}
161160

162161
private EventHandler<SplitEvent, EventMetadata> createMainThreadHandler(final SplitEventTask task) {
162+
return createEventHandler(task, "main thread", new TaskMethodCaller() {
163+
@Override
164+
public void callWithMetadata(EventMetadata metadata) {
165+
task.onPostExecutionView(mResources.getSplitClient(), metadata);
166+
}
167+
168+
@Override
169+
public void callWithoutMetadata() {
170+
task.onPostExecutionView(mResources.getSplitClient());
171+
}
172+
});
173+
}
174+
175+
/**
176+
* Helper interface for calling task methods.
177+
*/
178+
private interface TaskMethodCaller {
179+
void callWithMetadata(EventMetadata metadata) throws Exception;
180+
void callWithoutMetadata() throws Exception;
181+
}
182+
183+
/**
184+
* Creates an EventHandler that calls both metadata and legacy versions of the task method.
185+
*
186+
* @param task the task to execute
187+
* @param threadType description of thread type for error messages
188+
* @param caller interface for calling the appropriate task methods
189+
* @return an EventHandler that handles both metadata and legacy callbacks
190+
*/
191+
private EventHandler<SplitEvent, EventMetadata> createEventHandler(
192+
final SplitEventTask task,
193+
final String threadType,
194+
final TaskMethodCaller caller) {
163195
return new EventHandler<SplitEvent, EventMetadata>() {
164196
@Override
165197
public void handle(SplitEvent event, EventMetadata metadata) {
198+
executeTaskMethod(metadata, true, threadType, caller);
199+
executeTaskMethod(metadata, false, threadType, caller);
200+
}
201+
202+
private void executeTaskMethod(EventMetadata metadata, boolean withMetadata, String threadType, TaskMethodCaller caller) {
166203
try {
167-
task.onPostExecutionView(mResources.getSplitClient());
204+
if (withMetadata) {
205+
caller.callWithMetadata(metadata);
206+
} else {
207+
caller.callWithoutMetadata();
208+
}
168209
} catch (SplitEventTaskMethodNotImplementedException e) {
169210
// Method not implemented by client, ignore
170211
} catch (Exception e) {
171-
Logger.e("Error executing main thread event task: " + e.getMessage());
212+
String errorPrefix = withMetadata
213+
? "Error executing " + threadType + " event task (with metadata): "
214+
: "Error executing " + threadType + " event task: ";
215+
Logger.e(errorPrefix + e.getMessage());
172216
}
173217
}
174218
};

main/src/test/java/io/split/android/client/events/EventsManagerTest.java

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.split.android.client.events;
22

3+
import static org.junit.Assert.assertEquals;
34
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNotNull;
46
import static org.junit.Assert.assertTrue;
57
import static org.mockito.Mockito.when;
68

@@ -11,13 +13,17 @@
1113
import org.mockito.MockitoAnnotations;
1214

1315
import java.util.ArrayList;
16+
import java.util.Arrays;
1417
import java.util.List;
1518
import java.util.concurrent.CountDownLatch;
1619
import java.util.concurrent.TimeUnit;
20+
import java.util.concurrent.atomic.AtomicReference;
1721

1822
import io.split.android.client.SplitClient;
1923
import io.split.android.client.SplitClientConfig;
24+
import io.split.android.client.api.EventMetadata;
2025
import io.split.android.client.events.executors.SplitEventExecutorResources;
26+
import io.split.android.client.events.metadata.EventMetadataHelpers;
2127
import io.split.android.fake.SplitTaskExecutorStub;
2228

2329
public class EventsManagerTest {
@@ -266,4 +272,176 @@ private static void execute(boolean shouldStop, long intervalExecutionTime, long
266272
}
267273
}
268274
}
275+
276+
@Test
277+
public void sdkUpdateWithMetadataCallsMetadataMethod() throws InterruptedException {
278+
SplitEventsManager eventManager = new SplitEventsManager(new SplitTaskExecutorStub(), 0);
279+
CountDownLatch readyLatch = new CountDownLatch(1);
280+
CountDownLatch updateLatch = new CountDownLatch(1);
281+
AtomicReference<EventMetadata> receivedMetadata = new AtomicReference<>();
282+
283+
waitForSdkReady(eventManager, readyLatch);
284+
285+
eventManager.register(SplitEvent.SDK_UPDATE, new SplitEventTask() {
286+
@Override
287+
public void onPostExecution(SplitClient client, EventMetadata metadata) {
288+
receivedMetadata.set(metadata);
289+
updateLatch.countDown();
290+
}
291+
});
292+
293+
EventMetadata metadata = createTestMetadata();
294+
triggerSdkUpdateWithMetadata(eventManager, metadata);
295+
296+
boolean updateAwait = updateLatch.await(3, TimeUnit.SECONDS);
297+
assertTrue("SDK_UPDATE callback should be called", updateAwait);
298+
assertNotNull("Metadata should not be null", receivedMetadata.get());
299+
assertTrue("Metadata should contain updatedFlags", receivedMetadata.get().containsKey("updatedFlags"));
300+
}
301+
302+
@Test
303+
public void sdkUpdateWithMetadataCallsMetadataMethodOnMainThread() throws InterruptedException {
304+
SplitEventsManager eventManager = new SplitEventsManager(new SplitTaskExecutorStub(), 0);
305+
CountDownLatch readyLatch = new CountDownLatch(1);
306+
CountDownLatch updateLatch = new CountDownLatch(1);
307+
AtomicReference<EventMetadata> receivedMetadata = new AtomicReference<>();
308+
309+
waitForSdkReady(eventManager, readyLatch);
310+
311+
eventManager.register(SplitEvent.SDK_UPDATE, new SplitEventTask() {
312+
@Override
313+
public void onPostExecutionView(SplitClient client, EventMetadata metadata) {
314+
receivedMetadata.set(metadata);
315+
updateLatch.countDown();
316+
}
317+
});
318+
319+
EventMetadata metadata = createTestMetadata();
320+
triggerSdkUpdateWithMetadata(eventManager, metadata);
321+
322+
boolean updateAwait = updateLatch.await(3, TimeUnit.SECONDS);
323+
assertTrue("SDK_UPDATE callback should be called on main thread", updateAwait);
324+
assertNotNull("Metadata should not be null", receivedMetadata.get());
325+
assertTrue("Metadata should contain updatedFlags", receivedMetadata.get().containsKey("updatedFlags"));
326+
}
327+
328+
@Test
329+
public void sdkUpdateCallsLegacyMethodWhenOnlyLegacyImplemented() throws InterruptedException {
330+
SplitEventsManager eventManager = new SplitEventsManager(new SplitTaskExecutorStub(), 0);
331+
CountDownLatch readyLatch = new CountDownLatch(1);
332+
CountDownLatch updateLatch = new CountDownLatch(1);
333+
final boolean[] nonMetadataMethodCalled = {false};
334+
335+
waitForSdkReady(eventManager, readyLatch);
336+
337+
eventManager.register(SplitEvent.SDK_UPDATE, new SplitEventTask() {
338+
@Override
339+
public void onPostExecution(SplitClient client) {
340+
nonMetadataMethodCalled[0] = true;
341+
updateLatch.countDown();
342+
}
343+
});
344+
345+
EventMetadata metadata = createTestMetadata();
346+
triggerSdkUpdateWithMetadata(eventManager, metadata);
347+
348+
boolean updateAwait = updateLatch.await(3, TimeUnit.SECONDS);
349+
assertTrue("SDK_UPDATE callback should be called", updateAwait);
350+
assertTrue("Legacy method should be called", nonMetadataMethodCalled[0]);
351+
}
352+
353+
@Test
354+
public void sdkUpdateCallsBothMethodsWhenBothImplemented() throws InterruptedException {
355+
SplitEventsManager eventManager = new SplitEventsManager(new SplitTaskExecutorStub(), 0);
356+
CountDownLatch readyLatch = new CountDownLatch(1);
357+
CountDownLatch bothCalledLatch = new CountDownLatch(2);
358+
final boolean[] metadataMethodCalled = {false};
359+
final boolean[] legacyMethodCalled = {false};
360+
AtomicReference<EventMetadata> receivedMetadata = new AtomicReference<>();
361+
362+
waitForSdkReady(eventManager, readyLatch);
363+
364+
eventManager.register(SplitEvent.SDK_UPDATE, new SplitEventTask() {
365+
@Override
366+
public void onPostExecution(SplitClient client, EventMetadata metadata) {
367+
metadataMethodCalled[0] = true;
368+
receivedMetadata.set(metadata);
369+
bothCalledLatch.countDown();
370+
}
371+
372+
@Override
373+
public void onPostExecution(SplitClient client) {
374+
legacyMethodCalled[0] = true;
375+
bothCalledLatch.countDown();
376+
}
377+
});
378+
379+
EventMetadata metadata = createTestMetadata();
380+
triggerSdkUpdateWithMetadata(eventManager, metadata);
381+
382+
boolean bothCalled = bothCalledLatch.await(3, TimeUnit.SECONDS);
383+
assertTrue("Both callbacks should be called", bothCalled);
384+
assertTrue("Metadata method should be called", metadataMethodCalled[0]);
385+
assertTrue("Legacy method should also be called", legacyMethodCalled[0]);
386+
assertNotNull("Metadata should be passed to metadata method", receivedMetadata.get());
387+
assertTrue("Metadata should contain updatedFlags", receivedMetadata.get().containsKey("updatedFlags"));
388+
}
389+
390+
@Test
391+
public void sdkReadyFromCacheCallsBothMethodsWhenBothImplemented() throws InterruptedException {
392+
SplitEventsManager eventManager = new SplitEventsManager(new SplitTaskExecutorStub(), 0);
393+
394+
CountDownLatch bothCalledLatch = new CountDownLatch(2); // Expect 2 calls
395+
final boolean[] metadataMethodCalled = {false};
396+
final boolean[] legacyMethodCalled = {false};
397+
398+
// Register a task that implements both versions
399+
eventManager.register(SplitEvent.SDK_READY_FROM_CACHE, new SplitEventTask() {
400+
@Override
401+
public void onPostExecution(SplitClient client, EventMetadata metadata) {
402+
metadataMethodCalled[0] = true;
403+
bothCalledLatch.countDown();
404+
}
405+
406+
@Override
407+
public void onPostExecution(SplitClient client) {
408+
legacyMethodCalled[0] = true;
409+
bothCalledLatch.countDown();
410+
}
411+
});
412+
413+
// Trigger SDK_READY_FROM_CACHE
414+
eventManager.notifyInternalEvent(SplitInternalEvent.SPLITS_LOADED_FROM_STORAGE);
415+
eventManager.notifyInternalEvent(SplitInternalEvent.MY_SEGMENTS_LOADED_FROM_STORAGE);
416+
eventManager.notifyInternalEvent(SplitInternalEvent.ATTRIBUTES_LOADED_FROM_STORAGE);
417+
eventManager.notifyInternalEvent(SplitInternalEvent.ENCRYPTION_MIGRATION_DONE);
418+
419+
boolean bothCalled = bothCalledLatch.await(3, TimeUnit.SECONDS);
420+
assertTrue("Both callbacks should be called", bothCalled);
421+
assertTrue("Metadata method should be called", metadataMethodCalled[0]);
422+
assertTrue("Legacy method should also be called", legacyMethodCalled[0]);
423+
}
424+
425+
private void waitForSdkReady(SplitEventsManager eventManager, CountDownLatch readyLatch) throws InterruptedException {
426+
eventManager.register(SplitEvent.SDK_READY, new SplitEventTask() {
427+
@Override
428+
public void onPostExecutionView(SplitClient client) {
429+
readyLatch.countDown();
430+
}
431+
});
432+
433+
eventManager.notifyInternalEvent(SplitInternalEvent.TARGETING_RULES_SYNC_COMPLETE);
434+
eventManager.notifyInternalEvent(SplitInternalEvent.MEMBERSHIPS_SYNC_COMPLETE);
435+
boolean readyAwait = readyLatch.await(3, TimeUnit.SECONDS);
436+
assertTrue("SDK_READY should be triggered", readyAwait);
437+
}
438+
439+
private static EventMetadata createTestMetadata() {
440+
return EventMetadataHelpers.createUpdatedFlagsMetadata(
441+
Arrays.asList("flag1", "flag2"));
442+
}
443+
444+
private static void triggerSdkUpdateWithMetadata(SplitEventsManager eventManager, EventMetadata metadata) {
445+
eventManager.notifyInternalEvent(SplitInternalEvent.SPLITS_UPDATED, metadata);
446+
}
269447
}

0 commit comments

Comments
 (0)