Skip to content

Updated code for deep links should have context:referrer like Swift sdk #271

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class DeepLinkUtils(val analytics: Analytics) {
return
}

analytics.updateReferrer(intent.data.toString())
val properties = extractLinkProperties(referrer, intent.data)
analytics.track("Deep Link Opened", properties)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class StorageTests {
UserInfo(
anonymousId = "oldAnonId",
userId = "oldUserId",
traits = buildJsonObject { put("behaviour", "bad") }
traits = buildJsonObject { put("behaviour", "bad") },
referrer = "oldReferrer",
))

store.provide(
Expand Down Expand Up @@ -85,7 +86,8 @@ class StorageTests {
return UserInfo(
anonymousId = "newAnonId",
userId = "newUserId",
traits = emptyJsonObject
traits = emptyJsonObject,
referrer = "newReferrer"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ open class Analytics protected constructor(
*/
fun reset() {
val newAnonymousId = UUID.randomUUID().toString()
userInfo = UserInfo(newAnonymousId, null, null)
userInfo = UserInfo(newAnonymousId, null, null, null)

analyticsScope.launch(analyticsDispatcher) {
store.dispatch(UserInfo.ResetAction(newAnonymousId), UserInfo::class)
Expand Down Expand Up @@ -740,6 +740,16 @@ open class Analytics protected constructor(
catch (ignored: Exception) {}
}
}

fun updateReferrer(referrerUrl: String?) {
userInfo.referrer = referrerUrl
analyticsScope.launch {
store.dispatch(
UserInfo.SetReferrerAction(referrerUrl),
UserInfo::class
)
}
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.segment.analytics.kotlin.core

object Constants {
const val LIBRARY_VERSION = "1.20.0"
const val LIBRARY_VERSION = "1.20.1"
const val DEFAULT_API_HOST = "api.segment.io/v1"
const val DEFAULT_CDN_HOST = "cdn-settings.segment.com/v1"
}
29 changes: 21 additions & 8 deletions core/src/main/java/com/segment/analytics/kotlin/core/State.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import sovran.kotlin.Action
import sovran.kotlin.State
import java.util.*
import java.util.UUID

/**
* Stores state related to the analytics system
Expand Down Expand Up @@ -143,11 +143,13 @@ data class System(
* - anonymousId (String)
* - userId (String)
* - traits (Map)
* - referrer (String)
*/
data class UserInfo(
var anonymousId: String,
var userId: String?,
var traits: JsonObject?
var traits: JsonObject?,
var referrer: String?,
) : State {

companion object {
Expand All @@ -160,37 +162,48 @@ data class UserInfo(
val anonymousId: String =
storage.read(Storage.Constants.AnonymousId) ?: UUID.randomUUID().toString()

return UserInfo(anonymousId, userId, traits)
return UserInfo(anonymousId, userId, traits, null)
}
}

class ResetAction(var anonymousId: String = UUID.randomUUID().toString()) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return UserInfo(anonymousId, null, null)
return UserInfo(anonymousId, null, null, null)
}
}

class SetUserIdAction(var userId: String) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return UserInfo(state.anonymousId, userId, state.traits)
return state.copy(
userId = userId
)
}
}

class SetAnonymousIdAction(var anonymousId: String) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return UserInfo(anonymousId, state.userId, state.traits)
return state.copy(anonymousId = anonymousId)
}
}

class SetReferrerAction(var referrer: String?) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return state.copy(referrer = referrer)
}
}

class SetTraitsAction(var traits: JsonObject) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return UserInfo(state.anonymousId, state.userId, traits)
return state.copy(traits = traits)
}
}

