Skip to content

Commit 494e6e5

Browse files
authored
add new helpers for destinations (#18)
1 parent b93ff18 commit 494e6e5

File tree

4 files changed

+144
-5
lines changed

4 files changed

+144
-5
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,34 @@ package com.segment.analytics.kotlin.core
33
import com.segment.analytics.kotlin.core.platform.plugins.LogType
44
import com.segment.analytics.kotlin.core.platform.plugins.log
55
import kotlinx.coroutines.launch
6+
import kotlinx.serialization.DeserializationStrategy
67
import kotlinx.serialization.Serializable
78
import kotlinx.serialization.decodeFromString
89
import kotlinx.serialization.json.Json
910
import kotlinx.serialization.json.JsonObject
11+
import kotlinx.serialization.json.jsonObject
12+
import kotlinx.serialization.serializer
1013
import java.io.BufferedReader
1114

1215
@Serializable
1316
data class Settings(
1417
var integrations: JsonObject = emptyJsonObject,
1518
var plan: JsonObject = emptyJsonObject,
1619
var edgeFunction: JsonObject = emptyJsonObject,
17-
)
20+
) {
21+
inline fun <reified T : Any> destinationSettings(
22+
name: String,
23+
strategy: DeserializationStrategy<T> = Json.serializersModule.serializer()
24+
): T? {
25+
val integrationData = integrations[name]?.jsonObject ?: return null
26+
val typedSettings = Json.decodeFromJsonElement(strategy, integrationData)
27+
return typedSettings
28+
}
29+
30+
fun isDestinationEnabled(name: String): Boolean {
31+
return integrations.containsKey(name)
32+
}
33+
}
1834

1935
internal fun Analytics.update(settings: Settings) {
2036
timeline.applyClosure { plugin ->

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,13 @@ fun JsonObject.getMapSet(key: String): Set<Map<String, Any>>? {
8282
else
8383
null
8484
}
85+
86+
// Utility function to transform keys in JsonObject. Only acts on root level keys
87+
fun JsonObject.transformKeys(transform: (String) -> String): JsonObject {
88+
return JsonObject(this.mapKeys { transform(it.key) })
89+
}
90+
91+
// Utility function to transform values in JsonObject. Only acts on root level values
92+
fun JsonObject.transformValues(transform: (JsonElement) -> JsonElement): JsonObject {
93+
return JsonObject(this.mapValues { transform(it.value) })
94+
}

core/src/test/kotlin/com/segment/analytics/kotlin/core/JSONTests.kt

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import com.segment.analytics.kotlin.core.utilities.getInt
66
import com.segment.analytics.kotlin.core.utilities.getMapSet
77
import com.segment.analytics.kotlin.core.utilities.getString
88
import com.segment.analytics.kotlin.core.utilities.getStringSet
9+
import com.segment.analytics.kotlin.core.utilities.transformKeys
10+
import com.segment.analytics.kotlin.core.utilities.transformValues
911
import kotlinx.serialization.json.*
12+
import org.junit.jupiter.api.Assertions.assertEquals
1013
import org.junit.jupiter.api.Assertions.assertTrue
1114
import org.junit.jupiter.api.Assertions.assertFalse
1215
import org.junit.jupiter.api.Assertions.fail
@@ -193,7 +196,8 @@ class JSONTests {
193196

194197
@Test
195198
fun `get normal string set`() {
196-
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze") }))
199+
val jsonObject =
200+
JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze") }))
197201

198202
val keyedValue = jsonObject.getStringSet("keyed")
199203

@@ -204,7 +208,9 @@ class JSONTests {
204208

205209
@Test
206210
fun `get normal string set with duplicate`() {
207-
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze"); add("batman") }))
211+
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray {
212+
add("joker"); add("batman"); add("Mr. Freeze"); add("batman")
213+
}))
208214

209215
val keyedValue = jsonObject.getStringSet("keyed")
210216

@@ -214,7 +220,9 @@ class JSONTests {
214220

215221
@Test
216222
fun `get normal string set with improper lookup`() {
217-
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray { add("joker"); add("batman"); add("Mr. Freeze"); add("batman") }))
223+
val jsonObject = JsonObject(mapOf("keyed" to buildJsonArray {
224+
add("joker"); add("batman"); add("Mr. Freeze"); add("batman")
225+
}))
218226

219227
val keyedValue = jsonObject.getStringSet("keyed")
220228

@@ -263,7 +271,8 @@ class JSONTests {
263271

264272
@Test
265273
fun `get normal string set map with duplicate`() {
266-
val batmanMap = mapOf("villains" to buildJsonArray { add("Joker"); add("Bain"); add("Mr. Freeze"); add("Bain") },
274+
val batmanMap =
275+
mapOf("villains" to buildJsonArray { add("Joker"); add("Bain"); add("Mr. Freeze"); add("Bain") },
267276
"heroes" to buildJsonArray { add("Batman"); add("Robin"); add("James Gordon"); add("Catwoman") })
268277
val jsonObject = JsonObject(mapOf("batman" to JsonObject(batmanMap)))
269278

@@ -288,4 +297,44 @@ class JSONTests {
288297
// Make sure there is still 4 and that it did not remove an additional Bain
289298
assertTrue(retrievedMap.intOrNull == 18)
290299
}
300+
301+
@Test
302+
fun `transformKeys transforms keys correctly`() {
303+
val map = buildJsonObject {
304+
put("Joker", true)
305+
put("Catwoman", false)
306+
put("Mr. Freeze", true)
307+
}
308+
309+
val newMap = map.transformKeys { it.toUpperCase() }
310+
311+
with(newMap) {
312+
assertTrue(containsKey("JOKER"))
313+
assertTrue(containsKey("CATWOMAN"))
314+
assertTrue(containsKey("MR. FREEZE"))
315+
}
316+
}
317+
318+
@Test
319+
fun `transformValues transforms values correctly`() {
320+
val map = buildJsonObject {
321+
put("Joker", true)
322+
put("Catwoman", false)
323+
put("Mr. Freeze", true)
324+
}
325+
326+
val newMap = map.transformValues {
327+
if (it.jsonPrimitive.boolean) {
328+
JsonPrimitive("M")
329+
} else {
330+
JsonPrimitive("F")
331+
}
332+
}
333+
334+
with(newMap) {
335+
assertEquals("M", getString("Joker"))
336+
assertEquals("F", getString("Catwoman"))
337+
assertEquals("M", getString("Mr. Freeze"))
338+
}
339+
}
291340
}

core/src/test/kotlin/com/segment/analytics/kotlin/core/SettingsTests.kt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ import io.mockk.*
55
import kotlinx.coroutines.runBlocking
66
import kotlinx.coroutines.test.TestCoroutineDispatcher
77
import kotlinx.coroutines.test.TestCoroutineScope
8+
import kotlinx.serialization.Serializable
89
import kotlinx.serialization.json.buildJsonObject
910
import kotlinx.serialization.json.put
1011
import org.junit.jupiter.api.Assertions
12+
import org.junit.jupiter.api.Assertions.assertEquals
13+
import org.junit.jupiter.api.Assertions.assertFalse
14+
import org.junit.jupiter.api.Assertions.assertNotNull
15+
import org.junit.jupiter.api.Assertions.assertTrue
1116
import org.junit.jupiter.api.BeforeEach
1217
import org.junit.jupiter.api.Test
1318
import java.io.ByteArrayInputStream
@@ -86,4 +91,63 @@ class SettingsTests {
8691
)
8792
}
8893
}
94+
95+
@Test
96+
fun `isDestinationEnabled returns true when present`() {
97+
val settings = Settings(
98+
integrations = buildJsonObject {
99+
put("Foo", buildJsonObject {
100+
put("configA", true)
101+
})
102+
put("Bar", buildJsonObject {
103+
put("configC", 10)
104+
})
105+
}
106+
)
107+
108+
assertTrue(settings.isDestinationEnabled("Foo"))
109+
assertTrue(settings.isDestinationEnabled("Bar"))
110+
}
111+
112+
@Test
113+
fun `isDestinationEnabled returns false when absent`() {
114+
val settings = Settings(
115+
integrations = buildJsonObject {
116+
put("Foo", buildJsonObject {
117+
put("configA", true)
118+
})
119+
}
120+
)
121+
122+
assertTrue(settings.isDestinationEnabled("Foo"))
123+
assertFalse(settings.isDestinationEnabled("Bar"))
124+
}
125+
126+
@Serializable
127+
data class FooConfig(
128+
var configA: Boolean,
129+
var configB: Int,
130+
var configC: String
131+
)
132+
133+
@Test
134+
fun `can fetch typed settings correctly`() {
135+
val settings = Settings(
136+
integrations = buildJsonObject {
137+
put("Foo", buildJsonObject {
138+
put("configA", true)
139+
put("configB", 10)
140+
put("configC", "something")
141+
})
142+
}
143+
)
144+
145+
val typedSettings = settings.destinationSettings<FooConfig>("Foo")
146+
assertNotNull(typedSettings)
147+
with(typedSettings!!) {
148+
assertTrue(configA)
149+
assertEquals(10, configB)
150+
assertEquals("something", configC)
151+
}
152+
}
89153
}

0 commit comments

Comments
 (0)