Skip to content

Commit

Permalink
feat: session id and device id (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
merlinpaypal committed Apr 9, 2024
1 parent f72ffda commit a7208eb
Show file tree
Hide file tree
Showing 21 changed files with 266 additions and 104 deletions.
2 changes: 1 addition & 1 deletion demo/src/main/java/com/paypal/messagesdemo/XmlActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ class XmlActivity : AppCompatActivity() {
binding = ActivityMessageBinding.inflate(layoutInflater)
setContentView(binding.root)

PayPalMessageConfig.setGlobalAnalytics()
val config = PayPalMessageConfig(data = PayPalMessageData(clientID = "someClientID"))
val message = PayPalMessageView(context = this, config = config)
message.getConfig()
message.setConfig(config)
config.setGlobalAnalytics("", "")
message.clientID = ""
message.merchantID = ""
message.partnerAttributionID = ""
Expand Down
36 changes: 26 additions & 10 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
id 'kotlin-android'
id 'org.jetbrains.kotlin.android'
id 'de.mannodermaus.android-junit5' version "1.9.3.0"
id 'org.jetbrains.kotlinx.kover' version '0.7.4'
id 'org.jetbrains.kotlinx.kover' version '0.7.6'
}

android {
Expand Down Expand Up @@ -65,16 +65,33 @@ android {
}
}

// if this exists, the CI should not run certain tasks
def runnerFolder = new File('/home/runner')

tasks.register('addPreCommitGitHookOnBuild') {
group 'git'
println("⚈ ⚈ ⚈ Running Add Pre Commit Git Hook Script on Build ⚈ ⚈ ⚈")
exec {
commandLine("cp", "../scripts/pre-commit", "../.git/hooks")
if (!runnerFolder.exists()) {
println('⚈ ⚈ ⚈ Running Add Pre Commit Git Hook Script on Build ⚈ ⚈ ⚈')
exec {
commandLine('cp', '../scripts/pre-commit', '../.git/hooks')
}
println('✅ Added Pre Commit Git Hook Script.')
}
}

tasks.register('ignoreFilesOnBuild') {
group 'ignore'
if (!runnerFolder.exists()) {
exec {
commandLine('../scripts/ignore-files.sh', '-y')
}
}
println("✅ Added Pre Commit Git Hook Script.")
}

preBuild.doFirst { addPreCommitGitHookOnBuild }
preBuild.doFirst {
addPreCommitGitHookOnBuild
ignoreFilesOnBuild
}

tasks.withType(Test).configureEach {
useJUnitPlatform()
Expand All @@ -84,6 +101,9 @@ koverReport {
androidReports('debug') {
filters {
excludes {
annotatedBy(
'*KoverExcludeGenerated'
)
classes(
// config
'com.paypal.messages.config.message.PayPalMessageEventsCallbacks\$*',
Expand All @@ -94,16 +114,12 @@ koverReport {
// io
'com.paypal.messages.io.Api',
'com.paypal.messages.io.Api\$*',
'com.paypal.messages.io.Api\$Endpoints',
'com.paypal.messages.io.ApiMessageData',
'com.paypal.messages.io.ApiHashData',
'com.paypal.messages.io.LocalStorage*',
'com.paypal.messages.io.OnActionCompleted',
// logger,
'com.paypal.messages.logger.Logger*',
// utils
'com.paypal.messages.utils.LogCat*',
'com.paypal.messages.utils.PayPalErrors',
// UI Stuff
'*Fragment',
'*Fragment\$*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.content.SharedPreferences
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -114,4 +116,19 @@ class LocalStorageTest {
val actualHashState = localStorage.getMerchantHashState()
assertEquals(LocalStorage.State.CACHE_DISABLED, actualHashState)
}

@Test
fun testDeviceId() {
val localStorage = LocalStorage(context)
val deviceIdFirstRetrieval = localStorage.deviceId

assertNotNull(deviceIdFirstRetrieval)
assertTrue(deviceIdFirstRetrieval != "")

val deviceIdSecondRetrieval = localStorage.deviceId
assertEquals(deviceIdFirstRetrieval, deviceIdSecondRetrieval)

val deviceIdThirdRetrieval = localStorage.deviceId
assertEquals(deviceIdFirstRetrieval, deviceIdThirdRetrieval)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.paypal.messages.logger
import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.paypal.messages.config.message.PayPalMessageConfig
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -21,6 +23,12 @@ class LoggerTest {
val sharedPreferences = context.getSharedPreferences("com.paypal.messages", Context.MODE_PRIVATE)
sharedPreferences.edit().putString("merchantHash", "1234567890").apply()

PayPalMessageConfig.setGlobalAnalytics(
"test_integration_name",
"test_integration_version",
"test_device_id",
"test_session_id",
)
logger = Logger.getInstance("test_client_id")
component = TrackingComponent(
instanceId = "test_instance_id",
Expand All @@ -34,28 +42,20 @@ class LoggerTest {
assertNotNull(logger)
}

@Test
fun testSetGlobalAnalytics() {
logger.setGlobalAnalytics("test_integration_name", "test_integration_version")

assertEquals("test_integration_name", logger.integrationName)
assertEquals("test_integration_version", logger.integrationVersion)
}

// TODO: Figure out why this test passes locally but fails in the CI
@Test
fun testLog() {
component.componentEvents.add(TrackingEvent(EventType.MESSAGE_CLICK))
logger.setGlobalAnalytics("test_integration_name", "test_integration_version")
logger.log(context, component)

val payload = logger.payload
assertNotNull(payload)
if (payload != null) {
payload?.run {
assertEquals("test_client_id", payload.clientId)
assertEquals("random_session_id", payload.sessionId)
assertTrue(payload.sessionId != "")
assertEquals("test_integration_name", payload.integrationName)
assertEquals("test_integration_version", payload.integrationVersion)
assertEquals("test_device_id", payload.deviceId)
assertEquals("test_session_id", payload.sessionId)

assertEquals(1, payload.components.size)
assertEquals("test_type", payload.components[0].type)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.paypal.messages.config

object GlobalAnalytics {
var integrationName: String = ""
var integrationVersion: String = ""
var deviceId: String = ""
var sessionId: String = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.paypal.messages.config.message

@Retention(AnnotationRetention.RUNTIME)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.CONSTRUCTOR,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.PROPERTY,
AnnotationTarget.TYPE,
AnnotationTarget.TYPE_PARAMETER,
AnnotationTarget.VALUE_PARAMETER,
)
annotation class KoverExcludeGenerated
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.paypal.messages.config.message

import com.paypal.messages.logger.Logger
import com.paypal.messages.config.GlobalAnalytics

/**
* [PayPalMessageConfig] is the main configuration model for interacting with the PayPalMessage component
Expand All @@ -15,15 +15,19 @@ data class PayPalMessageConfig(
var viewStateCallbacks: PayPalMessageViewStateCallbacks? = null,
var eventsCallbacks: PayPalMessageEventsCallbacks? = null,
) : Cloneable {

public override fun clone() = PayPalMessageConfig(data.clone(), style, viewStateCallbacks?.clone(), eventsCallbacks?.clone())

fun setGlobalAnalytics(
integrationName: String,
integrationVersion: String,
) {
if (data.clientID != "") {
Logger.getInstance(data.clientID).setGlobalAnalytics(integrationName, integrationVersion)
companion object {
fun setGlobalAnalytics(
integrationName: String = "",
integrationVersion: String = "",
deviceId: String = "",
sessionId: String = "",
) {
GlobalAnalytics.integrationName = integrationName
GlobalAnalytics.integrationVersion = integrationVersion
GlobalAnalytics.deviceId = deviceId
GlobalAnalytics.sessionId = sessionId
}
}
}
5 changes: 3 additions & 2 deletions library/src/main/java/com/paypal/messages/io/ApiResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ sealed class ApiResult {
companion object {
fun getFailureWithDebugId(headers: Headers): ApiResult {
val headersMap = headers.toMultimap()
val error = headersMap["Paypal-Debug-Id"]?.firstOrNull()?.let {
PayPalErrors.InvalidResponseException("", it)
val error = headersMap["Paypal-Debug-Id"]?.let {
val debugId = it.firstOrNull()
PayPalErrors.InvalidResponseException("", debugId)
}
return Failure(error)
}
Expand Down
19 changes: 18 additions & 1 deletion library/src/main/java/com/paypal/messages/io/LocalStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package com.paypal.messages.io
import android.content.Context
import com.google.gson.Gson
import com.paypal.messages.utils.LogCat
import java.util.UUID

class LocalStorage constructor(context: Context) {
class LocalStorage(context: Context) {
private val TAG = this::class.java.simpleName
private val key = "PayPalUpstreamLocalStorage"
private val sharedPrefs = context.getSharedPreferences(key, Context.MODE_PRIVATE)
Expand All @@ -15,13 +16,29 @@ class LocalStorage constructor(context: Context) {
enum class StorageKeys(private val keyName: String) {
MERCHANT_HASH_DATA("merchantProfileHashData"),
TIMESTAMP("timestamp"),
DEVICE_ID("deviceId"),
;

override fun toString(): String {
return keyName
}
}

val deviceId: String
get() {
val deviceId = sharedPrefs.getString("${StorageKeys.DEVICE_ID}", null)
return if (deviceId == null) {
val newDeviceId = UUID.randomUUID().toString()
val editor = sharedPrefs.edit()
LogCat.debug(TAG, "No device ID found, setting device ID to: $newDeviceId")
editor.putString("${StorageKeys.DEVICE_ID}", newDeviceId)
editor.apply()
newDeviceId
} else {
deviceId
}
}

var merchantHashData: ApiHashData.Response?
get() {
val storage = sharedPrefs.getString("${StorageKeys.MERCHANT_HASH_DATA}", null)
Expand Down

0 comments on commit a7208eb

Please sign in to comment.