Skip to content

Commit 77fedfe

Browse files
authored
Added Firebase destination (#14)
* Added Firebase destination
1 parent b3978ce commit 77fedfe

File tree

6 files changed

+603
-2
lines changed

6 files changed

+603
-2
lines changed

analytics-kotlin/src/main/java/com/segment/analytics/utilities/JSON.kt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fun JsonObjectBuilder.putAll(obj: JsonObject) {
1111
}
1212
}
1313

14-
// Utility function to put "undefined" value in-stead of `null` when building JsonObject
14+
// Utility function to put "undefined" value instead of `null` when building JsonObject
1515
fun JsonObjectBuilder.putUndefinedIfNull(key: String, value: CharSequence?): JsonElement? =
1616
if (value.isNullOrEmpty()) {
1717
put(key, "undefined")
@@ -74,15 +74,39 @@ fun JsonPrimitive.toContent(): Any? {
7474
this.doubleOrNull?.let {
7575
return it
7676
}
77+
7778
return contentOrNull
7879
}
7980

8081
// Utility function to retrieve a boolean value from a jsonObject
81-
fun JsonObject.getBoolean(key: String): Boolean? = this[key]?.jsonPrimitive?.boolean
82+
fun JsonObject.getBoolean(key: String): Boolean? = this[key]?.jsonPrimitive?.booleanOrNull
8283

8384
// Utility function to retrieve a string value from a jsonObject
8485
fun JsonObject.getString(key: String): String? = this[key]?.jsonPrimitive?.contentOrNull
8586

87+
// Utility function to retrieve a double value from a jsonObject
88+
fun JsonObject.getDouble(key: String): Double? = this[key]?.jsonPrimitive?.doubleOrNull
89+
90+
// Utility function to retrieve a int value from a jsonObject
91+
fun JsonObject.getInt(key: String): Int? = this[key]?.jsonPrimitive?.intOrNull
92+
8693
// Utility function to retrieve a string set (from jsonArray) from a jsonObject
8794
fun JsonObject.getStringSet(key: String): Set<String>? =
8895
this[key]?.jsonArray?.map { it.jsonPrimitive.content }?.toSet()
96+
97+
// Utility function to retrieve a map set from a jsonObject
98+
fun JsonObject.getMapSet(key: String): Set<Map<String, Any>>? {
99+
100+
val returnList: MutableList<Map<String, Any>> = mutableListOf()
101+
102+
this[key]?.jsonObject?.let { jsonMap ->
103+
for ((mapKey, value) in jsonMap) {
104+
returnList.add(mapOf(mapKey to value))
105+
}
106+
}
107+
108+
return if (returnList.isNotEmpty())
109+
returnList.toSet()
110+
else
111+
null
112+
}
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
package com.segment.analytics.main
2+
3+
import com.segment.analytics.utilities.*
4+
import io.mockk.spyk
5+
import io.mockk.verify
6+
import kotlinx.serialization.json.*
7+
import org.junit.jupiter.api.Assertions
8+
import org.junit.jupiter.api.Test
9+
import org.junit.jupiter.api.TestInstance
10+
import java.lang.IllegalArgumentException
11+
import java.lang.IllegalStateException
12+
import java.util.*
13+
14+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
15+
class JSONTests {
16+
17+
@Test
18+
fun `get boolean succeeds`() {
19+
20+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(true)))
21+
22+
val keyedValue = jsonObject.getBoolean("keyed")
23+
24+
Assertions.assertTrue(keyedValue ?: false)
25+
}
26+
27+
@Test
28+
fun `get boolean fails`() {
29+
30+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(false)))
31+
32+
val keyedValue = jsonObject.getBoolean("keyed")
33+
34+
Assertions.assertFalse(keyedValue ?: true)
35+
}
36+
37+
@Test
38+
fun `get boolean bad value throws`() {
39+
40+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(18)))
41+
42+
try {
43+
val keyedValue = jsonObject.getBoolean("keyed")
44+
Assertions.assertTrue(keyedValue == null)
45+
} catch (e: Exception) {
46+
Assertions.fail("Should not throw when not boolean`")
47+
}
48+
}
49+
50+
@Test
51+
fun `get boolean optional`() {
52+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(null as Boolean?)))
53+
54+
try {
55+
val keyedValue = jsonObject.getBoolean("keyed")
56+
Assertions.assertTrue(keyedValue == null)
57+
} catch (e: Exception) {
58+
Assertions.fail("Should not throw when null boolean")
59+
}
60+
}
61+
62+
@Test
63+
fun `get normal string succeeds`() {
64+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive("test")))
65+
66+
val keyedValue = jsonObject.getString("keyed")
67+
68+
Assertions.assertTrue(keyedValue.equals("test"))
69+
}
70+
71+
@Test
72+
fun `get normal string fails`() {
73+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive("tes†")))
74+
75+
val keyedValue = jsonObject.getString("keyed")
76+
77+
Assertions.assertFalse(keyedValue.equals("test"))
78+
}
79+
80+
@Test
81+
fun `get string bad value throws`() {
82+
83+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(18)))
84+
85+
try {
86+
val keyedValue = jsonObject.getString("keyed")
87+
Assertions.assertTrue(keyedValue.equals("18"))
88+
} catch (e: Exception) {
89+
Assertions.fail("Should not throw when not int primitive")
90+
}
91+
}
92+
93+
@Test
94+
fun `get string optional`() {
95+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(null as String?)))
96+
97+
try {
98+
val keyedValue = jsonObject.getString("keyed")
99+
Assertions.assertTrue(keyedValue == null)
100+
} catch (e: Exception) {
101+
Assertions.fail("Should not throw when null string")
102+
}
103+
}
104+
105+
@Test
106+
fun `get normal integer succeeds`() {
107+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(18)))
108+
109+
val keyedValue = jsonObject.getInt("keyed")
110+
111+
Assertions.assertTrue(keyedValue?.equals(18) ?: false)
112+
}
113+
114+
@Test
115+
fun `get normal integer fails`() {
116+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(19)))
117+
118+
val keyedValue = jsonObject.getInt("keyed")
119+
120+
Assertions.assertFalse(keyedValue?.equals(18) ?: true)
121+
}
122+
123+
@Test
124+
fun `get integer bad value throws`() {
125+
126+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive("18")))
127+
128+
try {
129+
val keyedValue = jsonObject.getInt("keyed")
130+
Assertions.assertTrue(keyedValue?.equals(18) ?: false)
131+
} catch (e: Exception) {
132+
Assertions.fail("Should not throw when not int primitive")
133+
}
134+
}
135+
136+
@Test
137+
fun `get integer optional`() {
138+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(null as Int?)))
139+
140+
try {
141+
val keyedValue = jsonObject.getInt("keyed")
142+
Assertions.assertTrue(keyedValue == null)
143+
} catch (e: Exception) {
144+
Assertions.fail("Should not throw when null int")
145+
}
146+
}
147+
148+
@Test
149+
fun `get normal double succeeds`() {
150+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(18.0)))
151+
152+
val keyedValue = jsonObject.getDouble("keyed")
153+
154+
Assertions.assertTrue(keyedValue?.equals(18.0) ?: false)
155+
}
156+
157+
@Test
158+
fun `get normal double fails`() {
159+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(19.0)))
160+
161+
val keyedValue = jsonObject.getDouble("keyed")
162+
163+
Assertions.assertFalse(keyedValue?.equals(18.0) ?: true)
164+
}
165+
166+
@Test
167+
fun `get double bad value throws`() {
168+
169+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive("18")))
170+
171+
try {
172+
val keyedValue = jsonObject.getDouble("keyed")
173+
Assertions.assertTrue(keyedValue?.equals(18.0) ?: false)
174+
} catch (e: Exception) {
175+
Assertions.fail("Should not throw when not double primitive")
176+
}
177+
}
178+
179+
@Test
180+
fun `get double optional`() {
181+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(null as Double?)))
182+
183+
try {
184+
val keyedValue = jsonObject.getDouble("keyed")
185+
Assertions.assertTrue(keyedValue == null)
186+
} catch (e: Exception) {
187+
Assertions.fail("Should not throw when null double")
188+
}
189+
}
190+
191+
@Test
192+
fun `get normal string set`() {
193+
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze") }))
194+
195+
val keyedValue = jsonObject.getStringSet("keyed")
196+
197+
Assertions.assertTrue(keyedValue?.count() ?: 0 == 3)
198+
199+
Assertions.assertTrue(keyedValue?.contains("Mr. Freeze") ?: false)
200+
}
201+
202+
@Test
203+
fun `get normal string set with duplicate`() {
204+
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze"); add("batman") }))
205+
206+
val keyedValue = jsonObject.getStringSet("keyed")
207+
208+
// Make sure there is still 3 and that it removed an additional batman
209+
Assertions.assertTrue(keyedValue?.count() ?: 0 == 3)
210+
}
211+
212+
@Test
213+
fun `get normal string set with improper lookup`() {
214+
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze"); add("batman") }))
215+
216+
val keyedValue = jsonObject.getStringSet("keyed")
217+
218+
Assertions.assertFalse(keyedValue?.contains("Penguin") ?: true)
219+
}
220+
221+
@Test
222+
fun `get null lookup for improper keyed type`() {
223+
val jsonObject = JsonObject(mapOf("keyed" to JsonPrimitive(18)))
224+
225+
try {
226+
val keyedValue = jsonObject.getStringSet("keyed")
227+
Assertions.fail("Should not return a set with the wrong primitive")
228+
} catch (e: Exception) {
229+
Assertions.assertTrue(e is IllegalArgumentException)
230+
}
231+
}
232+
233+
@Test
234+
fun `get normal set map`() {
235+
val villainMap = mapOf("villains" to JsonPrimitive("Mr. Freeze"))
236+
val jsonObject = JsonObject(mapOf("keyed" to JsonObject(villainMap)))
237+
238+
val keyedValue = jsonObject.getMapSet("keyed")
239+
240+
Assertions.assertTrue(keyedValue is Set<Map<*, *>>)
241+
242+
Assertions.assertTrue(keyedValue?.contains(villainMap) ?: false)
243+
}
244+
245+
@Test
246+
fun `get normal set map retrieve key value`() {
247+
val villainMap = mapOf("villains" to JsonPrimitive("Mr. Freeze"))
248+
val jsonObject = JsonObject(mapOf("keyed" to JsonObject(villainMap)))
249+
250+
val keyedValue = jsonObject.getMapSet("keyed")
251+
252+
val keyedMap = keyedValue?.first() ?: run {
253+
Assertions.fail("Could not find map")
254+
}
255+
256+
val temp = keyedMap["villains"] as JsonPrimitive
257+
258+
Assertions.assertTrue(temp?.contentOrNull == "Mr. Freeze")
259+
}
260+
261+
@Test
262+
fun `get normal string set map with duplicate`() {
263+
val batmanMap = mapOf("villains" to buildJsonArray { add("Joker"); add("Bain"); add("Mr. Freeze"); add("Bain") },
264+
"heroes" to buildJsonArray { add("Batman"); add("Robin"); add("James Gordon"); add("Catwoman") })
265+
val jsonObject = JsonObject(mapOf("batman" to JsonObject(batmanMap)))
266+
267+
val keyedValue = jsonObject.getMapSet("batman")
268+
269+
// Make sure there is still 4 and that it did not remove an additional Bain
270+
Assertions.assertTrue(keyedValue?.count() ?: 0 == 2)
271+
}
272+
273+
@Test
274+
fun `get normal map with wrong type`() {
275+
val villainMap = mapOf("villains" to JsonPrimitive(18))
276+
val jsonObject = JsonObject(mapOf("keyed" to JsonObject(villainMap)))
277+
278+
val keyedValue = jsonObject.getMapSet("keyed")
279+
280+
val villainNumber = keyedValue?.first() as Map<*, JsonPrimitive>
281+
val retrievedMap = villainNumber["villains"] ?: run {
282+
Assertions.fail("Could not find villains map")
283+
}
284+
285+
// Make sure there is still 4 and that it did not remove an additional Bain
286+
Assertions.assertTrue(retrievedMap.intOrNull == 18)
287+
}
288+
}

