Skip to content

Commit 0707bca

Browse files
committed
add: unit tests for custom events
1 parent 66e916c commit 0707bca

File tree

4 files changed

+208
-5
lines changed

4 files changed

+208
-5
lines changed

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/UserManagerTests.kt

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import com.onesignal.core.internal.language.ILanguageContext
44
import com.onesignal.mocks.MockHelper
55
import com.onesignal.user.internal.subscriptions.ISubscriptionManager
66
import com.onesignal.user.internal.subscriptions.SubscriptionList
7+
import io.kotest.assertions.throwables.shouldNotThrow
78
import io.kotest.core.spec.style.FunSpec
9+
import io.kotest.matchers.equals.shouldBeEqual
810
import io.kotest.matchers.shouldBe
911
import io.kotest.matchers.shouldNotBe
1012
import io.mockk.every
@@ -26,7 +28,7 @@ class UserManagerTests : FunSpec({
2628
every { languageContext.language = capture(languageSlot) } answers { }
2729

2830
val userManager =
29-
UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), MockHelper.propertiesModelStore(), languageContext)
31+
UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), MockHelper.propertiesModelStore(), MockHelper.customEventController(), languageContext)
3032

3133
// When
3234
userManager.setLanguage("new-language")
@@ -44,7 +46,7 @@ class UserManagerTests : FunSpec({
4446
}
4547

4648
val userManager =
47-
UserManager(mockSubscriptionManager, identityModelStore, MockHelper.propertiesModelStore(), MockHelper.languageContext())
49+
UserManager(mockSubscriptionManager, identityModelStore, MockHelper.propertiesModelStore(), MockHelper.customEventController(), MockHelper.languageContext())
4850

4951
// When
5052
val externalId = userManager.externalId
@@ -63,7 +65,7 @@ class UserManagerTests : FunSpec({
6365
}
6466

6567
val userManager =
66-
UserManager(mockSubscriptionManager, identityModelStore, MockHelper.propertiesModelStore(), MockHelper.languageContext())
68+
UserManager(mockSubscriptionManager, identityModelStore, MockHelper.propertiesModelStore(), MockHelper.customEventController(), MockHelper.languageContext())
6769

6870
// When
6971
val alias1 = userManager.aliases["my-alias-key1"]
@@ -102,7 +104,7 @@ class UserManagerTests : FunSpec({
102104
}
103105

104106
val userManager =
105-
UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.languageContext())
107+
UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.customEventController(), MockHelper.languageContext())
106108

107109
// When
108110
val tag1 = propertiesModelStore.model.tags["my-tag-key1"]
@@ -141,7 +143,7 @@ class UserManagerTests : FunSpec({
141143
it.tags["my-tag-key1"] = "my-tag-value1"
142144
}
143145

144-
val userManager = UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.languageContext())
146+
val userManager = UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.customEventController(), MockHelper.languageContext())
145147

