@@ -3,6 +3,9 @@ package com.parsely.parselyandroid
33import android.app.Activity
44import androidx.test.core.app.ActivityScenario
55import androidx.test.ext.junit.runners.AndroidJUnit4
6+ import androidx.test.platform.app.InstrumentationRegistry
7+ import androidx.test.uiautomator.UiDevice
8+ import androidx.test.uiautomator.UiSelector
69import com.fasterxml.jackson.annotation.JsonIgnoreProperties
710import com.fasterxml.jackson.annotation.JsonProperty
811import com.fasterxml.jackson.core.type.TypeReference
@@ -12,7 +15,10 @@ import java.io.FileInputStream
1215import java.io.ObjectInputStream
1316import java.lang.reflect.Field
1417import java.nio.file.Path
18+ import java.util.concurrent.TimeUnit
1519import kotlin.io.path.Path
20+ import kotlin.time.Duration
21+ import kotlin.time.Duration.Companion.hours
1622import kotlin.time.Duration.Companion.milliseconds
1723import kotlin.time.Duration.Companion.seconds
1824import kotlinx.coroutines.runBlocking
@@ -70,6 +76,43 @@ class FunctionalTests {
7076 }
7177 }
7278
79+ /* *
80+ * In this scenario, the consumer application:
81+ * 1. Goes to the background
82+ * 2. Is re-launched
83+ * This pattern occurs twice, which allows us to confirm the following assertions:
84+ * 1. The event request is triggered when the consumer application is moved to the background
85+ * 2. If the consumer application is sent to the background again within a short interval,
86+ * the request is not duplicated.
87+ */
88+ @Test
89+ fun appSendsEventsWhenMovedToBackgroundAndDoesntSendDuplicatedRequestWhenItsMovedToBackgroundAgainQuickly () {
90+ val device = UiDevice .getInstance(InstrumentationRegistry .getInstrumentation())
91+ ActivityScenario .launch(SampleActivity ::class .java).use { scenario ->
92+ scenario.onActivity { activity: Activity ->
93+ beforeEach(activity)
94+ server.enqueue(MockResponse ().setResponseCode(200 ))
95+ server.enqueue(MockResponse ().setResponseCode(200 ))
96+ parselyTracker = initializeTracker(activity, flushInterval = 1 .hours)
97+
98+ repeat(20 ) {
99+ parselyTracker.trackPageview(" url" , null , null , null )
100+ }
101+ }
102+
103+ device.pressHome()
104+ device.pressRecentApps()
105+ device.findObject(UiSelector ().descriptionContains(" com.parsely" )).click()
106+ device.pressHome()
107+
108+ val firstRequest = server.takeRequest(10000 , TimeUnit .MILLISECONDS )?.toMap()
109+ val secondRequest = server.takeRequest(10000 , TimeUnit .MILLISECONDS )?.toMap()
110+
111+ assertThat(firstRequest!! [" events" ]).hasSize(20 )
112+ assertThat(secondRequest).isNull()
113+ }
114+ }
115+
73116 private fun RecordedRequest.toMap (): Map <String , List <Event >> {
74117 val listType: TypeReference <Map <String , List <Event >>> =
75118 object : TypeReference <Map <String , List <Event >>>() {}
@@ -90,7 +133,10 @@ class FunctionalTests {
90133 }
91134 }
92135
93- private fun initializeTracker (activity : Activity ): ParselyTracker {
136+ private fun initializeTracker (
137+ activity : Activity ,
138+ flushInterval : Duration = defaultFlushInterval
139+ ): ParselyTracker {
94140 return ParselyTracker .sharedInstance(
95141 siteId, flushInterval.inWholeSeconds.toInt(), activity.application
96142 ).apply {
@@ -103,7 +149,7 @@ class FunctionalTests {
103149 private companion object {
104150 const val siteId = " 123"
105151 const val localStorageFileName = " parsely-events.ser"
106- val flushInterval = 10 .seconds
152+ val defaultFlushInterval = 10 .seconds
107153 }
108154
109155 class SampleActivity : Activity ()
0 commit comments