samples/kotlin-android-app-destinations/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ dependencies {
4141
// Mixpanel
4242
api 'com.mixpanel.android:mixpanel-android:5.8.7'
4343

44+
// Firebase
45+
implementation 'com.google.firebase:firebase-core:15.0.2'
4446

4547
implementation project(':analytics-kotlin')
4648

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"project_info": {
3+
"project_number": "896388530950",
4+
"project_id": "codyfire-aec37",
5+
"storage_bucket": "codyfire-aec37.appspot.com"
6+
},
7+
"client": [
8+
{
9+
"client_info": {
10+
"mobilesdk_app_id": "1:896388530950:android:05388b0468bcc4fb9b1487",
11+
"android_client_info": {
12+
"package_name": "com.segment.analytics.destinations"
13+
}
14+
},
15+
"oauth_client": [
16+
{
17+
"client_id": "896388530950-athmfbk281ot242c49jg8l50phar0g09.apps.googleusercontent.com",
18+
"client_type": 3
19+
}
20+
],
21+
"api_key": [
22+
{
23+
"current_key": "AIzaSyDrjBK2AfgX1ZL63ypw5vGUSfp1vBOx970"
24+
}
25+
],
26+
"services": {
27+
"appinvite_service": {
28+
"other_platform_oauth_client": [
29+
{
30+
"client_id": "896388530950-athmfbk281ot242c49jg8l50phar0g09.apps.googleusercontent.com",
31+
"client_type": 3
32+
},
33+
{
34+
"client_id": "896388530950-bevk6oulirofbnc87iahub4vth7salm2.apps.googleusercontent.com",
35+
"client_type": 2,
36+
"ios_info": {
37+
"bundle_id": "com.segment.DestinationsExample"
38+
}
39+
}
40+
]
41+
}
42+
}
43+
}
44+
],
45+
"configuration_version": "1"
46+
}

0 commit comments

Comments
 (0)