146148
// When
147149
val tagSnapshot1 = userManager.getTags()
@@ -173,6 +175,7 @@ class UserManagerTests : FunSpec({
173175
mockSubscriptionManager,
174176
MockHelper.identityModelStore(),
175177
MockHelper.propertiesModelStore(),
178+
MockHelper.customEventController(),
176179
MockHelper.languageContext(),
177180
)
178181

@@ -191,4 +194,42 @@ class UserManagerTests : FunSpec({
191194
verify(exactly = 1) { mockSubscriptionManager.addSmsSubscription("+15558675309") }
192195
verify(exactly = 1) { mockSubscriptionManager.removeSmsSubscription("+15558675309") }
193196
}
197+
198+
test("custom event controller sends various types of properties") {
199+
// Given
200+
val customEventController = MockHelper.customEventController()
201+
202+
val userManager =
203+
UserManager(mockk<ISubscriptionManager>(), MockHelper.identityModelStore(), MockHelper.propertiesModelStore(), customEventController, MockHelper.languageContext())
204+
205+
val eventName = "eventName"
206+
val properties =
207+
mapOf(
208+
"key1" to "value1",
209+
"key2" to 2,
210+
"key3" to 5.123,
211+
"key4" to mapOf("key4-1" to "value4-1"),
212+
"key5" to mapOf("key5-1" to mapOf("key5-1-1" to 0)),
213+
)
214+
215+
// When
216+
// should be able to handle any of the map structures above
217+
shouldNotThrow<Exception> {
218+
userManager.trackEvent(
219+
eventName,
220+
properties,
221+
)
222+
}
223+
224+
// Then
225+
// ensure the controller call sendCustomEvent() with the correct name and properties
226+
verify(exactly = 1) {
227+
customEventController.sendCustomEvent(
228+
withArg {
229+
it.name shouldBeEqual(eventName)
230+
it.properties.toString() shouldBeEqual(properties.toString())
231+
},
232+
)
233+
}
234+
}
194235
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.onesignal.user.internal.backend
2+
3+
import com.onesignal.core.internal.http.HttpResponse
4+
import com.onesignal.core.internal.http.IHttpClient
5+
import com.onesignal.core.internal.operations.ExecutionResult
6+
import com.onesignal.debug.LogLevel
7+
import com.onesignal.debug.internal.logging.Logging
8+
import com.onesignal.user.internal.customEvents.impl.CustomEvent
9+
import com.onesignal.user.internal.customEvents.impl.CustomEventBackendService
10+
import com.onesignal.user.internal.customEvents.impl.CustomEventMetadata
11+
import io.kotest.core.spec.style.FunSpec
12+
import io.kotest.matchers.equals.shouldBeEqual
13+
import io.kotest.matchers.shouldBe
14+
import io.mockk.coEvery
15+
import io.mockk.coVerify
16+
import io.mockk.mockk
17+
import org.json.JSONObject
18+
19+
class CustomEventBackendServiceTests : FunSpec({
20+
beforeAny {
21+
Logging.logLevel = LogLevel.NONE
22+
}
23+
24+
val metadata =
25+
CustomEventMetadata(
26+
"Android",
27+
"sdk",
28+
"1.0",
29+
"type",
30+
"deviceModel",
31+
"deviceOS",
32+
)
33+
34+
test("track event") {
35+
// Given
36+
val spyHttpClient = mockk<IHttpClient>()
37+
coEvery { spyHttpClient.post(any(), any()) } returns HttpResponse(202, "")
38+
val customEventBackendService = CustomEventBackendService(spyHttpClient)
39+
40+
// When
41+
val properties =
42+
mapOf(
43+
"proKey1" to "proVal1",
44+
)
45+
val customEvent =
46+
CustomEvent(
47+
"event-name",
48+
properties,
49+
)
50+
51+
val response =
52+
customEventBackendService.sendCustomEvent(
53+
appId = "appId",
54+
onesignalId = "onesignalId",
55+
externalId = null,
56+
timestamp = 1,
57+
customEvent = customEvent,
58+
metadata = metadata,
59+
)
60+
61+
// Then
62+
response.result shouldBe ExecutionResult.SUCCESS
63+
coVerify {
64+
spyHttpClient.post(
65+
"apps/appId/integrations/sdk/custom_events",
66+
withArg {
67+
val eventsObject = it.getJSONArray("events").getJSONObject(0)
68+
val eventMap = mutableMapOf<String, Any?>()
69+
for (key in eventsObject.keys()) {
70+
eventMap[key] = eventsObject.get(key)
71+
}
72+
73+
eventMap.get("name") shouldBe customEvent.name
74+
eventMap.get("app_id") shouldBe "appId"
75+
eventMap.get("onesignal_id") shouldBe "onesignalId"
76+
eventMap.get("external_id") shouldBe null
77+
eventMap.get("timestamp") shouldBe "1969-12-31T19:00:00.001Z"
78+
79+
val payload = eventMap.get("payload") as JSONObject
80+
payload.getJSONObject("os_sdk").toString() shouldBeEqual metadata.toJSONObject().toString()
81+
payload.getString("proKey1") shouldBeEqual "proVal1"
82+
},
83+
)
84+
}
85+
}
86+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.onesignal.user.internal.operations
2+
3+
import android.content.Context
4+
import android.os.Build
5+
import com.onesignal.common.OneSignalUtils
6+
import com.onesignal.core.internal.device.IDeviceService
7+
import com.onesignal.core.internal.operations.ExecutionResponse
8+
import com.onesignal.core.internal.operations.ExecutionResult
9+
import com.onesignal.core.internal.operations.Operation
10+
import com.onesignal.mocks.MockHelper
11+
import com.onesignal.user.internal.customEvents.ICustomEventBackendService
12+
import com.onesignal.user.internal.customEvents.impl.CustomEvent
13+
import com.onesignal.user.internal.operations.impl.executors.CustomEventOperationExecutor
14+
import io.kotest.core.spec.style.FunSpec
15+
import io.kotest.matchers.equals.shouldBeEqual
16+
import io.kotest.matchers.shouldBe
17+
import io.mockk.coEvery
18+
import io.mockk.coVerify
19+
import io.mockk.every
20+
import io.mockk.mockk
21+
22+
class CustomEventOperationExecutorTests : FunSpec({
23+
test("execution of track event operation") {
24+
// Given
25+
val mockCustomEventBackendService = mockk<ICustomEventBackendService>()
26+
coEvery { mockCustomEventBackendService.sendCustomEvent(any(), any(), any(), any(), any(), any()) } returns ExecutionResponse(ExecutionResult.SUCCESS)
27+
28+
val mockApplicationService = MockHelper.applicationService()
29+
val mockContext = mockk<Context>(relaxed = true)
30+
every { mockApplicationService.appContext } returns mockContext
31+
val mockDeviceService = MockHelper.deviceService()
32+
every { mockDeviceService.deviceType } returns IDeviceService.DeviceType.Android
33+
34+
val deviceMode = Build.MODEL
35+
val deviceOS = Build.VERSION.RELEASE
36+
37+
val customEvent =
38+
CustomEvent(
39+
"event-name",
40+
mapOf("key" to "value"),
41+
)
42+
val customEventOperationExecutor =
43+
CustomEventOperationExecutor(mockCustomEventBackendService, mockApplicationService, mockDeviceService)
44+
val operations = listOf<Operation>(TrackEventOperation("appId", "onesignalId", null, 1, customEvent))
45+
46+
// When
47+
val response = customEventOperationExecutor.execute(operations)
48+
49+
// Then
50+
response.result shouldBe ExecutionResult.SUCCESS
51+
coVerify(exactly = 1) {
52+
mockCustomEventBackendService.sendCustomEvent(
53+
"appId",
54+
"onesignalId",
55+
null,
56+
1,
57+
customEvent,
58+
withArg {
59+
it.sdk shouldBe OneSignalUtils.SDK_VERSION
60+
it.appVersion?.shouldBeEqual("0")
61+
it.type?.shouldBeEqual(("AndroidPush"))
62+
it.deviceType?.shouldBeEqual(("Android"))
63+
it.deviceModel shouldBe deviceMode
64+
it.deviceOS shouldBe deviceOS
65+
},
66+
)
67+
}
68+
}
69+
})

OneSignalSDK/onesignal/testhelpers/src/main/java/com/onesignal/mocks/MockHelper.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.onesignal.core.internal.language.ILanguageContext
88
import com.onesignal.core.internal.time.ITime
99
import com.onesignal.session.internal.session.SessionModel
1010
import com.onesignal.session.internal.session.SessionModelStore
11+
import com.onesignal.user.internal.customEvents.ICustomEventController
1112
import com.onesignal.user.internal.identity.IdentityModel
1213
import com.onesignal.user.internal.identity.IdentityModelStore
1314
import com.onesignal.user.internal.properties.PropertiesModel
@@ -126,4 +127,10 @@ object MockHelper {
126127
every { deviceService.deviceType } returns IDeviceService.DeviceType.Android
127128
return deviceService
128129
}
130+
131+
fun customEventController(): ICustomEventController {
132+
val controller = mockk<ICustomEventController>()
133+
every { controller.sendCustomEvent(any()) } just runs
134+
return controller
135+
}
129136
}

0 commit comments

Comments
 (0)