class SetUserIdAndTraitsAction(var userId: String, var traits: JsonObject) : Action<UserInfo> {
override fun reduce(state: UserInfo): UserInfo {
return UserInfo(state.anonymousId, userId, traits)
return state.copy(
userId = userId,
traits = traits
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.segment.analytics.kotlin.core.utilities.putAll
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import java.util.*
import java.util.UUID

/**
* Analytics plugin used to populate events with basic context data.
Expand All @@ -27,6 +27,8 @@ class ContextPlugin : Plugin {
const val LIBRARY_NAME_KEY = "name"
const val LIBRARY_VERSION_KEY = "version"
const val INSTANCE_ID_KEY = "instanceId"
const val REFERRER_KEY = "referrer"
const val URL_KEY = "url"
}

override fun setup(analytics: Analytics) {
Expand All @@ -45,6 +47,13 @@ class ContextPlugin : Plugin {
// putLibrary
put(LIBRARY_KEY, library)
put(INSTANCE_ID_KEY, instanceId)

// add additional context data
analytics.userInfo.referrer?.let { referrer ->
put(REFERRER_KEY, buildJsonObject {
put(URL_KEY, referrer)
})
}
}
event.context = newContext
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,8 @@ class AnalyticsTests {
UserInfo(
userId = "oldUserId",
traits = buildJsonObject { put("behaviour", "bad") },
anonymousId = "qwerty-qwerty-123"
), curUserInfo
anonymousId = "qwerty-qwerty-123",
referrer = null), curUserInfo
)

analytics.identify("newUserId", buildJsonObject { put("behaviour", "good") })
Expand All @@ -483,7 +483,8 @@ class AnalyticsTests {
UserInfo(
userId = "newUserId",
traits = buildJsonObject { put("behaviour", "good") },
anonymousId = "qwerty-qwerty-123"
anonymousId = "qwerty-qwerty-123",
referrer = null
), newUserInfo
)
}
Expand All @@ -501,7 +502,8 @@ class AnalyticsTests {
UserInfo(
userId = "oldUserId",
traits = buildJsonObject { put("behaviour", "bad") },
anonymousId = "qwerty-qwerty-123"
anonymousId = "qwerty-qwerty-123",
referrer = null
), curUserInfo
)

Expand All @@ -512,7 +514,8 @@ class AnalyticsTests {
UserInfo(
userId = "oldUserId",
traits = buildJsonObject { put("behaviour", "good") },
anonymousId = "qwerty-qwerty-123"
anonymousId = "qwerty-qwerty-123",
referrer = null
), newUserInfo
)
}
Expand Down Expand Up @@ -782,7 +785,8 @@ class AnalyticsTests {
UserInfo(
userId = "newId",
traits = emptyJsonObject,
anonymousId = "qwerty-qwerty-123"
anonymousId = "qwerty-qwerty-123",
referrer = null
), newUserInfo
)
}
Expand Down Expand Up @@ -890,6 +894,25 @@ class AnalyticsTests {
}
}

@Nested
inner class Referrer {
@Test
fun `updateReferrer non-null update`() = runTest {
analytics.updateReferrer("https://example.com")
val newUserInfo = analytics.store.currentState(UserInfo::class)
assertEquals(analytics.userInfo.referrer, "https://example.com")
assertEquals(newUserInfo?.referrer, "https://example.com")
}

@Test
fun `updateReferrer null update`() = runTest {
analytics.updateReferrer(null)
val newUserInfo = analytics.store.currentState(UserInfo::class)
assertEquals(analytics.userInfo.referrer, null)
assertEquals(newUserInfo?.referrer, null)
}
}

@Test
fun `settings fetches current Analytics Settings`() = runTest {
val settings = Settings(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,25 @@ internal class StateTest {
assertEquals(traits, (analytics.store.currentState(UserInfo::class))?.traits)
}
}

@Test
fun setReferrerAction() = runTest {
analytics.store.dispatch(UserInfo.SetReferrerAction("oldReferrer"), UserInfo::class)
assertEquals("oldReferrer", (analytics.store.currentState(UserInfo::class))?.referrer)

analytics.store.dispatch(UserInfo.SetReferrerAction("newReferrer"), UserInfo::class)
assertEquals("newReferrer", (analytics.store.currentState(UserInfo::class))?.referrer)
}


@Test
fun `setReferrerAction state change`() = runTest {
val traits = buildJsonObject { put("behaviour", "bad") }
analytics.store.dispatch(UserInfo.SetReferrerAction("newReferrer"), UserInfo::class)
analytics.store.dispatch(UserInfo.SetUserIdAction("oldUserId"), UserInfo::class)
analytics.store.dispatch(UserInfo.SetAnonymousIdAction("anonymous"), UserInfo::class)
analytics.store.dispatch(UserInfo.SetTraitsAction(traits), UserInfo::class)

assertEquals("newReferrer", (analytics.store.currentState(UserInfo::class))?.referrer)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ internal class InMemoryStorageTest {
return UserInfo(
anonymousId = "newAnonId",
userId = "newUserId",
traits = emptyJsonObject
traits = emptyJsonObject,
referrer = "newReferrer"
)
}
}
Expand Down Expand Up @@ -294,7 +295,8 @@ internal class InMemoryStorageTest {
return UserInfo(
anonymousId = "newAnonId",
userId = "newUserId",
traits = emptyJsonObject
traits = emptyJsonObject,
referrer = "newReferrer"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ internal class StorageImplTest {
UserInfo(
anonymousId = "oldAnonId",
userId = "oldUserId",
traits = buildJsonObject { put("behaviour", "bad") }
traits = buildJsonObject { put("behaviour", "bad") },
referrer = "oldReferrer"
))

store.provide(
Expand Down Expand Up @@ -86,7 +87,8 @@ internal class StorageImplTest {
return UserInfo(
anonymousId = "newAnonId",
userId = "newUserId",
traits = emptyJsonObject
traits = emptyJsonObject,
referrer = "newReferrer"
)
}
}
Expand Down Expand Up @@ -341,7 +343,8 @@ internal class StorageImplTest {
return UserInfo(
anonymousId = "newAnonId",
userId = "newUserId",
traits = emptyJsonObject
traits = emptyJsonObject,
referrer = "newReferrer"
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android.disableAutomaticComponentCreation=true
# Deployment variables
GROUP=com.segment.analytics.kotlin

VERSION_CODE=1200
VERSION_NAME=1.20.0
VERSION_CODE=1201
VERSION_NAME=1.20.1

POM_NAME=Segment for Kotlin
POM_DESCRIPTION=The hassle-free way to add analytics to your Kotlin app.
Expand Down