Skip to content

Commit 6436b76

Browse files
committed
add unit tests
1 parent 288eeb3 commit 6436b76

File tree

4 files changed

+240
-2
lines changed

4 files changed

+240
-2
lines changed

core/src/main/java/com/segment/analytics/kotlin/core/State.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ data class System(
8484

8585
class ToggleRunningAction(var running: Boolean) : Action<System> {
8686
override fun reduce(state: System): System {
87-
if (running && state.waitingPlugins.size > 0) {
87+
if (running && state.waitingPlugins.isNotEmpty()) {
8888
running = false
8989
}
9090

core/src/main/java/com/segment/analytics/kotlin/core/platform/Plugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ abstract class DestinationPlugin : EventPlugin {
161161

162162
final override fun execute(event: BaseEvent): BaseEvent? = process(event)
163163

164-
internal fun isDestinationEnabled(event: BaseEvent?): Boolean {
164+
open fun isDestinationEnabled(event: BaseEvent?): Boolean {
165165
// if event payload has integration marked false then its disabled by customer
166166
val customerEnabled = event?.integrations?.getBoolean(key) ?: true // default to true when missing
167167

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package com.segment.analytics.kotlin.core
2+
3+
import com.segment.analytics.kotlin.core.platform.EventPlugin
4+
import com.segment.analytics.kotlin.core.platform.Plugin
5+
import com.segment.analytics.kotlin.core.utils.StubDestinationPlugin
6+
import com.segment.analytics.kotlin.core.utils.clearPersistentStorage
7+
import com.segment.analytics.kotlin.core.utils.mockHTTPClient
8+
import com.segment.analytics.kotlin.core.utils.testAnalytics
9+
import io.mockk.coEvery
10+
import io.mockk.coVerify
11+
import io.mockk.mockkStatic
12+
import kotlinx.coroutines.Job
13+
import kotlinx.coroutines.delay
14+
import kotlinx.coroutines.launch
15+
import kotlinx.coroutines.test.TestScope
16+
import kotlinx.coroutines.test.UnconfinedTestDispatcher
17+
import kotlinx.coroutines.test.advanceTimeBy
18+
import kotlinx.coroutines.test.advanceUntilIdle
19+
import kotlinx.coroutines.test.runTest
20+
import org.junit.jupiter.api.BeforeEach
21+
import org.junit.jupiter.api.Test
22+
import org.junit.jupiter.api.Assertions.*
23+
24+
25+
class WaitingTests {
26+
27+
private lateinit var analytics: Analytics
28+
29+
private val testDispatcher = UnconfinedTestDispatcher()
30+
31+
private val testScope = TestScope(testDispatcher)
32+
33+
@BeforeEach
34+
fun setup() {
35+
clearPersistentStorage()
36+
mockHTTPClient()
37+
val config = Configuration(
38+
writeKey = "123",
39+
application = "Test",
40+
autoAddSegmentDestination = false
41+
)
42+
analytics = testAnalytics(config, testScope, testDispatcher)
43+
}
44+
45+
@Test
46+
fun `test resume after timeout`() = testScope.runTest {
47+
assertTrue(analytics.running())
48+
analytics.pauseEventProcessing(1000)
49+
assertFalse(analytics.running())
50+
advanceTimeBy(2000)
51+
assertTrue(analytics.running())
52+
}
53+
54+
@Test
55+
fun `test manual resume`() = testScope.runTest {
56+
assertTrue(analytics.running())
57+
analytics.pauseEventProcessing()
58+
assertFalse(analytics.running())
59+
analytics.resumeEventProcessing()
60+
assertTrue(analytics.running())
61+
}
62+
63+
64+
@Test
65+
fun `test pause does not dispatch state if already pause`() {
66+
mockkStatic("com.segment.analytics.kotlin.core.WaitingKt")
67+
coEvery { analytics.startProcessingAfterTimeout(any()) } returns Job()
68+
69+
testScope.runTest {
70+
analytics.pauseEventProcessing()
71+
analytics.pauseEventProcessing()
72+
analytics.pauseEventProcessing()
73+
coVerify(exactly = 1) {
74+
analytics.startProcessingAfterTimeout(any())
75+
}
76+
}
77+
}
78+
79+
@Test
80+
fun `test WaitingPlugin makes analytics to wait`() = testScope.runTest {
81+
assertTrue(analytics.running())
82+
val waitingPlugin = ExampleWaitingPlugin()
83+
analytics.add(waitingPlugin)
84+
analytics.track("foo")
85+
86+
assertFalse(analytics.running())
87+
assertFalse(waitingPlugin.tracked)
88+
89+
advanceUntilIdle()
90+
91+
assertTrue(analytics.running())
92+
assertTrue(waitingPlugin.tracked)
93+
}
94+
95+
@Test
96+
fun `test timeout force resume`() = testScope.runTest {
97+
assertTrue(analytics.running())
98+
val waitingPlugin = ManualResumeWaitingPlugin()
99+
analytics.add(waitingPlugin)
100+
analytics.track("foo")
101+
102+
assertFalse(analytics.running())
103+
assertFalse(waitingPlugin.tracked)
104+
105+
advanceUntilIdle()
106+
107+
assertTrue(analytics.running())
108+
assertTrue(waitingPlugin.tracked)
109+
}
110+
111+
@Test
112+
fun `test multiple WaitingPlugin`() = testScope.runTest {
113+
assertTrue(analytics.running())
114+
val plugin1 = ExampleWaitingPlugin()
115+
val plugin2 = ManualResumeWaitingPlugin()
116+
analytics.add(plugin1)
117+
analytics.add(plugin2)
118+
analytics.track("foo")
119+
120+
assertFalse(analytics.running())
121+
assertFalse(plugin1.tracked)
122+
assertFalse(plugin2.tracked)
123+
124+
plugin1.resume()
125+
advanceTimeBy(6000)
126+
127+
assertFalse(analytics.running())
128+
assertFalse(plugin1.tracked)
129+
assertFalse(plugin2.tracked)
130+
131+
plugin2.resume()
132+
advanceUntilIdle()
133+
assertTrue(analytics.running())
134+
assertTrue(plugin1.tracked)
135+
assertTrue(plugin2.tracked)
136+
}
137+
138+
@Test
139+
fun `test WaitingPlugin makes analytics to wait on DestinationPlugin`() = testScope.runTest {
140+
assertTrue(analytics.running())
141+
val waitingPlugin = ExampleWaitingPlugin()
142+
val destinationPlugin = StubDestinationPlugin()
143+
analytics.add(destinationPlugin)
144+
destinationPlugin.add(waitingPlugin)
145+
analytics.track("foo")
146+
147+
assertFalse(analytics.running())
148+
assertFalse(waitingPlugin.tracked)
149+
150+
advanceUntilIdle()
151+
152+
assertTrue(analytics.running())
153+
assertTrue(waitingPlugin.tracked)
154+
}
155+
156+
@Test
157+
fun `test timeout force resume on DestinationPlugin`() = testScope.runTest {
158+
assertTrue(analytics.running())
159+
val waitingPlugin = ManualResumeWaitingPlugin()
160+
val destinationPlugin = StubDestinationPlugin()
161+
analytics.add(destinationPlugin)
162+
destinationPlugin.add(waitingPlugin)
163+
analytics.track("foo")
164+
165+
assertFalse(analytics.running())
166+
assertFalse(waitingPlugin.tracked)
167+
168+
advanceUntilIdle()
169+
170+
assertTrue(analytics.running())
171+
assertTrue(waitingPlugin.tracked)
172+
}
173+
174+
@Test
175+
fun `test multiple WaitingPlugin on DestinationPlugin`() = testScope.runTest {
176+
assertTrue(analytics.running())
177+
val destinationPlugin = StubDestinationPlugin()
178+
analytics.add(destinationPlugin)
179+
val plugin1 = ExampleWaitingPlugin()
180+
val plugin2 = ManualResumeWaitingPlugin()
181+
destinationPlugin.add(plugin1)
182+
destinationPlugin.add(plugin2)
183+
analytics.track("foo")
184+
185+
assertFalse(analytics.running())
186+
assertFalse(plugin1.tracked)
187+
assertFalse(plugin2.tracked)
188+
189+
plugin1.resume()
190+
advanceTimeBy(6000)
191+
192+
assertFalse(analytics.running())
193+
assertFalse(plugin1.tracked)
194+
assertFalse(plugin2.tracked)
195+
196+
plugin2.resume()
197+
advanceUntilIdle()
198+
assertTrue(analytics.running())
199+
assertTrue(plugin1.tracked)
200+
assertTrue(plugin2.tracked)
201+
}
202+
203+
class ExampleWaitingPlugin: EventPlugin, WaitingPlugin {
204+
override val type: Plugin.Type = Plugin.Type.Enrichment
205+
override lateinit var analytics: Analytics
206+
var tracked = false
207+
208+
override fun update(settings: Settings, type: Plugin.UpdateType) {
209+
if (type == Plugin.UpdateType.Initial) {
210+
analytics.analyticsScope.launch(analytics.analyticsDispatcher) {
211+
delay(3000)
212+
resume()
213+
}
214+
}
215+
}
216+
217+
override fun track(payload: TrackEvent): BaseEvent? {
218+
tracked = true
219+
return super.track(payload)
220+
}
221+
}
222+
223+
class ManualResumeWaitingPlugin: EventPlugin, WaitingPlugin {
224+
override val type: Plugin.Type = Plugin.Type.Enrichment
225+
override lateinit var analytics: Analytics
226+
var tracked = false
227+
228+
override fun track(payload: TrackEvent): BaseEvent? {
229+
tracked = true
230+
return super.track(payload)
231+
}
232+
}
233+
}

core/src/test/kotlin/com/segment/analytics/kotlin/core/utils/Plugins.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,9 @@ open class StubPlugin : EventPlugin {
7373
open class StubAfterPlugin : EventPlugin {
7474
override val type: Plugin.Type = Plugin.Type.After
7575
override lateinit var analytics: Analytics
76+
}
77+
78+
open class StubDestinationPlugin : DestinationPlugin() {
79+
override val key: String = "StubDestination"
80+
override fun isDestinationEnabled(event: BaseEvent?) = true
7681
}

0 commit comments

Comments
 (0)