Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: event bus integration with push #358

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion messagingpush/api/messagingpush.api
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public final class io/customer/messagingpush/util/PushTrackingUtil$Companion {
}

public final class io/customer/messagingpush/util/PushTrackingUtilImpl : io/customer/messagingpush/util/PushTrackingUtil {
public fun <init> (Lio/customer/sdk/repository/TrackRepository;)V
public fun <init> ()V
public fun parseLaunchedActivityForTracking (Landroid/os/Bundle;)Z
}

19 changes: 19 additions & 0 deletions messagingpush/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,23 @@ dependencies {

api Dependencies.firebaseMessaging
implementation Dependencies.googlePlayServicesBase

testImplementation(platform(Dependencies.junitBom))
testImplementation(Dependencies.junitJupiter)
testImplementation(Dependencies.mockk)

// enables running JUnit 4 tests within the JUnit 5 (jupiter) platform.
testRuntimeOnly(Dependencies.junitVintageEngine)
}

tasks.withType(Test).configureEach {
useJUnitPlatform()
filter {
excludeTestsMatching("*Integration*")
}
ignoreFailures = true
// https://github.com/mockk/mockk/issues/681
jvmArgs("--add-opens", "java.base/java.time=ALL-UNNAMED",
"--add-opens", "java.base/java.util=ALL-UNNAMED"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future, once we have all modules using JUnit5, we can pull these changes up to common gradle file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's the plan 👍

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import io.customer.messagingpush.di.pushMessageProcessor
import io.customer.messagingpush.extensions.getSDKInstanceOrNull
import io.customer.sdk.android.CustomerIO
import io.customer.sdk.communication.Event
import io.customer.sdk.core.di.SDKComponent.eventBus

open class CustomerIOFirebaseMessagingService : FirebaseMessagingService() {

Expand Down Expand Up @@ -91,6 +93,10 @@
}

private fun handleNewToken(context: Context, token: String) {
eventBus.publish(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to either create class variable or use SDKComponent.eventBus for improved readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i thought import or event clicking on it would be sufficient, I can add the extended name just felt like a overhead.

Event.RegisterDeviceTokenEvent(token)

Check warning on line 97 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOFirebaseMessagingService.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOFirebaseMessagingService.kt#L96-L97

Added lines #L96 - L97 were not covered by tests
)
// todo: remove this
context.getSDKInstanceOrNull()?.registerDeviceToken(deviceToken = token)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import io.customer.messagingpush.di.pushTrackingUtil
import io.customer.messagingpush.lifecycle.MessagingPushLifecycleCallback
import io.customer.sdk.android.CustomerIO
import io.customer.sdk.android.CustomerIOInstance
import io.customer.sdk.communication.Event
import io.customer.sdk.core.di.SDKComponent.eventBus
import io.customer.sdk.core.module.CustomerIOModule
import io.customer.sdk.di.CustomerIOComponent

Expand Down Expand Up @@ -52,7 +54,11 @@ internal constructor(
*/
private fun getCurrentFcmToken() {
fcmTokenProvider.getCurrentToken { token ->
token?.let { customerIO.registerDeviceToken(token) }
token?.let {
eventBus.publish(Event.RegisterDeviceTokenEvent(token))
// todo: remove this
customerIO.registerDeviceToken(token)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@ internal val CustomerIOComponent.deepLinkUtil: DeepLinkUtil

@InternalCustomerIOApi
val CustomerIOComponent.pushTrackingUtil: PushTrackingUtil
get() = override() ?: PushTrackingUtilImpl(trackRepository)
get() = override() ?: PushTrackingUtilImpl()

internal val CustomerIOComponent.pushMessageProcessor: PushMessageProcessor
get() = override() ?: getSingletonInstanceCreate {
PushMessageProcessorImpl(
logger = logger,
moduleConfig = moduleConfig,
deepLinkUtil = deepLinkUtil,
trackRepository = trackRepository
deepLinkUtil = deepLinkUtil
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import io.customer.messagingpush.data.model.CustomerIOParsedPushPayload
import io.customer.messagingpush.extensions.parcelable
import io.customer.messagingpush.util.DeepLinkUtil
import io.customer.messagingpush.util.PushTrackingUtil
import io.customer.sdk.communication.Event
import io.customer.sdk.core.di.SDKComponent.eventBus
import io.customer.sdk.core.util.Logger
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.extensions.takeIfNotBlank
import io.customer.sdk.repository.TrackRepository

internal class PushMessageProcessorImpl(
private val logger: Logger,
private val moduleConfig: MessagingPushModuleConfig,
private val deepLinkUtil: DeepLinkUtil,
private val trackRepository: TrackRepository
private val deepLinkUtil: DeepLinkUtil
) : PushMessageProcessor {

/**
Expand Down Expand Up @@ -87,10 +87,12 @@ internal class PushMessageProcessorImpl(
private fun trackDeliveredMetrics(deliveryId: String, deliveryToken: String) {
// Track delivered event only if auto-tracking is enabled
if (moduleConfig.autoTrackPushEvents) {
trackRepository.trackMetric(
deliveryID = deliveryId,
deviceToken = deliveryToken,
event = MetricEvent.delivered
eventBus.publish(
Event.TrackPushMetricEvent(
event = MetricEvent.delivered.name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be outside the scope of this PR, but curious if there is a reason for using String instead of MetricEvent enum? Is this for wrappers flexibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MetricEvent has a Moshi dependency to it, which we will be getting rid of. So pulling it in core didn't make sense, on top of that wrappers would also not be using it.

End goal would be to create another enum and replace the string and remove the tracking one.

deliveryId = deliveryId,
deviceToken = deliveryToken
)
)
}
}
Expand Down Expand Up @@ -119,10 +121,12 @@ internal class PushMessageProcessorImpl(

private fun trackNotificationClickMetrics(payload: CustomerIOParsedPushPayload) {
if (moduleConfig.autoTrackPushEvents) {
trackRepository.trackMetric(
deliveryID = payload.cioDeliveryId,
event = MetricEvent.opened,
deviceToken = payload.cioDeliveryToken
eventBus.publish(
Event.TrackPushMetricEvent(
event = MetricEvent.opened.name,
deliveryId = payload.cioDeliveryId,
deviceToken = payload.cioDeliveryToken
)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package io.customer.messagingpush.util

import android.os.Bundle
import io.customer.sdk.communication.Event
import io.customer.sdk.core.di.SDKComponent.eventBus
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.repository.TrackRepository

interface PushTrackingUtil {
fun parseLaunchedActivityForTracking(bundle: Bundle): Boolean
Expand All @@ -13,20 +14,20 @@ interface PushTrackingUtil {
}
}

class PushTrackingUtilImpl(
private val trackRepository: TrackRepository
) : PushTrackingUtil {
class PushTrackingUtilImpl : PushTrackingUtil {

override fun parseLaunchedActivityForTracking(bundle: Bundle): Boolean {
val deliveryId = bundle.getString(PushTrackingUtil.DELIVERY_ID_KEY)
val deliveryToken = bundle.getString(PushTrackingUtil.DELIVERY_TOKEN_KEY)

if (deliveryId == null || deliveryToken == null) return false

trackRepository.trackMetric(
deliveryID = deliveryId,
deviceToken = deliveryToken,
event = MetricEvent.opened
eventBus.publish(
Event.TrackPushMetricEvent(
deliveryId = deliveryId,
event = MetricEvent.opened.name,
deviceToken = deliveryToken
Shahroz16 marked this conversation as resolved.
Show resolved Hide resolved
)
)

return true
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package io.customer.messagingpush

import android.os.Bundle
import io.customer.messagingpush.util.PushTrackingUtil
import io.customer.messagingpush.util.PushTrackingUtilImpl
import io.customer.sdk.communication.Event
import io.customer.sdk.communication.EventBus
import io.customer.sdk.core.di.SDKComponent
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.extensions.random
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.amshove.kluent.shouldBe
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class PushTrackingUtilTest {

private lateinit var eventBus: EventBus
private lateinit var util: PushTrackingUtil

@BeforeEach
fun setup() {
util = PushTrackingUtilImpl()
eventBus = mockk(relaxed = true)
SDKComponent.overrideDependency(EventBus::class.java, eventBus)
}

@Test
fun parseLaunchedActivityForTracking_givenBundleWithoutDeliveryData_expectDoNoTrackPush() {
val givenBundle = mockk<Bundle>()
every { givenBundle.getString("foo") } returns "randomString"
every { givenBundle.getString(PushTrackingUtil.DELIVERY_ID_KEY) } returns null
every { givenBundle.getString(PushTrackingUtil.DELIVERY_TOKEN_KEY) } returns null

val result = util.parseLaunchedActivityForTracking(givenBundle)

result shouldBe false

verify(exactly = 0) { eventBus.publish(any<Event.TrackPushMetricEvent>()) }
}

@Test
fun parseLaunchedActivityForTracking_givenBundleWithDeliveryData_expectTrackPush() {
val givenDeliveryId = String.random
val givenDeviceToken = String.random

val givenBundle = mockk<Bundle>()
every { givenBundle.getString(PushTrackingUtil.DELIVERY_ID_KEY) } returns givenDeliveryId
every { givenBundle.getString(PushTrackingUtil.DELIVERY_TOKEN_KEY) } returns givenDeviceToken

val result = util.parseLaunchedActivityForTracking(givenBundle)

result shouldBe true

verify(exactly = 1) {
eventBus.publish(
Event.TrackPushMetricEvent(
deliveryId = givenDeliveryId,
event = MetricEvent.opened.name,
deviceToken = givenDeviceToken
)
)
}
}
}
Loading