diff --git a/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java b/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java index 4a0a4c6..d6b0ce3 100644 --- a/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java +++ b/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java @@ -155,6 +155,7 @@ public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner, @NonNull Life if (isNewSession) { autoRecordEventClient.handleSessionStart(); autoRecordEventClient.setIsEntrances(); + sessionClient.startSession(); recordScreenViewAfterSessionStart(); } } diff --git a/clickstream/src/main/java/software/aws/solution/clickstream/client/AutoRecordEventClient.java b/clickstream/src/main/java/software/aws/solution/clickstream/client/AutoRecordEventClient.java index bf34db3..17a86cd 100644 --- a/clickstream/src/main/java/software/aws/solution/clickstream/client/AutoRecordEventClient.java +++ b/clickstream/src/main/java/software/aws/solution/clickstream/client/AutoRecordEventClient.java @@ -49,6 +49,11 @@ public class AutoRecordEventClient { */ private boolean isFirstTime = true; + /** + * whether the app has entered the background at least once. + */ + private boolean isAppEndCalled = false; + /** * current screen is entrances. */ @@ -252,10 +257,12 @@ public void handleAppStart() { preferences.putBoolean("isFirstOpen", false); isFirstOpen = false; } - final AnalyticsEvent event = - this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.APP_START); - event.addAttribute(Event.ReservedAttribute.IS_FIRST_TIME, isFirstTime); - this.clickstreamContext.getAnalyticsClient().recordEvent(event); + if (isFirstTime || isAppEndCalled) { + final AnalyticsEvent event = + this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.APP_START); + event.addAttribute(Event.ReservedAttribute.IS_FIRST_TIME, isFirstTime); + this.clickstreamContext.getAnalyticsClient().recordEvent(event); + } isFirstTime = false; } @@ -275,6 +282,7 @@ public void handleAppEnd() { final AnalyticsEvent event = this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.APP_END); this.clickstreamContext.getAnalyticsClient().recordEvent(event); + isAppEndCalled = true; } /** diff --git a/clickstream/src/main/java/software/aws/solution/clickstream/client/ClickstreamManager.java b/clickstream/src/main/java/software/aws/solution/clickstream/client/ClickstreamManager.java index fbc7639..c9a51e3 100644 --- a/clickstream/src/main/java/software/aws/solution/clickstream/client/ClickstreamManager.java +++ b/clickstream/src/main/java/software/aws/solution/clickstream/client/ClickstreamManager.java @@ -63,6 +63,8 @@ public ClickstreamManager(@NonNull final ClickstreamConfiguration config) { } LOG.debug(String.format(Locale.US, "Clickstream SDK(%s) initialization successfully completed", BuildConfig.VERSION_NAME)); + this.autoRecordEventClient.handleAppStart(); + handleSessionStart(); } catch (final RuntimeException runtimeException) { LOG.error(String.format(Locale.US, "Cannot initialize Clickstream SDK %s", runtimeException.getMessage())); @@ -70,6 +72,18 @@ public ClickstreamManager(@NonNull final ClickstreamConfiguration config) { } } + /** + * handle session start after SDK initialize. + */ + private void handleSessionStart() { + boolean isNewSession = sessionClient.initialSession(); + if (isNewSession) { + autoRecordEventClient.handleSessionStart(); + autoRecordEventClient.setIsEntrances(); + sessionClient.startSession(); + } + } + /** * Enable track app exception. */ diff --git a/clickstream/src/main/java/software/aws/solution/clickstream/client/Session.java b/clickstream/src/main/java/software/aws/solution/clickstream/client/Session.java index f601860..b2086fb 100644 --- a/clickstream/src/main/java/software/aws/solution/clickstream/client/Session.java +++ b/clickstream/src/main/java/software/aws/solution/clickstream/client/Session.java @@ -58,6 +58,8 @@ public final class Session { private Long pauseTime; private final int sessionIndex; + private boolean isStarted; + /** * CONSTRUCTOR - ACTUAL Used by SessionClient. * @@ -118,6 +120,22 @@ public static Session getInstance(final ClickstreamContext context, Session prev } } + /** + * function for get session whether is started. + * + * @return session whether is started. + */ + public boolean isStarted() { + return this.isStarted; + } + + /** + * function for flag the session is started. + */ + public void start() { + this.isStarted = true; + } + /** * Pauses the session object. Generates a stop time. */ diff --git a/clickstream/src/main/java/software/aws/solution/clickstream/client/SessionClient.java b/clickstream/src/main/java/software/aws/solution/clickstream/client/SessionClient.java index 0a33c48..edaeda3 100644 --- a/clickstream/src/main/java/software/aws/solution/clickstream/client/SessionClient.java +++ b/clickstream/src/main/java/software/aws/solution/clickstream/client/SessionClient.java @@ -60,7 +60,14 @@ public SessionClient(@NonNull final ClickstreamContext clickstreamContext) { public synchronized boolean initialSession() { session = Session.getInstance(clickstreamContext, session); this.clickstreamContext.getAnalyticsClient().setSession(session); - return session.isNewSession(); + return session.isNewSession() && !session.isStarted(); + } + + /** + * method for start the session. + */ + public void startSession() { + session.start(); } /** diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/ActivityLifecycleManagerUnitTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/ActivityLifecycleManagerUnitTest.java index 52af248..054aa05 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/ActivityLifecycleManagerUnitTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/ActivityLifecycleManagerUnitTest.java @@ -30,9 +30,11 @@ import org.robolectric.RobolectricTestRunner; import software.aws.solution.clickstream.client.AutoRecordEventClient; import software.aws.solution.clickstream.client.ClickstreamManager; +import software.aws.solution.clickstream.client.ScreenRefererTool; import software.aws.solution.clickstream.client.SessionClient; import software.aws.solution.clickstream.util.ReflectUtil; +import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -47,6 +49,7 @@ public final class ActivityLifecycleManagerUnitTest { private Application.ActivityLifecycleCallbacks callbacks; private Log log; private LifecycleRegistry lifecycle; + private LifecycleOwner lifecycleOwner; private ActivityLifecycleManager lifecycleManager; /** @@ -65,9 +68,10 @@ public void setup() throws Exception { this.callbacks = lifecycleManager; log = mock(Log.class); ReflectUtil.modifyFiled(this.callbacks, "LOG", log); - - lifecycle = new LifecycleRegistry(mock(LifecycleOwner.class)); + lifecycleOwner = mock(LifecycleOwner.class); + lifecycle = new LifecycleRegistry(lifecycleOwner); lifecycleManager.startLifecycleTracking(ApplicationProvider.getApplicationContext(), lifecycle); + ScreenRefererTool.clear(); } /** @@ -121,6 +125,7 @@ public void testContextIsInValid() { */ @Test public void testOnAppForegrounded() { + assertNotNull(lifecycleOwner); when(sessionClient.initialSession()).thenReturn(true); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); verify(autoRecordEventClient).updateStartEngageTimestamp(); diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/AnalyticsClientTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/AnalyticsClientTest.java index 680c560..d6a4a47 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/AnalyticsClientTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/AnalyticsClientTest.java @@ -70,7 +70,7 @@ public void setup() throws Exception { Context context = ApplicationProvider.getApplicationContext(); AWSClickstreamPluginConfiguration.Builder configurationBuilder = AWSClickstreamPluginConfiguration.builder(); configurationBuilder.withAppId("demo-app") - .withEndpoint("http://cs-se-serve-1qtj719j88vwn-1291141553.ap-southeast-1.elb.amazonaws.com/collect") + .withEndpoint("http://example.com/collect") .withSendEventsInterval(10000); AWSClickstreamPluginConfiguration clickstreamPluginConfiguration = configurationBuilder.build(); ClickstreamManager clickstreamManager = diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java index 77d7bd9..309dc6f 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java @@ -73,6 +73,8 @@ public class AutoRecordEventClientTest { private ClickstreamContext clickstreamContext; private AutoRecordEventClient client; private LifecycleRegistry lifecycle; + private LifecycleOwner lifecycleOwner; + private ClickstreamManager clickstreamManager; /** * prepare AutoRecordEventClient and context. @@ -83,22 +85,91 @@ public void setup() { dbUtil = new ClickstreamDBUtil(context); AWSClickstreamPluginConfiguration.Builder configurationBuilder = AWSClickstreamPluginConfiguration.builder(); configurationBuilder.withAppId("demo-app") - .withEndpoint("http://cs-se-serve-1qtj719j88vwn-1291141553.ap-southeast-1.elb.amazonaws.com/collect") + .withEndpoint("http://example.com/collect") .withSendEventsInterval(10000) .withTrackScreenViewEvents(true) .withTrackUserEngagementEvents(true); AWSClickstreamPluginConfiguration clickstreamPluginConfiguration = configurationBuilder.build(); - ClickstreamManager clickstreamManager = - ClickstreamManagerFactory.create(context, clickstreamPluginConfiguration); + clickstreamManager = ClickstreamManagerFactory.create(context, clickstreamPluginConfiguration); client = clickstreamManager.getAutoRecordEventClient(); clickstreamContext = clickstreamManager.getClickstreamContext(); callbacks = new ActivityLifecycleManager(clickstreamManager); ActivityLifecycleManager lifecycleManager = new ActivityLifecycleManager(clickstreamManager); - lifecycle = new LifecycleRegistry(mock(LifecycleOwner.class)); + lifecycleOwner = mock(LifecycleOwner.class); + lifecycle = new LifecycleRegistry(lifecycleOwner); lifecycleManager.startLifecycleTracking(ApplicationProvider.getApplicationContext(), lifecycle); } + /** + * test events after SDK initialization. + * + * @throws Exception exception. + */ + @Test + public void testSDKInitializationEvents() throws Exception { + try (Cursor cursor = dbUtil.queryAllEvents()) { + List eventList = new ArrayList<>(); + while (cursor.moveToNext()) { + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + String eventName = jsonObject.getString("event_type"); + eventList.add(eventName); + } + assertEquals(3, eventList.size()); + assertEquals(Event.PresetEvent.FIRST_OPEN, eventList.get(0)); + assertEquals(Event.PresetEvent.APP_START, eventList.get(1)); + assertEquals(Event.PresetEvent.SESSION_START, eventList.get(2)); + } + } + + /** + * test SDK initialize with stored session. + * + * @throws Exception exception. + */ + @Test + public void testSDKInitializeWithStoredSession() throws Exception { + ReflectUtil.invokeMethod(clickstreamManager, "handleSessionStart"); + try (Cursor cursor = dbUtil.queryAllEvents()) { + List eventList = new ArrayList<>(); + while (cursor.moveToNext()) { + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + String eventName = jsonObject.getString("event_type"); + eventList.add(eventName); + } + assertEquals(3, eventList.size()); + assertEquals(Event.PresetEvent.FIRST_OPEN, eventList.get(0)); + assertEquals(Event.PresetEvent.APP_START, eventList.get(1)); + assertEquals(Event.PresetEvent.SESSION_START, eventList.get(2)); + } + } + + /** + * test SDK lazy initialization. + * + * @throws Exception exception. + */ + @Test + public void testLazyInitialization() throws Exception { + lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); + try (Cursor cursor = dbUtil.queryAllEvents()) { + List eventList = new ArrayList<>(); + while (cursor.moveToNext()) { + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + String eventName = jsonObject.getString("event_type"); + eventList.add(eventName); + } + assertEquals(3, eventList.size()); + assertEquals(Event.PresetEvent.FIRST_OPEN, eventList.get(0)); + assertEquals(Event.PresetEvent.APP_START, eventList.get(1)); + assertEquals(Event.PresetEvent.SESSION_START, eventList.get(2)); + } + } + + /** * test record user engagement event after view screen more than 1 second. * @@ -147,6 +218,7 @@ public void testEventsHaveSameSessionId() throws Exception { callbacks.onActivityCreated(activity, bundle); callbacks.onActivityStarted(activity); callbacks.onActivityResumed(activity); + assertNotNull(lifecycleOwner); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP); try (Cursor cursor = dbUtil.queryAllEvents()) { List eventList = new ArrayList<>(); @@ -864,7 +936,7 @@ public void testOSVersionForUpdate() throws Exception { @Test public void testHandleFirstOpen() throws Exception { client.handleAppStart(); - assertEquals(2, dbUtil.getTotalNumber()); + assertEquals(3, dbUtil.getTotalNumber()); Cursor cursor = dbUtil.queryAllEvents(); cursor.moveToFirst(); String eventString = cursor.getString(2); @@ -889,7 +961,7 @@ public void testHandleFirstOpenMultiTimes() throws Exception { client.handleAppStart(); client.handleAppStart(); client.handleAppStart(); - assertEquals(4, dbUtil.getTotalNumber()); + assertEquals(3, dbUtil.getTotalNumber()); Cursor cursor = dbUtil.queryAllEvents(); cursor.moveToFirst(); String eventString = cursor.getString(2); @@ -906,14 +978,14 @@ public void testHandleFirstOpenMultiTimes() throws Exception { */ @Test public void testHandleAppStart() throws Exception { - client.handleAppStart(); Activity activity1 = mock(Activity.class); Bundle bundle = mock(Bundle.class); callbacks.onActivityCreated(activity1, bundle); callbacks.onActivityStarted(activity1); callbacks.onActivityResumed(activity1); + client.handleAppEnd(); client.handleAppStart(); - assertEquals(4, dbUtil.getTotalNumber()); + assertEquals(6, dbUtil.getTotalNumber()); try (Cursor cursor = dbUtil.queryAllEvents()) { List eventList = new ArrayList<>(); while (cursor.moveToNext()) { @@ -928,10 +1000,11 @@ public void testHandleAppStart() throws Exception { assertFalse(appStart1.has(ReservedAttribute.SCREEN_NAME)); assertFalse(appStart1.has(Event.ReservedAttribute.SCREEN_ID)); - assertEquals(Event.PresetEvent.SCREEN_VIEW, eventList.get(2).getString("event_type")); - - assertEquals(Event.PresetEvent.APP_START, eventList.get(3).getString("event_type")); - JSONObject appStart2 = eventList.get(3).getJSONObject("attributes"); + assertEquals(Event.PresetEvent.SESSION_START, eventList.get(2).getString("event_type")); + assertEquals(Event.PresetEvent.SCREEN_VIEW, eventList.get(3).getString("event_type")); + assertEquals(Event.PresetEvent.APP_END, eventList.get(4).getString("event_type")); + assertEquals(Event.PresetEvent.APP_START, eventList.get(5).getString("event_type")); + JSONObject appStart2 = eventList.get(5).getJSONObject("attributes"); assertFalse(appStart2.getBoolean(Event.ReservedAttribute.IS_FIRST_TIME)); assertTrue(appStart2.has(ReservedAttribute.SCREEN_NAME)); assertTrue(appStart2.has(ReservedAttribute.SCREEN_UNIQUE_ID)); diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/EventRecorderTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/EventRecorderTest.java index fb282c3..0137697 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/EventRecorderTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/EventRecorderTest.java @@ -121,7 +121,7 @@ public void setup() throws Exception { AWSClickstreamPluginConfiguration.Builder configurationBuilder = AWSClickstreamPluginConfiguration.builder(); configurationBuilder.withAppId("demo-app") - .withEndpoint("http://cs-se-serve-1qtj719j88vwn-1291141553.ap-southeast-1.elb.amazonaws.com/collect") + .withEndpoint("http://example.com/collect") .withSendEventsInterval(10000); AWSClickstreamPluginConfiguration clickstreamPluginConfiguration = configurationBuilder.build(); ClickstreamManager clickstreamManager = @@ -137,6 +137,8 @@ public void setup() throws Exception { (EventRecorder) ReflectUtil.newInstance(EventRecorder.class, clickstreamContext, dbUtil, executorService); log = mock(Log.class); ReflectUtil.modifyFiled(eventRecorder, "LOG", log); + assertEquals(3, dbUtil.getTotalNumber()); + dbUtil.deleteBatchEvents(3); } /** @@ -214,7 +216,7 @@ public void testGetBatchOfEventsForOneEvent() throws Exception { String[] result = getBatchOfEvents(cursor); assertEquals(result.length, 2); assertTrue(result[0].contains(event.getEventId())); - assertEquals("1", result[1]); + assertEquals("4", result[1]); cursor.close(); } @@ -241,7 +243,7 @@ public void testGetBatchOfEventsForOneEventReachedLimitSize() throws Exception { assertEquals(result.length, 2); assertNotNull(result[0]); assertTrue(result[0].length() > 512 * 1024); - assertEquals("1", result[1]); + assertEquals("4", result[1]); cursor.close(); } @@ -259,7 +261,7 @@ public void testGetBatchOfEventsNotReachedDefaultLimitSize() throws Exception { String[] result = getBatchOfEvents(cursor); assertEquals(2, result.length); assertEquals(new JSONArray(result[0]).length(), 20); - assertEquals("20", result[1]); + assertEquals("23", result[1]); cursor.close(); } @@ -277,7 +279,7 @@ public void testGetBatchOfEventsReachedLimitNumber() throws Exception { String[] result = getBatchOfEvents(cursor); assertEquals(2, result.length); assertEquals(new JSONArray(result[0]).length(), 100); - assertEquals("100", result[1]); + assertEquals("103", result[1]); cursor.close(); } @@ -299,7 +301,7 @@ public void testGetBatchOfEventsReachedDefaultLimitSize() throws Exception { assertEquals(2, result.length); int length = new JSONArray(result[0]).length(); assertTrue(length < 30); - assertEquals(String.valueOf(length), result[1]); + assertEquals(length, Integer.parseInt(result[1]) - 3); cursor.close(); } diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/ExceptionHandlerTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/ExceptionHandlerTest.java index 697f7c1..ae0f370 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/ExceptionHandlerTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/ExceptionHandlerTest.java @@ -57,9 +57,10 @@ public void setup() throws Exception { AWSClickstreamPluginConfiguration.Builder configurationBuilder = AWSClickstreamPluginConfiguration.builder(); configurationBuilder.withAppId("demo-app") .withTrackAppExceptionEvents(true) - .withEndpoint("http://cs-se-serve-1qtj719j88vwn-1291141553.ap-southeast-1.elb.amazonaws.com/collect") + .withEndpoint("http://example.com/collect") .withSendEventsInterval(10000); clickstreamManager = ClickstreamManagerFactory.create(context, configurationBuilder.build()); + dbUtil.deleteBatchEvents(3); } /** diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/IntegrationTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/IntegrationTest.java index cb62388..cba0c38 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/IntegrationTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/IntegrationTest.java @@ -62,6 +62,8 @@ import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -120,21 +122,21 @@ public void setup() throws Exception { assert analyticsClient != null; eventRecorder = (EventRecorder) ReflectUtil.getFiled(analyticsClient, "eventRecorder"); dbUtil = (ClickstreamDBUtil) ReflectUtil.getFiled(eventRecorder, "dbUtil"); + if (!isConfigured) { + assertEquals(3, dbUtil.getTotalNumber()); + dbUtil.deleteBatchEvents(3); + } } /** * test record event with name use ClickstreamAnalytics api and make sure * the event has be auto submitted success after handler post massage. - * - * @throws Exception exception */ @Test - public void testRecordEventWithName() throws Exception { + public void testRecordEventWithName() { executeBackground(); ClickstreamAnalytics.recordEvent("testRecordEventWithName"); assertEquals(1, dbUtil.getTotalNumber()); - Thread.sleep(2500); - assertEquals(0, dbUtil.getTotalNumber()); } /** @@ -153,8 +155,6 @@ public void testRecordEventWithInvalidName() throws Exception { assertEquals(Event.PresetEvent.CLICKSTREAM_ERROR, jsonObject.getString("event_type")); } assertEquals(1, dbUtil.getTotalNumber()); - Thread.sleep(1500); - assertEquals(0, dbUtil.getTotalNumber()); } /** @@ -178,21 +178,18 @@ public void testRecordOneEvent() throws Exception { ClickstreamAnalytics.recordEvent(event); assertEquals(1, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToFirst(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject attribute = jsonObject.getJSONObject("attributes"); - Assert.assertEquals("PasswordReset", jsonObject.getString("event_type")); - Assert.assertEquals("SMS", attribute.getString("Channel")); - Assert.assertTrue(attribute.getBoolean("Successful")); - Assert.assertEquals(792, attribute.getInt("ProcessDuration")); - Assert.assertEquals(120.3, attribute.getDouble("UserAge"), 0.01); - Assert.assertEquals(169823889238L, attribute.getLong("Timestamp")); - - Thread.sleep(2500); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToFirst(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject attribute = jsonObject.getJSONObject("attributes"); + Assert.assertEquals("PasswordReset", jsonObject.getString("event_type")); + Assert.assertEquals("SMS", attribute.getString("Channel")); + Assert.assertTrue(attribute.getBoolean("Successful")); + Assert.assertEquals(792, attribute.getInt("ProcessDuration")); + Assert.assertEquals(120.3, attribute.getDouble("UserAge"), 0.01); + Assert.assertEquals(169823889238L, attribute.getLong("Timestamp")); + } } /** @@ -212,17 +209,15 @@ public void testRecordScreenViewEvent() throws Exception { ClickstreamAnalytics.recordEvent(event); assertEquals(1, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToFirst(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject attribute = jsonObject.getJSONObject("attributes"); - Assert.assertEquals(ClickstreamAnalytics.Event.SCREEN_VIEW, jsonObject.getString("event_type")); - Assert.assertEquals("HomeFragment", attribute.getString(ClickstreamAnalytics.Attr.SCREEN_NAME)); - Assert.assertEquals(0, attribute.getInt(Event.ReservedAttribute.ENTRANCES)); - Thread.sleep(1500); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToFirst(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject attribute = jsonObject.getJSONObject("attributes"); + Assert.assertEquals(ClickstreamAnalytics.Event.SCREEN_VIEW, jsonObject.getString("event_type")); + Assert.assertEquals("HomeFragment", attribute.getString(ClickstreamAnalytics.Attr.SCREEN_NAME)); + Assert.assertEquals(1, attribute.getInt(Event.ReservedAttribute.ENTRANCES)); + } } /** @@ -302,27 +297,23 @@ public void testAddGlobalAttribute() throws Exception { .build(); ClickstreamAnalytics.recordEvent(event); assertEquals(1, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToFirst(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject attribute = jsonObject.getJSONObject("attributes"); - - Assert.assertEquals("HUAWEI", attribute.getString("channel")); - Assert.assertEquals(5.1, attribute.getDouble("level"), 0.01); - Assert.assertEquals(6, attribute.getInt("class")); - Assert.assertTrue(attribute.getBoolean("isOpenNotification")); - Assert.assertEquals(timestamp, attribute.getLong("timestamp")); - - Assert.assertEquals("SMS", attribute.getString("Message")); - Assert.assertTrue(attribute.getBoolean("Successful")); - Assert.assertEquals(792, attribute.getInt("ProcessDuration")); - Assert.assertEquals(120.3, attribute.getDouble("UserAge"), 0.01); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToFirst(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject attribute = jsonObject.getJSONObject("attributes"); - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1000); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + Assert.assertEquals("HUAWEI", attribute.getString("channel")); + Assert.assertEquals(5.1, attribute.getDouble("level"), 0.01); + Assert.assertEquals(6, attribute.getInt("class")); + Assert.assertTrue(attribute.getBoolean("isOpenNotification")); + Assert.assertEquals(timestamp, attribute.getLong("timestamp")); + + Assert.assertEquals("SMS", attribute.getString("Message")); + Assert.assertTrue(attribute.getBoolean("Successful")); + Assert.assertEquals(792, attribute.getInt("ProcessDuration")); + Assert.assertEquals(120.3, attribute.getDouble("UserAge"), 0.01); + } } @@ -350,20 +341,16 @@ public void testDeleteGlobalAttribute() throws Exception { ClickstreamAnalytics.deleteGlobalAttributes("level"); ClickstreamAnalytics.recordEvent(event); assertEquals(1, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToFirst(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject attribute = jsonObject.getJSONObject("attributes"); - - Assert.assertEquals("HUAWEI", attribute.getString("channel")); - Assert.assertFalse(attribute.has("level")); - Assert.assertTrue(attribute.getBoolean("isOpenNotification")); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToFirst(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject attribute = jsonObject.getJSONObject("attributes"); - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1000); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + Assert.assertEquals("HUAWEI", attribute.getString("channel")); + Assert.assertFalse(attribute.has("level")); + Assert.assertTrue(attribute.getBoolean("isOpenNotification")); + } } /** @@ -385,24 +372,20 @@ public void testAddUserAttributes() throws Exception { ClickstreamAnalytics.addUserAttributes(clickstreamUserAttribute); assertEquals(2, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToLast(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - String eventType = jsonObject.getString("event_type"); - Assert.assertEquals(Event.PresetEvent.PROFILE_SET, eventType); - JSONObject user = jsonObject.getJSONObject("user"); - Assert.assertEquals("13212", ((JSONObject) user.get(Event.ReservedAttribute.USER_ID)).getString("value")); - Assert.assertEquals(21, ((JSONObject) user.get("_user_age")).getInt("value")); - Assert.assertTrue(((JSONObject) user.get("_user_age")).has("set_timestamp")); - Assert.assertEquals("carl", ((JSONObject) user.get("_user_name")).getString("value")); - Assert.assertTrue(((JSONObject) user.get("_user_name")).has("set_timestamp")); - Assert.assertEquals(timestamp, ((JSONObject) user.get("timestamp")).getLong("value")); - - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1000); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToLast(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + String eventType = jsonObject.getString("event_type"); + Assert.assertEquals(Event.PresetEvent.PROFILE_SET, eventType); + JSONObject user = jsonObject.getJSONObject("user"); + Assert.assertEquals("13212", ((JSONObject) user.get(Event.ReservedAttribute.USER_ID)).getString("value")); + Assert.assertEquals(21, ((JSONObject) user.get("_user_age")).getInt("value")); + Assert.assertTrue(((JSONObject) user.get("_user_age")).has("set_timestamp")); + Assert.assertEquals("carl", ((JSONObject) user.get("_user_name")).getString("value")); + Assert.assertTrue(((JSONObject) user.get("_user_name")).has("set_timestamp")); + Assert.assertEquals(timestamp, ((JSONObject) user.get("timestamp")).getLong("value")); + } } /** @@ -423,19 +406,15 @@ public void testModifyUserId() throws Exception { ClickstreamAnalytics.setUserId("12345"); assertEquals(3, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToLast(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject user = jsonObject.getJSONObject("user"); - Assert.assertEquals("12345", ((JSONObject) user.get(Event.ReservedAttribute.USER_ID)).getString("value")); - Assert.assertFalse(user.has("_user_age")); - Assert.assertFalse(user.has("_user_name")); - - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1000); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToLast(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject user = jsonObject.getJSONObject("user"); + Assert.assertEquals("12345", ((JSONObject) user.get(Event.ReservedAttribute.USER_ID)).getString("value")); + Assert.assertFalse(user.has("_user_age")); + Assert.assertFalse(user.has("_user_name")); + } } /** @@ -464,19 +443,15 @@ public void testSetUserIdNull() throws Exception { ClickstreamAnalytics.recordEvent(event); assertEquals(4, dbUtil.getTotalNumber()); - Cursor cursor = dbUtil.queryAllEvents(); - cursor.moveToLast(); - String eventString = cursor.getString(2); - JSONObject jsonObject = new JSONObject(eventString); - JSONObject user = jsonObject.getJSONObject("user"); - Assert.assertFalse(user.has(Event.ReservedAttribute.USER_ID)); - Assert.assertFalse(user.has("_user_age")); - Assert.assertFalse(user.has("_user_name")); - - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1000); - assertEquals(0, dbUtil.getTotalNumber()); - cursor.close(); + try (Cursor cursor = dbUtil.queryAllEvents()) { + cursor.moveToLast(); + String eventString = cursor.getString(2); + JSONObject jsonObject = new JSONObject(eventString); + JSONObject user = jsonObject.getJSONObject("user"); + Assert.assertFalse(user.has(Event.ReservedAttribute.USER_ID)); + Assert.assertFalse(user.has("_user_age")); + Assert.assertFalse(user.has("_user_name")); + } } /** @@ -579,10 +554,6 @@ public void testCustomConfig() throws Exception { String appId = jsonObject.getString("app_id"); assertEquals("23982", appId); } - - ClickstreamAnalytics.flushEvents(); - Thread.sleep(1500); - assertEquals(0, dbUtil.getTotalNumber()); } /** @@ -782,49 +753,48 @@ public void testEnableAfterDisable() throws Exception { ReflectUtil.modifyFiled(submitter, "LOG", log); ClickstreamAnalytics.disable(); - verify(log).debug("Auto submitting stop"); + verify(log, atLeastOnce()).debug("Auto submitting stop"); assertEquals(0, dbUtil.getTotalNumber()); ClickstreamAnalytics.recordEvent("testRecordEventWithName"); assertEquals(0, dbUtil.getTotalNumber()); ClickstreamAnalytics.enable(); - verify(log).debug("Auto submitting start"); + verify(log, atLeastOnce()).debug("Auto submitting start"); ClickstreamAnalytics.recordEvent("testRecordEventWithName"); assertEquals(1, dbUtil.getTotalNumber()); } /** - * test disable track activity lifecycle. + * test disable sdk and will not record app lifecycle events. * * @throws Exception exception */ @Test - public void testDisableActivityLifecycle() throws Exception { + public void testDisableAppLifecycle() throws Exception { ActivityLifecycleManager lifecycleManager = (ActivityLifecycleManager) ReflectUtil.getFiled(plugin, "activityLifecycleManager"); + LifecycleRegistry lifecycle = new LifecycleRegistry(mock(LifecycleOwner.class)); + lifecycleManager.startLifecycleTracking(application, lifecycle); ClickstreamAnalytics.disable(); + lifecycleManager.stopLifecycleTracking(application, lifecycle); - verify(application).unregisterActivityLifecycleCallbacks(lifecycleManager); + lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); + assertEquals(0, dbUtil.getTotalNumber()); ClickstreamAnalytics.enable(); } + /** - * test disable sdk and will not record app lifecycle events. + * test disable track activity lifecycle. * * @throws Exception exception */ @Test - public void testDisableAppLifecycle() throws Exception { + public void testDisableAndEnableActivityLifecycle() throws Exception { ActivityLifecycleManager lifecycleManager = (ActivityLifecycleManager) ReflectUtil.getFiled(plugin, "activityLifecycleManager"); - LifecycleRegistry lifecycle = new LifecycleRegistry(mock(LifecycleOwner.class)); - lifecycleManager.startLifecycleTracking(application, lifecycle); - ClickstreamAnalytics.disable(); - lifecycleManager.stopLifecycleTracking(application, lifecycle); - - lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); - assertEquals(0, dbUtil.getTotalNumber()); + verify(application, atLeast(1)).unregisterActivityLifecycleCallbacks(lifecycleManager); ClickstreamAnalytics.enable(); } diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java index 7229378..b21aa6d 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java @@ -50,7 +50,7 @@ public void setup() { AWSClickstreamPluginConfiguration.Builder configurationBuilder = AWSClickstreamPluginConfiguration.builder(); configurationBuilder.withAppId("demo-app") - .withEndpoint("http://cs-se-serve-1qtj719j88vwn-1291141553.ap-southeast-1.elb.amazonaws.com/collect") + .withEndpoint("http://example.com/collect") .withSendEventsInterval(10000) .withSessionTimeOut(1800000L); AWSClickstreamPluginConfiguration clickstreamPluginConfiguration = configurationBuilder.build(); diff --git a/clickstream/src/test/java/software/aws/solution/clickstream/db/DBUtilTest.java b/clickstream/src/test/java/software/aws/solution/clickstream/db/DBUtilTest.java index 33bcb2c..f865694 100644 --- a/clickstream/src/test/java/software/aws/solution/clickstream/db/DBUtilTest.java +++ b/clickstream/src/test/java/software/aws/solution/clickstream/db/DBUtilTest.java @@ -30,6 +30,8 @@ import software.aws.solution.clickstream.client.AnalyticsEvent; import software.aws.solution.clickstream.client.db.ClickstreamDBUtil; +import java.util.Objects; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -39,6 +41,7 @@ public class DBUtilTest { private ClickstreamDBUtil dbUtil; + private AnalyticsEvent analyticsEvent; /** * prepare dbUtil and context. @@ -46,6 +49,8 @@ public class DBUtilTest { @Before public void setup() { dbUtil = new ClickstreamDBUtil(ApplicationProvider.getApplicationContext()); + analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); + dbUtil.deleteBatchEvents(3); } /** @@ -53,9 +58,8 @@ public void setup() { */ @Test public void testInsertSingleEvent() { - AnalyticsEvent analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); Uri uri = dbUtil.saveEvent(analyticsEvent); - int idInserted = Integer.parseInt(uri.getLastPathSegment()); + int idInserted = Integer.parseInt(Objects.requireNonNull(uri.getLastPathSegment())); assertNotEquals(idInserted, 0); } @@ -64,11 +68,10 @@ public void testInsertSingleEvent() { */ @Test public void testQueryAll() { - AnalyticsEvent analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); Uri uri1 = dbUtil.saveEvent(analyticsEvent); Uri uri2 = dbUtil.saveEvent(analyticsEvent); - int idInserted1 = Integer.parseInt(uri1.getLastPathSegment()); - int idInserted2 = Integer.parseInt(uri2.getLastPathSegment()); + int idInserted1 = Integer.parseInt(Objects.requireNonNull(uri1.getLastPathSegment())); + int idInserted2 = Integer.parseInt(Objects.requireNonNull(uri2.getLastPathSegment())); assertNotEquals(idInserted1, 0); assertNotEquals(idInserted2, 0); Cursor c = dbUtil.queryAllEvents(); @@ -83,11 +86,10 @@ public void testQueryAll() { */ @Test public void testDelete() { - AnalyticsEvent analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); Uri uri1 = dbUtil.saveEvent(analyticsEvent); Uri uri2 = dbUtil.saveEvent(analyticsEvent); - int idInserted1 = Integer.parseInt(uri1.getLastPathSegment()); - int idInserted2 = Integer.parseInt(uri2.getLastPathSegment()); + int idInserted1 = Integer.parseInt(Objects.requireNonNull(uri1.getLastPathSegment())); + int idInserted2 = Integer.parseInt(Objects.requireNonNull(uri2.getLastPathSegment())); assertNotEquals(idInserted1, 0); assertNotEquals(idInserted2, 0); Cursor c = dbUtil.queryAllEvents(); @@ -115,13 +117,12 @@ public void testDelete() { */ @Test public void testGetTotalDbSize() { - AnalyticsEvent analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); int eventLength1 = analyticsEvent.toJSONObject().toString().length(); Uri uri1 = dbUtil.saveEvent(analyticsEvent); int eventLength2 = analyticsEvent.toJSONObject().toString().length(); Uri uri2 = dbUtil.saveEvent(analyticsEvent); - int idInserted1 = Integer.parseInt(uri1.getLastPathSegment()); - int idInserted2 = Integer.parseInt(uri2.getLastPathSegment()); + int idInserted1 = Integer.parseInt(Objects.requireNonNull(uri1.getLastPathSegment())); + int idInserted2 = Integer.parseInt(Objects.requireNonNull(uri2.getLastPathSegment())); assertNotEquals(idInserted1, 0); assertNotEquals(idInserted2, 0); Cursor c = dbUtil.queryAllEvents(); @@ -136,11 +137,10 @@ public void testGetTotalDbSize() { */ @Test public void testGetTotalDbNumber() { - AnalyticsEvent analyticsEvent = AnalyticsEventTest.getAnalyticsClient().createEvent("testEvent"); Uri uri1 = dbUtil.saveEvent(analyticsEvent); Uri uri2 = dbUtil.saveEvent(analyticsEvent); - int idInserted1 = Integer.parseInt(uri1.getLastPathSegment()); - int idInserted2 = Integer.parseInt(uri2.getLastPathSegment()); + int idInserted1 = Integer.parseInt(Objects.requireNonNull(uri1.getLastPathSegment())); + int idInserted2 = Integer.parseInt(Objects.requireNonNull(uri2.getLastPathSegment())); assertNotEquals(idInserted1, 0); assertNotEquals(idInserted2, 0); assertEquals(dbUtil.getTotalNumber(), 2);