From ad3366169d0a380fde1973c29d3b31a428894579 Mon Sep 17 00:00:00 2001
From: Xiaowei Zhu <33129495+zhu-xiaowei@users.noreply.github.com>
Date: Tue, 5 Mar 2024 23:01:50 +0800
Subject: [PATCH] fix: the second app start event's sessionId (#70)

Co-authored-by: xiaoweii <xiaoweii@amazom.com>
---
 .github/workflows/integration_test.yml        |  1 -
 .../clickstream/ActivityLifecycleManager.java |  3 +-
 .../client/AutoRecordEventClient.java         |  9 ++++
 .../clickstream/client/SessionClient.java     |  5 ---
 .../AutoRecordEventClientTest.java            |  9 ++++
 .../clickstream/SessionClientTest.java        | 43 +------------------
 6 files changed, 22 insertions(+), 48 deletions(-)

diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml
index 180815b..47162e8 100644
--- a/.github/workflows/integration_test.yml
+++ b/.github/workflows/integration_test.yml
@@ -29,7 +29,6 @@ jobs:
           cache: gradle
       - name: Build SDK release aar file
         run: |
-          echo ${{ github.event.pull_request.title }}
           chmod +x gradlew
           ./gradlew assembleRelease
       - name: Set up JDK 17
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 2ca5bed..4a0a4c6 100644
--- a/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java
+++ b/clickstream/src/main/java/software/aws/solution/clickstream/ActivityLifecycleManager.java
@@ -149,10 +149,11 @@ public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner, @NonNull Life
         } else if (event == Lifecycle.Event.ON_START) {
             LOG.debug("Application entered the foreground.");
             isFromForeground = true;
+            boolean isNewSession = sessionClient.initialSession();
             autoRecordEventClient.handleAppStart();
             autoRecordEventClient.updateStartEngageTimestamp();
-            boolean isNewSession = sessionClient.initialSession();
             if (isNewSession) {
+                autoRecordEventClient.handleSessionStart();
                 autoRecordEventClient.setIsEntrances();
                 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 431efda..bf34db3 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
@@ -259,6 +259,15 @@ public void handleAppStart() {
         isFirstTime = false;
     }
 
+    /**
+     * handle session start events.
+     */
+    public void handleSessionStart() {
+        final AnalyticsEvent event =
+            this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.SESSION_START);
+        this.clickstreamContext.getAnalyticsClient().recordEvent(event);
+    }
+
     /**
      * handle the app end event.
      */
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 8af49f2..0a33c48 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,11 +60,6 @@ public SessionClient(@NonNull final ClickstreamContext clickstreamContext) {
     public synchronized boolean initialSession() {
         session = Session.getInstance(clickstreamContext, session);
         this.clickstreamContext.getAnalyticsClient().setSession(session);
-        if (session.isNewSession()) {
-            final AnalyticsEvent event =
-                this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.SESSION_START);
-            this.clickstreamContext.getAnalyticsClient().recordEvent(event);
-        }
         return session.isNewSession();
     }
 
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 b370d64..77d7bd9 100644
--- a/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java
+++ b/clickstream/src/test/java/software/aws/solution/clickstream/AutoRecordEventClientTest.java
@@ -1019,6 +1019,15 @@ public void testSessionTimeoutAfterReopenTheApp() throws Exception {
             JSONObject jsonObject2 = new JSONObject(eventString2);
             String eventName2 = jsonObject2.getString("event_type");
             assertEquals(Event.PresetEvent.SESSION_START, eventName2);
+
+            // assert that the second app start event will have the same session id
+            cursor.moveToPrevious();
+            String eventString3 = cursor.getString(2);
+            JSONObject jsonObject3 = new JSONObject(eventString3);
+            String eventName3 = jsonObject3.getString("event_type");
+            assertEquals(Event.PresetEvent.APP_START, eventName3);
+            assertEquals(jsonObject3.getJSONObject("attributes").getString("_session_id"),
+                jsonObject2.getJSONObject("attributes").getString("_session_id"));
         }
     }
 
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 7888e75..7229378 100644
--- a/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java
+++ b/clickstream/src/test/java/software/aws/solution/clickstream/SessionClientTest.java
@@ -16,11 +16,8 @@
 package software.aws.solution.clickstream;
 
 import android.content.Context;
