Skip to content

Conversation

@Ayyanchira
Copy link
Member

@Ayyanchira Ayyanchira commented Nov 18, 2025

🔹 Jira Ticket(s) if any

✏️ Description

Adds Push Test

“Akshay added 2 commits November 13, 2025 07:25
Activity created; utility function added in BaseIntegrationTest; Dedicated PushNotification Test file with one mvp function; Constants for new campaign id from Mobile SDK do not Delete project; An actvity for push modified
- Json file is gitignored for now
- Not sure how github action will perform.
- Device is receiving push notification
- However, it was noticed taht test were passing even before that indicating tests written are not accurate
@Ayyanchira Ayyanchira changed the title Sdk 7 bcit push [SDK - 7] - BCIT Push Nov 18, 2025
Copy link
Member Author

@Ayyanchira Ayyanchira left a comment

Choose a reason for hiding this comment

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

Gave a first pass @sumeruchat @joaodordio . Have added explanations and thoughts on this PR

Comment on lines +39 to +40
private val lastHandledAction = AtomicReference<com.iterable.iterableapi.IterableAction?>(null)
private val lastHandledActionType = AtomicReference<String?>(null)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is like mutual lock which is assigned a value when handlers are called. Used by test to affirm handlers getting called.

Comment on lines +80 to +92
.setCustomActionHandler(object : com.iterable.iterableapi.IterableCustomActionHandler {
override fun handleIterableCustomAction(
action: com.iterable.iterableapi.IterableAction,
actionContext: com.iterable.iterableapi.IterableActionContext
): Boolean {
// Handle custom actions during tests
val actionType = action.getType()
Log.d("BaseIntegrationTest", "Custom action triggered: type=$actionType, action=$action, source=${actionContext.source}")
customActionHandlerCalled.set(true)
lastHandledAction.set(action)
lastHandledActionType.set(actionType)
return false
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Checking customActionHandler along with previously tested urlHandler

customActionHandlerCalled.set(true)
lastHandledAction.set(action)
lastHandledActionType.set(actionType)
return false
Copy link
Member Author

Choose a reason for hiding this comment

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

returning false here despite handling the deeplink so taht we can verify if SDK is going to take any action aruond it or not.

urlHandlerCalled.set(true)
lastHandledUrl.set(url.toString())
true
false
Copy link
Member Author

Choose a reason for hiding this comment

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

returning false here as I want SDK to take action when google.com is clicked. Returning true indicates that app has handled the link and prevent SDK to take further action. Without this change, it will not open google.com on chrome. It gives opportunity for developer to handle it internally first.

Comment on lines +131 to +142
protected fun hasNotificationPermission(): Boolean {
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
androidx.core.content.ContextCompat.checkSelfPermission(
context,
android.Manifest.permission.POST_NOTIFICATIONS
) == android.content.pm.PackageManager.PERMISSION_GRANTED
} else {
// For Android 12 and below, notifications are enabled by default
androidx.core.app.NotificationManagerCompat.from(context).areNotificationsEnabled()
}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Notification permission logic

}
}

private fun triggerPushCampaign() {
Copy link
Member Author

Choose a reason for hiding this comment

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

The way autoamtion works actually doesnt need the buttons to trigger push campaign. It directly calls the function. The buttons exist to help us test manually. But perhaps I can have the automation use buttons so that source of truth for triggering the campaign stays singular

Comment on lines 7 to 48
import com.iterable.iterableapi.IterableFirebaseMessagingService

class IntegrationFirebaseMessagingService : FirebaseMessagingService() {

companion object {
private const val TAG = "IntegrationFCMService"
}

override fun onNewToken(token: String) {
super.onNewToken(token)
Log.d(TAG, "New FCM token: $token")

// Register the token with Iterable SDK
try {
com.iterable.iterableapi.IterableApi.getInstance().registerForPush()
Log.d(TAG, "FCM token registered with Iterable SDK")
} catch (e: Exception) {
Log.e(TAG, "Failed to register FCM token with Iterable SDK", e)
}
}

override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)

Log.d(TAG, "Received FCM message: ${remoteMessage.messageId}")
Log.d(TAG, "Message data: ${remoteMessage.data}")
Log.d(TAG, "Message notification: ${remoteMessage.notification}")

// Check if this is a silent push for in-app messages
val isSilent = remoteMessage.data["silent"] == "true"
val isInAppMessage = remoteMessage.data["inAppMessage"] == "true"

if (isSilent && isInAppMessage) {
Log.d(TAG, "Received silent push for in-app message")
// The Iterable SDK will handle the silent push automatically
// We just need to track that it was received
IntegrationTestUtils(this).setSilentPushProcessed(true)
} else {
Log.d(TAG, "Received regular push notification")
// Regular push notification - Iterable SDK will handle display
IntegrationTestUtils(this).setPushNotificationReceived(true)
IterableFirebaseMessagingService.handleMessageReceived(this, remoteMessage)
Copy link
Member Author

Choose a reason for hiding this comment

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

Added Firebase configuration on integration test module. This makes FIrebase work for this project. Making it receive notifications

Log.d(TAG, "Custom action received: type=$actionType, data=$actionData")
// You can add custom logic here to handle different action types
// For now, just log and return true to indicate the action was handled
return false
Copy link
Member Author

Choose a reason for hiding this comment

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

Similar to BaseIntegration test, it may seem duplicate, but for manual testing, this is where the Iterable initializes vs for Test, BaseIntegrationTest file is where the SDK initializes with all the config

Comment on lines +1 to +6
plugins {
id 'com.android.application'
// Add the Google services Gradle plugin
id 'com.google.gms.google-services'
}

Copy link
Member Author

Choose a reason for hiding this comment

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

on following Firebase docs. pretty standard

Copy link
Member Author

Choose a reason for hiding this comment

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

Just a simple UI with buttons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants