Skip to content

Commit

Permalink
fix: number parsing coverts to double (customerio#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shahroz16 committed Jan 21, 2022
1 parent 5c8bb0f commit 72a80fe
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 16 deletions.
6 changes: 1 addition & 5 deletions README.md
Expand Up @@ -12,11 +12,7 @@

This is the official Customer.io SDK for Android.

You'll find our [complete SDK documentation at https://customer.io/docs/sdk/android](https://customer.io/docs/sdk/android/). This readme only contains basic information to help you install and initialize the SDK.

**Our SDK is a work in progress!** While we're *very* excited about it, it's still in its alpha phase; it is not ready for general availability. If you want to try it out, contact [product@customer.io](mailto:product@customer.io) and we'll help set you up!

## Summary
# Getting started

The SDK supports both Kotlin and Java.

Expand Down
15 changes: 10 additions & 5 deletions app/src/main/java/io/customer/example/MainActivity.kt
Expand Up @@ -48,11 +48,15 @@ class MainActivity : AppCompatActivity() {
).enqueue(outputCallback)
CustomerIO.instance().track(
name = "int event",
attributes = mapOf("value" to 1)
attributes = mapOf("value" to 1388377266772)
).enqueue(outputCallback)
CustomerIO.instance().track(
name = "long event",
attributes = mapOf("value" to 1L)
attributes = mapOf("value" to 1653L)
).enqueue(outputCallback)
CustomerIO.instance().track(
name = "double event",
attributes = mapOf("value" to 133333.882)
).enqueue(outputCallback)
CustomerIO.instance().track(
name = "array event",
Expand Down Expand Up @@ -87,9 +91,10 @@ class MainActivity : AppCompatActivity() {
CoroutineScope(Dispatchers.IO).launch {
when (
val result =
CustomerIO.instance()
.identify("sample@email.com@email.com", mapOf("speed" to "slow"))
.execute()
CustomerIO.instance().identify(
identifier = "support-ticket-test",
mapOf("created_at" to 1642659790)
).execute()
) {
is ErrorResult -> Log.v("ErrorResult", result.error.cause.toString())
is Success -> Log.v("Success", "Success")
Expand Down
Expand Up @@ -3,6 +3,7 @@ package io.customer.sdk.data.moshi
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.customer.sdk.data.moshi.adapter.BigDecimalAdapter
import io.customer.sdk.data.moshi.adapter.SupportedAttributesFactory

internal interface CustomerIOParser {
Expand All @@ -14,6 +15,7 @@ internal class CustomerIOParserImpl : CustomerIOParser {

private val moshi by lazy {
Moshi.Builder()
.add(BigDecimalAdapter())
.add(SupportedAttributesFactory())
.build()
}
Expand Down
@@ -0,0 +1,13 @@
package io.customer.sdk.data.moshi.adapter

import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
import java.math.BigDecimal

class BigDecimalAdapter {
@FromJson
fun fromJson(string: String) = BigDecimal(string)

@ToJson
fun toJson(value: BigDecimal) = value.toString()
}
Expand Up @@ -2,6 +2,7 @@ package io.customer.sdk.data.moshi.adapter

import com.squareup.moshi.*
import java.lang.reflect.Type
import java.math.BigDecimal

internal class SupportedAttributesFactory : JsonAdapter.Factory {
override fun create(
Expand All @@ -20,6 +21,8 @@ internal class SupportedAttributesAdapter(moshi: Moshi) :
JsonAdapter<Map<String, Any>>() {

private val elementAdapter: JsonAdapter<Any> = moshi.adapter(Any::class.java)
private val elementBigDecimalAdapter: JsonAdapter<BigDecimal> =
moshi.adapter(BigDecimal::class.java)

private val mapAdapter: JsonAdapter<Map<String, Any?>> =
moshi.adapter(
Expand All @@ -37,7 +40,11 @@ internal class SupportedAttributesAdapter(moshi: Moshi) :
try {
val name = reader.nextName()
val peeked = reader.peekJson()
result[name] = elementAdapter.fromJson(peeked)!!
if (peeked.peek() == JsonReader.Token.NUMBER) {
result[name] = elementBigDecimalAdapter.fromJson(peeked)!!
} else {
result[name] = elementAdapter.fromJson(peeked)!!
}
} catch (ignored: JsonDataException) {
}
reader.skipValue()
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/main/java/io/customer/sdk/di/CustomerIOComponent.kt
@@ -1,6 +1,7 @@
package io.customer.sdk.di

import android.content.Context
import com.squareup.moshi.Moshi
import io.customer.sdk.BuildConfig
import io.customer.sdk.CustomerIOClient
import io.customer.sdk.CustomerIOConfig
Expand All @@ -12,6 +13,7 @@ import io.customer.sdk.api.service.CustomerService
import io.customer.sdk.api.service.PushService
import io.customer.sdk.data.moshi.CustomerIOParser
import io.customer.sdk.data.moshi.CustomerIOParserImpl
import io.customer.sdk.data.moshi.adapter.BigDecimalAdapter
import io.customer.sdk.data.store.*
import io.customer.sdk.repository.*
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -88,6 +90,14 @@ internal class CustomerIOComponent(
}
}

private val retrofitMoshiConverterFactory by lazy {
MoshiConverterFactory.create(
Moshi.Builder()
.add(BigDecimalAdapter())
.build()
)
}

private fun buildRetrofit(
endpoint: String,
timeout: Long
Expand All @@ -96,7 +106,7 @@ internal class CustomerIOComponent(
return Retrofit.Builder()
.baseUrl(endpoint)
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create())
.addConverterFactory(retrofitMoshiConverterFactory)
.addCallAdapterFactory(CustomerIoCallAdapterFactory.create())
.build()
}
Expand Down
Expand Up @@ -35,16 +35,18 @@ internal class AttributesRepositoryTest {
val result = attributesRepository.mapToJson(mapOf("key" to 1, "key2" to 2))

// JSON only has numbers. Not integers or doubles. And since numbers can have decimals they are always represented as doubles in Java.
val expected = mapOf("key" to 1, "key2" to 2).mapValues { it.value.toDouble() }
val expected = mapOf("key" to 1, "key2" to 2).mapValues { it.value.toBigDecimal() }

(result == expected).shouldBeTrue()
}

@Test
fun `Verify Long attributes are mapped correctly`() {
val expected = mapOf("key" to 1.0, "key2" to 2.0)
val expected =
sortedMapOf("key" to 1.0, "key2" to 2.0).mapValues { it.value.toBigDecimal() }

val result = attributesRepository.mapToJson(mapOf("key" to 1.0, "key2" to 2.0))
val result =
attributesRepository.mapToJson(mutableMapOf("key" to 1.0, "key2" to 2.0)).toSortedMap()

(result == expected).shouldBeTrue()
}
Expand All @@ -53,7 +55,7 @@ internal class AttributesRepositoryTest {
fun `Verify Date attributes are mapped correctly`() {

val date = Date()
val expected = mapOf("key" to date.getUnixTimestamp().toDouble())
val expected = mapOf("key" to date.getUnixTimestamp().toBigDecimal())

// even if Date is sent, unix timestamp should be mapped
val result = attributesRepository.mapToJson(mapOf("key" to date))
Expand Down

0 comments on commit 72a80fe

Please sign in to comment.