-import android.database.Cursor;
 import androidx.test.core.app.ApplicationProvider;
 
-import org.json.JSONObject;
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -31,7 +28,6 @@
 import software.aws.solution.clickstream.client.ClickstreamManager;
 import software.aws.solution.clickstream.client.Session;
 import software.aws.solution.clickstream.client.SessionClient;
-import software.aws.solution.clickstream.client.db.ClickstreamDBUtil;
 import software.aws.solution.clickstream.util.ReflectUtil;
 
 import static org.mockito.Mockito.mock;
@@ -43,7 +39,6 @@
 public class SessionClientTest {
     private SessionClient client;
     private AnalyticsClient analyticsClient;
-    private ClickstreamDBUtil dbUtil;
     private ClickstreamContext clickstreamContext;
 
     /**
@@ -53,7 +48,6 @@ public class SessionClientTest {
     public void setup() {
         Context context = ApplicationProvider.getApplicationContext();
 
-        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")
@@ -74,22 +68,12 @@ public void setup() {
      */
     @Test
     public void testExecuteStart() throws Exception {
-        client.initialSession();
+        boolean isNewSession = client.initialSession();
         Session session = (Session) ReflectUtil.getFiled(client, "session");
         Assert.assertNotNull(session);
         Session clientSession = (Session) ReflectUtil.getFiled(analyticsClient, "session");
         Assert.assertNotNull(clientSession);
-        Assert.assertEquals(1, dbUtil.getTotalNumber());
-        Cursor cursor = dbUtil.queryAllEvents();
-        cursor.moveToFirst();
-        String eventString = cursor.getString(2);
-        JSONObject jsonObject = new JSONObject(eventString);
-        Assert.assertEquals("_session_start", jsonObject.getString("event_type"));
-        JSONObject attributes = jsonObject.getJSONObject("attributes");
-        Assert.assertNotNull(attributes.getString("_session_id"));
-        Assert.assertNotNull(attributes.getString("_session_start_timestamp"));
-        Assert.assertNotNull(attributes.getString("_session_duration"));
-        cursor.close();
+        Assert.assertTrue(isNewSession);
     }
 
     /**
@@ -106,17 +90,6 @@ public void testExecuteStartAndStore() throws Exception {
         client.storeSession();
         Session storedSession = (Session) ReflectUtil.getFiled(client, "session");
         Assert.assertFalse(storedSession.isNewSession());
-
-        Assert.assertEquals(1, dbUtil.getTotalNumber());
-        Cursor cursor = dbUtil.queryAllEvents();
-        cursor.moveToFirst();
-        String eventString = cursor.getString(2);
-        JSONObject jsonObject = new JSONObject(eventString);
-        JSONObject attributes = jsonObject.getJSONObject("attributes");
-        Assert.assertNotNull(attributes.getString("_session_id"));
-        Assert.assertNotNull(attributes.getString("_session_start_timestamp"));
-        Assert.assertNotNull(attributes.getString("_session_duration"));
-        cursor.close();
     }
 
 
@@ -143,8 +116,6 @@ public void testExecuteStartTwiceWithoutSessionTimeout() throws Exception {
         Assert.assertEquals(session.getSessionID(), newSession.getSessionID());
         Assert.assertEquals(session.getStartTime(), newSession.getStartTime());
         Assert.assertEquals(1, newSession.getSessionIndex());
-
-        Assert.assertEquals(1, dbUtil.getTotalNumber());
     }
 
 
@@ -172,8 +143,6 @@ public void testExecuteStartTwiceWithSessionTimeout() throws Exception {
         Assert.assertNotEquals(session.getSessionID(), newSession.getSessionID());
         Assert.assertNotEquals(session.getStartTime(), newSession.getStartTime());
         Assert.assertEquals(2, newSession.getSessionIndex());
-
-        Assert.assertEquals(2, dbUtil.getTotalNumber());
     }
 
 
@@ -185,12 +154,4 @@ public void testInitSessionClientWithNullAnalyticsClient() {
         ClickstreamContext context = mock(ClickstreamContext.class);
         new SessionClient(context);
     }
-
-    /**
-     * close db.
-     */
-    @After
-    public void tearDown() {
-        dbUtil.closeDB();
-    }
 }