Skip to content

Commit

Permalink
feat: changes for react native package
Browse files Browse the repository at this point in the history
  • Loading branch information
mrehan27 committed Aug 12, 2022
1 parent fd7ae28 commit 2f20ac3
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 35 deletions.
12 changes: 6 additions & 6 deletions common-test/src/main/java/io/customer/commontest/BaseTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ import androidx.test.platform.app.InstrumentationRegistry
import io.customer.commontest.util.DispatchersProviderStub
import io.customer.sdk.CustomerIOConfig
import io.customer.sdk.data.model.Region
import io.customer.sdk.data.store.Client
import io.customer.sdk.data.store.DeviceStore
import io.customer.sdk.di.CustomerIOComponent
import io.customer.sdk.module.CustomerIOModuleConfig
import io.customer.sdk.util.CioLogLevel
import io.customer.sdk.util.DateUtil
import io.customer.sdk.util.DispatchersProvider
import io.customer.sdk.util.JsonAdapter
import io.customer.sdk.util.Seconds
import io.customer.sdk.util.*
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
Expand All @@ -38,7 +35,7 @@ abstract class BaseTest {

protected lateinit var cioConfig: CustomerIOConfig

protected val deviceStore: DeviceStore = DeviceStoreStub().deviceStore
protected lateinit var deviceStore: DeviceStore
protected lateinit var dispatchersProviderStub: DispatchersProviderStub

protected lateinit var di: CustomerIOComponent
Expand All @@ -53,6 +50,7 @@ abstract class BaseTest {
protected lateinit var dateUtilStub: DateUtilStub

protected fun createConfig(
client: Client = Client.Android,
siteId: String = this.siteId,
apiKey: String = "xyz",
region: Region = Region.EU,
Expand All @@ -67,6 +65,7 @@ abstract class BaseTest {
targetSdkVersion: Int = android.os.Build.VERSION_CODES.R,
configurations: Map<String, CustomerIOModuleConfig> = emptyMap()
) = CustomerIOConfig(
client = client,
siteId = siteId,
apiKey = apiKey,
region = region,
Expand Down Expand Up @@ -107,6 +106,7 @@ abstract class BaseTest {
dateUtilStub = DateUtilStub().also {
di.overrideDependency(DateUtil::class.java, it)
}
deviceStore = DeviceStoreStub().getDeviceStore(cioConfig)
dispatchersProviderStub = DispatchersProviderStub().also {
di.overrideDependency(DispatchersProvider::class.java, it)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.customer.commontest

import io.customer.sdk.CustomerIOConfig
import io.customer.sdk.data.store.ApplicationStore
import io.customer.sdk.data.store.BuildStore
import io.customer.sdk.data.store.DeviceStore
Expand All @@ -8,8 +9,9 @@ import java.util.*

class DeviceStoreStub {

val deviceStore: DeviceStore
get() = DeviceStoreImp(
fun getDeviceStore(cioConfig: CustomerIOConfig): DeviceStore {
return DeviceStoreImp(
sdkConfig = cioConfig,
buildStore = object : BuildStore {
override val deviceBrand: String
get() = "Google"
Expand All @@ -34,4 +36,5 @@ class DeviceStoreStub {
},
version = "1.0.0-alpha.6"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ import io.customer.sdk.module.CustomerIOModuleConfig
* In app messaging module configurations that can be used to customize app
* experience based on the provided configurations
*/
class MessagingInAppModuleConfig : CustomerIOModuleConfig
class MessagingInAppModuleConfig private constructor() : CustomerIOModuleConfig {
class Builder : CustomerIOModuleConfig.Builder<MessagingInAppModuleConfig> {
override fun build(): MessagingInAppModuleConfig {
return MessagingInAppModuleConfig()
}
}

companion object {
internal fun default(): MessagingInAppModuleConfig = Builder().build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import io.customer.sdk.module.CustomerIOModule
import io.customer.sdk.repository.TrackRepository

class ModuleMessagingInApp internal constructor(
override val moduleConfig: MessagingInAppModuleConfig = MessagingInAppModuleConfig(),
override val moduleConfig: MessagingInAppModuleConfig = MessagingInAppModuleConfig.default(),
private val overrideDiGraph: CustomerIOComponent?,
private val organizationId: String
) : CustomerIOModule<MessagingInAppModuleConfig> {

@JvmOverloads
constructor(
organizationId: String,
config: MessagingInAppModuleConfig = MessagingInAppModuleConfig()
config: MessagingInAppModuleConfig = MessagingInAppModuleConfig.default()
) : this(
moduleConfig = config,
overrideDiGraph = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal class CustomerIOPushReceiver : BroadcastReceiver() {
val deliveryId = payload?.cioDeliveryId
val deliveryToken = payload?.cioDeliveryToken

if (deliveryId != null && deliveryToken != null) {
if (deliveryId != null && deliveryToken != null && moduleConfig.autoTrackPushEvents) {
CustomerIO.instance().trackMetric(deliveryId, MetricEvent.opened, deliveryToken)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,63 @@ import io.customer.sdk.module.CustomerIOModuleConfig
* @property redirectDeepLinksToOtherApps flag to support opening urls from
* notification to other native apps or browsers; default true
*/
class MessagingPushModuleConfig @JvmOverloads constructor(
val notificationCallback: CustomerIOPushNotificationCallback? = null,
val redirectDeepLinksToOtherApps: Boolean = true
) : CustomerIOModuleConfig
class MessagingPushModuleConfig private constructor(
val autoTrackPushEvents: Boolean,
val notificationCallback: CustomerIOPushNotificationCallback?,
val redirectDeepLinksToOtherApps: Boolean
) : CustomerIOModuleConfig {
class Builder : CustomerIOModuleConfig.Builder<MessagingPushModuleConfig> {
private var autoTrackPushEvents: Boolean = true
private var notificationCallback: CustomerIOPushNotificationCallback? = null
private var redirectDeepLinksToOtherApps: Boolean = true

/**
* Allows to enable/disable automatic tracking of push events. Auto tracking will generate
* opened and delivered metrics for push notifications sent by Customer.io without
* any additional code
*
* @param autoTrackPushEvents true to enable auto tracking, false otherwise; default true
*/
fun setAutoTrackPushEvents(autoTrackPushEvents: Boolean): Builder {
this.autoTrackPushEvents = autoTrackPushEvents
return this
}

/**
* Callback that notifies client on push notification related actions.
*
* @param notificationCallback listener to receive callback events
*/
fun setNotificationCallback(notificationCallback: CustomerIOPushNotificationCallback): Builder {
this.notificationCallback = notificationCallback
return this
}

/**
* Allows to enable/disable opening non app links outside the app
* <p>
* true: links not supported by apps will be opened in other matching apps,
* if no matching apps are found, host app will be launched to default landing page
* false: links not supported will only open the host app to its default landing page
*
* @param redirectDeepLinksToOtherApps flag to support opening urls from
* notification to other native apps or browsers; default true
*/
fun setRedirectDeepLinksToOtherApps(redirectDeepLinksToOtherApps: Boolean): Builder {
this.redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps
return this
}

override fun build(): MessagingPushModuleConfig {
return MessagingPushModuleConfig(
autoTrackPushEvents = autoTrackPushEvents,
notificationCallback = notificationCallback,
redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps
)
}
}

companion object {
internal fun default(): MessagingPushModuleConfig = Builder().build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import io.customer.sdk.di.CustomerIOComponent
import io.customer.sdk.module.CustomerIOModule

class ModuleMessagingPushFCM internal constructor(
override val moduleConfig: MessagingPushModuleConfig = MessagingPushModuleConfig(),
override val moduleConfig: MessagingPushModuleConfig = MessagingPushModuleConfig.default(),
private val overrideCustomerIO: CustomerIOInstance?,
private val overrideDiGraph: CustomerIOComponent?
) : CustomerIOModule<MessagingPushModuleConfig> {

@JvmOverloads
constructor(config: MessagingPushModuleConfig = MessagingPushModuleConfig()) : this(
constructor(config: MessagingPushModuleConfig = MessagingPushModuleConfig.default()) : this(
moduleConfig = config,
overrideCustomerIO = null,
overrideDiGraph = null
Expand All @@ -34,7 +34,11 @@ class ModuleMessagingPushFCM internal constructor(
override fun initialize() {
getCurrentFcmToken()
diGraph.activityLifecycleCallbacks.registerCallback(
MessagingPushLifecycleCallback(diGraph.deepLinkUtil, diGraph.pushTrackingUtil)
MessagingPushLifecycleCallback(
moduleConfig = moduleConfig,
deepLinkUtil = diGraph.deepLinkUtil,
pushTrackingUtil = diGraph.pushTrackingUtil
)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import android.app.Activity
import android.content.Context
import android.os.Bundle
import androidx.lifecycle.Lifecycle
import io.customer.messagingpush.MessagingPushModuleConfig
import io.customer.messagingpush.util.DeepLinkUtil
import io.customer.messagingpush.util.PushTrackingUtil
import io.customer.sdk.lifecycle.LifecycleCallback

internal class MessagingPushLifecycleCallback internal constructor(
private val moduleConfig: MessagingPushModuleConfig,
private val deepLinkUtil: DeepLinkUtil,
private val pushTrackingUtil: PushTrackingUtil
) : LifecycleCallback {
Expand All @@ -19,7 +21,9 @@ internal class MessagingPushLifecycleCallback internal constructor(
Lifecycle.Event.ON_CREATE -> {
val intentArguments = activity.intent.extras ?: return

pushTrackingUtil.parseLaunchedActivityForTracking(intentArguments)
if (moduleConfig.autoTrackPushEvents) {
pushTrackingUtil.parseLaunchedActivityForTracking(intentArguments)
}
launchContentAction(
activity,
intentArguments.getString(PENDING_CONTENT_ACTION_LINK)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,42 @@ internal class ModuleMessagingConfigTest : BaseTest() {
@Test
fun initialize_givenEmptyConfig_expectDefaultValues() {
val module = ModuleMessagingPushFCM(
moduleConfig = MessagingPushModuleConfig(),
moduleConfig = MessagingPushModuleConfig.default(),
overrideCustomerIO = customerIOMock,
overrideDiGraph = di
)

configurations[ModuleMessagingPushFCM.MODULE_NAME] = module.moduleConfig
val moduleConfig = di.moduleConfig

moduleConfig.autoTrackPushEvents.shouldBeTrue()
moduleConfig.notificationCallback.shouldBeNull()
moduleConfig.redirectDeepLinksToOtherApps.shouldBeTrue()
}

@Test
fun initialize_givenCustomConfig_expectCustomValues() {
val module = ModuleMessagingPushFCM(
moduleConfig = MessagingPushModuleConfig(
notificationCallback = object : CustomerIOPushNotificationCallback {
override fun createTaskStackFromPayload(
context: Context,
payload: CustomerIOParsedPushPayload
): TaskStackBuilder? = null
},
redirectDeepLinksToOtherApps = false
),
moduleConfig = MessagingPushModuleConfig.Builder().apply {
setAutoTrackPushEvents(false)
setNotificationCallback(
object : CustomerIOPushNotificationCallback {
override fun createTaskStackFromPayload(
context: Context,
payload: CustomerIOParsedPushPayload
): TaskStackBuilder? = null
}
)
setRedirectDeepLinksToOtherApps(false)
}.build(),
overrideCustomerIO = customerIOMock,
overrideDiGraph = di
)

configurations[ModuleMessagingPushFCM.MODULE_NAME] = module.moduleConfig
val moduleConfig = di.moduleConfig

moduleConfig.autoTrackPushEvents.shouldBeFalse()
moduleConfig.notificationCallback.shouldNotBeNull()
moduleConfig.redirectDeepLinksToOtherApps.shouldBeFalse()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class ModuleMessagingPushFCMTest : BaseTest() {
super.setup()

di.overrideDependency(DeviceTokenProvider::class.java, fcmTokenProviderMock)
di.overrideDependency(MessagingPushModuleConfig::class.java, MessagingPushModuleConfig())
di.overrideDependency(MessagingPushModuleConfig::class.java, MessagingPushModuleConfig.default())

module = ModuleMessagingPushFCM(overrideCustomerIO = customerIOMock, overrideDiGraph = di)
}
Expand Down
36 changes: 34 additions & 2 deletions sdk/src/main/java/io/customer/sdk/CustomerIO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.content.pm.PackageManager
import io.customer.sdk.data.model.CustomAttributes
import io.customer.sdk.data.model.Region
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.data.store.Client
import io.customer.sdk.di.CustomerIOComponent
import io.customer.sdk.extensions.getScreenNameFromActivity
import io.customer.sdk.module.CustomerIOModule
Expand Down Expand Up @@ -104,13 +105,21 @@ class CustomerIO internal constructor(
private var region: Region = Region.US,
private val appContext: Application
) {
private var client: Client = Client.Android
private var timeout = 6000L
private var shouldAutoRecordScreenViews: Boolean = false
private var autoTrackDeviceAttributes: Boolean = true
private val modules: MutableMap<String, CustomerIOModule<out CustomerIOModuleConfig>> = mutableMapOf()
private var logLevel = CioLogLevel.ERROR
internal var overrideDiGraph: CustomerIOComponent? = null // set for automated tests
private var trackingApiUrl: String? = null
private var backgroundQueueMinNumberOfTasks: Int = 10
private var backgroundQueueSecondsDelay: Double = 30.0

fun setClient(client: Client): Builder {
this.client = client
return this
}

fun setRegion(region: Region): Builder {
this.region = region
Expand Down Expand Up @@ -146,6 +155,28 @@ class CustomerIO internal constructor(
return this
}

/**
* Sets the number of tasks in the background queue before the queue begins operating.
* This is mostly used during development to test configuration is setup. We do not recommend
* modifying this value because it impacts battery life of mobile device.
*
* @param backgroundQueueMinNumberOfTasks the minimum number of tasks in background queue; default 10
*/
fun setBackgroundQueueMinNumberOfTasks(backgroundQueueMinNumberOfTasks: Int): Builder {
this.backgroundQueueMinNumberOfTasks = backgroundQueueMinNumberOfTasks
return this
}

/**
* Sets the number of seconds to delay running queue after a task has been added to it
*
* @param backgroundQueueSecondsDelay time in seconds to delay events; default 30
*/
fun setBackgroundQueueSecondsDelay(backgroundQueueSecondsDelay: Double): Builder {
this.backgroundQueueSecondsDelay = backgroundQueueSecondsDelay
return this
}

fun <Config : CustomerIOModuleConfig> addCustomerIOModule(module: CustomerIOModule<Config>): Builder {
modules[module.moduleName] = module
return this
Expand All @@ -161,14 +192,15 @@ class CustomerIO internal constructor(
}

val config = CustomerIOConfig(
client = client,
siteId = siteId,
apiKey = apiKey,
region = region,
timeout = timeout,
autoTrackScreenViews = shouldAutoRecordScreenViews,
autoTrackDeviceAttributes = autoTrackDeviceAttributes,
backgroundQueueMinNumberOfTasks = 10,
backgroundQueueSecondsDelay = 30.0,
backgroundQueueMinNumberOfTasks = backgroundQueueMinNumberOfTasks,
backgroundQueueSecondsDelay = backgroundQueueSecondsDelay,
backgroundQueueTaskExpiredSeconds = Seconds.fromDays(3).value,
logLevel = logLevel,
trackingApiUrl = trackingApiUrl,
Expand Down
2 changes: 2 additions & 0 deletions sdk/src/main/java/io/customer/sdk/CustomerIOConfig.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package io.customer.sdk

import io.customer.sdk.data.model.Region
import io.customer.sdk.data.store.Client
import io.customer.sdk.module.CustomerIOModuleConfig
import io.customer.sdk.util.CioLogLevel

data class CustomerIOConfig(
val client: Client,
val siteId: String,
val apiKey: String,
val region: Region,
Expand Down
Loading

0 comments on commit 2f20ac3

Please sign in to comment.