Skip to content

Commit

Permalink
feat: in-app feature no longer requires orgId (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shahroz16 committed Jan 26, 2023
1 parent 44cc4d1 commit fc2a08e
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 36 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/io.customer/android/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object Versions {
internal const val FIREBASE_MESSAGING = "23.1.0"
internal const val GRADLE_NEXUS_PUBLISH_PLUGIN = "1.1.0"
internal const val GRADLE_VERSIONS_PLUGIN = "0.39.0"
internal const val GIST = "2.3.0"
internal const val GIST = "3.0.2"
internal const val GOOGLE_PLAY_SERVICES_BASE = "17.6.0"
internal const val KLUENT = "1.72"
internal const val KOTLIN_BINARY_VALIDATOR = "0.10.1"
Expand Down
3 changes: 3 additions & 0 deletions messaginginapp/api/messaginginapp.api
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public final class io/customer/messaginginapp/MessagingInAppModuleConfig$Compani
}

public final class io/customer/messaginginapp/ModuleMessagingInApp : io/customer/sdk/module/CustomerIOModule {
public fun <init> ()V
public fun <init> (Lio/customer/messaginginapp/MessagingInAppModuleConfig;)V
public synthetic fun <init> (Lio/customer/messaginginapp/MessagingInAppModuleConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Lio/customer/messaginginapp/MessagingInAppModuleConfig;)V
public synthetic fun <init> (Ljava/lang/String;Lio/customer/messaginginapp/MessagingInAppModuleConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
9 changes: 9 additions & 0 deletions messaginginapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ android {
}
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
freeCompilerArgs += [
'-Xopt-in=kotlin.RequiresOptIn',
'-Xopt-in=io.customer.base.internal.InternalCustomerIOApi',
]
}
}

dependencies {
api project(":base")
api project(":sdk")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
package io.customer.messaginginapp

import android.app.Application
import androidx.annotation.VisibleForTesting
import io.customer.base.internal.InternalCustomerIOApi
import io.customer.messaginginapp.di.gistProvider
import io.customer.messaginginapp.hook.ModuleInAppHookProvider
import io.customer.sdk.CustomerIO
import io.customer.sdk.CustomerIOConfig
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.di.CustomerIOComponent
import io.customer.sdk.hooks.HookModule
import io.customer.sdk.hooks.HooksManager
import io.customer.sdk.module.CustomerIOModule
import io.customer.sdk.repository.TrackRepository

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

@JvmOverloads
@Deprecated(
"organizationId no longer required and will be removed in future",
replaceWith = ReplaceWith("constructor(config: MessagingInAppModuleConfig)")
)
constructor(
organizationId: String,
config: MessagingInAppModuleConfig = MessagingInAppModuleConfig.default()
) : this(
moduleConfig = config,
overrideDiGraph = null,
organizationId = organizationId
overrideDiGraph = null
)

@JvmOverloads
constructor(
config: MessagingInAppModuleConfig = MessagingInAppModuleConfig.default()
) : this(
moduleConfig = config,
overrideDiGraph = null
)

override val moduleName: String
Expand All @@ -45,8 +61,11 @@ class ModuleMessagingInApp internal constructor(

private val logger by lazy { diGraph.logger }

private val config: CustomerIOConfig
get() = diGraph.sdkConfig

override fun initialize() {
initializeGist(organizationId)
initializeGist(config)
setupHooks()
configureSdkModule(moduleConfig)
setupGistCallbacks()
Expand All @@ -59,25 +78,21 @@ class ModuleMessagingInApp internal constructor(
}

private fun setupGistCallbacks() {
gistProvider.subscribeToEvents(
onMessageShown = { deliveryID ->
logger.debug("in-app message shown $deliveryID")
trackRepository.trackInAppMetric(
deliveryID = deliveryID,
event = MetricEvent.opened
)
},
onAction = { deliveryID: String, _: String, _: String, _: String ->
gistProvider.subscribeToEvents(onMessageShown = { deliveryID ->
logger.debug("in-app message shown $deliveryID")
trackRepository.trackInAppMetric(
deliveryID = deliveryID,
event = MetricEvent.opened
)
}, onAction = { deliveryID: String, _: String, _: String, _: String ->
logger.debug("in-app message clicked $deliveryID")
trackRepository.trackInAppMetric(
deliveryID = deliveryID,
event = MetricEvent.clicked
)
},
onError = { errorMessage ->
}, onError = { errorMessage ->
logger.error("in-app message error occurred $errorMessage")
}
)
})
}

private fun setupHooks() {
Expand All @@ -87,10 +102,11 @@ class ModuleMessagingInApp internal constructor(
)
}

private fun initializeGist(organizationId: String) {
private fun initializeGist(config: CustomerIOConfig) {
gistProvider.initProvider(
application = diGraph.context.applicationContext as Application,
organizationId = organizationId
siteId = config.siteId,
region = config.region.code
)

// if identifier is already present, set the userToken again so in case if the customer was already identified and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import build.gist.presentation.GistSdk
* Wrapper around Gist Apis
*/
internal interface GistApi {
fun initProvider(application: Application, organizationId: String)
fun initProvider(application: Application, siteId: String, dataCenter: String)
fun setUserToken(userToken: String)
fun setCurrentRoute(route: String)
fun clearUserToken()
Expand All @@ -23,10 +23,11 @@ internal interface GistApi {
}

internal class GistApiProvider : GistApi {
override fun initProvider(application: Application, organizationId: String) {
override fun initProvider(application: Application, siteId: String, dataCenter: String) {
GistSdk.init(
application = application,
organizationId = organizationId
siteId = siteId,
dataCenter = dataCenter
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.customer.messaginginapp.type.InAppEventListener
import io.customer.messaginginapp.type.InAppMessage

internal interface InAppMessagesProvider {
fun initProvider(application: Application, organizationId: String)
fun initProvider(application: Application, siteId: String, region: String)
fun setUserToken(userToken: String)
fun setCurrentRoute(route: String)
fun clearUserToken()
Expand All @@ -31,8 +31,8 @@ internal class GistInAppMessagesProvider(private val provider: GistApi) :
provider.addListener(this)
}

override fun initProvider(application: Application, organizationId: String) {
provider.initProvider(application, organizationId)
override fun initProvider(application: Application, siteId: String, region: String) {
provider.initProvider(application, siteId, dataCenter = region)
}

override fun setUserToken(userToken: String) {
Expand Down Expand Up @@ -74,7 +74,11 @@ internal class GistInAppMessagesProvider(private val provider: GistApi) :
override fun embedMessage(message: Message, elementId: String) {}

override fun onAction(message: Message, currentRoute: String, action: String, name: String) {
listener?.messageActionTaken(InAppMessage.getFromGistMessage(message), action = action, name = name)
listener?.messageActionTaken(
InAppMessage.getFromGistMessage(message),
action = action,
name = name
)
}

override fun onError(message: Message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.customer.commontest.BaseTest
import io.customer.messaginginapp.provider.InAppMessagesProvider
import io.customer.messaginginapp.type.InAppEventListener
import io.customer.sdk.extensions.random
import io.customer.sdk.hooks.HookModule
import io.customer.sdk.hooks.HooksManager
import io.customer.sdk.repository.preference.SitePreferenceRepository
import org.amshove.kluent.shouldBe
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.*
import java.lang.reflect.Field

@RunWith(AndroidJUnit4::class)
internal class ModuleMessagingInAppTest : BaseTest() {
Expand All @@ -32,17 +35,20 @@ internal class ModuleMessagingInAppTest : BaseTest() {
module = ModuleMessagingInApp(
moduleConfig = MessagingInAppModuleConfig.Builder().setEventListener(eventListenerMock)
.build(),
overrideDiGraph = di,
organizationId = "test"
overrideDiGraph = di
)
}

@Test
fun initialize_givenComponentInitialize_expectGistToInitializeWithCorrectOrganizationId_expectModuleHookToBeAdded_expectSubscriptionOfGistCallbacks() {
fun initialize_givenComponentInitialize_expectGistToInitializeWithCorrectValuesAndHooks() {
module.initialize()

// verify gist is initialized
verify(gistInAppMessagesProvider).initProvider(any(), eq("test"))
verify(gistInAppMessagesProvider).initProvider(
any(),
eq(cioConfig.siteId),
eq(cioConfig.region.code)
)

// verify hook was added
verify(hooksManager).add(eq(HookModule.MessagingInApp), any())
Expand All @@ -61,7 +67,11 @@ internal class ModuleMessagingInAppTest : BaseTest() {
module.initialize()

// verify gist is initialized
verify(gistInAppMessagesProvider).initProvider(any(), eq("test"))
verify(gistInAppMessagesProvider).initProvider(
any(),
eq(cioConfig.siteId),
eq(cioConfig.region.code)
)

// verify gist sets userToken
verify(gistInAppMessagesProvider).setUserToken(eq("identifier"))
Expand All @@ -72,9 +82,34 @@ internal class ModuleMessagingInAppTest : BaseTest() {
module.initialize()

// verify gist is initialized
verify(gistInAppMessagesProvider).initProvider(any(), eq("test"))
verify(gistInAppMessagesProvider).initProvider(
any(),
eq(cioConfig.siteId),
eq(cioConfig.region.code)
)

// verify gist doesn't userToken
verify(gistInAppMessagesProvider, never()).setUserToken(any())
}

@Test
fun initialize_givenComponentInitializedWithOrganizationId_expectOrganizationIdToBeIgnored() {
// since `organizationId` is a private member, to check if its being used we have to use reflection
// this test will be deleted when the deprecated variable is removed

val orgId = String.random
val module = ModuleMessagingInApp(
organizationId = orgId
)
val fields = ModuleMessagingInApp::class.java.declaredFields
var organizationId: Field? = null
for (field in fields) {
if (field.name == "organizationId") {
organizationId = field
break
}
}
organizationId?.isAccessible = true
(organizationId?.get(module)) shouldBe null
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.customer.messagingpush

import androidx.annotation.VisibleForTesting
import io.customer.base.internal.InternalCustomerIOApi
import io.customer.messagingpush.di.deepLinkUtil
import io.customer.messagingpush.di.fcmTokenProvider
import io.customer.messagingpush.di.pushTrackingUtil
Expand All @@ -9,7 +11,10 @@ import io.customer.sdk.CustomerIOInstance
import io.customer.sdk.di.CustomerIOComponent
import io.customer.sdk.module.CustomerIOModule

class ModuleMessagingPushFCM internal constructor(
class ModuleMessagingPushFCM
@VisibleForTesting
@InternalCustomerIOApi
internal constructor(
override val moduleConfig: MessagingPushModuleConfig = MessagingPushModuleConfig.default(),
private val overrideCustomerIO: CustomerIOInstance?,
private val overrideDiGraph: CustomerIOComponent?
Expand Down

0 comments on commit fc2a08e

Please sign in to comment.