Skip to content

Commit

Permalink
feat: include persistent visitor id in context
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklasl committed Apr 29, 2024
1 parent 2fca516 commit 85d1826
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Provider/src/main/java/com/spotify/confidence/Confidence.kt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ class Confidence internal constructor(
}
}

internal const val VISITOR_ID_CONTEXT_KEY = "visitorId"

object ConfidenceFactory {
fun create(
context: Context,
Expand Down Expand Up @@ -152,6 +154,8 @@ object ConfidenceFactory {
flagResolver = flagResolver,
diskStorage = FileDiskStorage.create(context),
flagApplierClient = flagApplierClient
)
).apply {
putContext(VISITOR_ID_CONTEXT_KEY, ConfidenceValue.String(VisitorUtil.getId(context)))
}
}
}
22 changes: 22 additions & 0 deletions Provider/src/main/java/com/spotify/confidence/VisitorUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.spotify.confidence

import android.content.Context
import java.util.UUID

internal const val SHARED_PREFS_NAME = "confidence-visitor"
internal const val VISITOR_ID_SHARED_PREFS_KEY = "visitorId"
internal const val DEFAULT_VALUE = "unable-to-read"

internal object VisitorUtil {
fun getId(context: Context): String {
return with(context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)) {
if (contains(VISITOR_ID_SHARED_PREFS_KEY)) {
getString(VISITOR_ID_SHARED_PREFS_KEY, DEFAULT_VALUE) ?: DEFAULT_VALUE
} else {
val visitorId = UUID.randomUUID().toString()
edit().putString(VISITOR_ID_SHARED_PREFS_KEY, visitorId).apply()
visitorId
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.spotify.confidence

import android.content.Context
import android.content.SharedPreferences
import com.spotify.confidence.cache.FLAGS_FILE_NAME
import com.spotify.confidence.cache.FileDiskStorage
import com.spotify.confidence.client.ResolveReason
Expand All @@ -22,6 +23,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.mockito.kotlin.any
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.io.File
Expand All @@ -30,6 +32,8 @@ import java.util.UUID

private const val clientSecret = "21wxcxXpU6tKBRFtEFTXYiH7nDqL86Mm"
private val mockContext: Context = mock()
private val mockSharedPrefs: SharedPreferences = mock()
private val mockSharedPrefsEdit: SharedPreferences.Editor = mock()

class ConfidenceIntegrationTests {

Expand All @@ -40,6 +44,10 @@ class ConfidenceIntegrationTests {
fun setup() {
whenever(mockContext.filesDir).thenReturn(Files.createTempDirectory("tmpTests").toFile())
whenever(mockContext.getDir(any(), any())).thenReturn(Files.createTempDirectory("events").toFile())
whenever(mockContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)).thenReturn(mockSharedPrefs)
whenever(mockSharedPrefs.edit()).thenReturn(mockSharedPrefsEdit)
whenever(mockSharedPrefsEdit.putString(any(), any())).thenReturn(mockSharedPrefsEdit)
doNothing().whenever(mockSharedPrefsEdit).apply()
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.spotify.confidence

import android.content.Context
import android.content.SharedPreferences
import com.spotify.confidence.client.SdkMetadata
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
Expand All @@ -10,13 +11,17 @@ import kotlinx.coroutines.test.runTest
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.io.File
import java.nio.file.Files

private const val clientSecret = "WciJVLIEiNnRxV8gaYPZNCFF8vbAXOu6"
private val mockContext: Context = mock()
private val mockSharedPrefs: SharedPreferences = mock()
private val mockSharedPrefsEdit: SharedPreferences.Editor = mock()

@OptIn(ExperimentalCoroutinesApi::class)
class EventSenderIntegrationTest {
Expand All @@ -27,12 +32,29 @@ class EventSenderIntegrationTest {
@Before
fun setup() {
whenever(mockContext.getDir("events", Context.MODE_PRIVATE)).thenReturn(directory)
whenever(mockContext.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)).thenReturn(mockSharedPrefs)
whenever(mockSharedPrefs.edit()).thenReturn(mockSharedPrefsEdit)
whenever(mockSharedPrefsEdit.putString(any(), any())).thenReturn(mockSharedPrefsEdit)
doNothing().whenever(mockSharedPrefsEdit).apply()
eventSender = null
for (file in directory.walkFiles()) {
file.delete()
}
}

@Test
fun created_event_sender_has_visitor_id_context() = runTest {
val testDispatcher = UnconfinedTestDispatcher(testScheduler)
eventSender = ConfidenceFactory.create(
mockContext,
clientSecret,
dispatcher = testDispatcher
)
val context = eventSender?.getContext()
Assert.assertNotNull(context)
Assert.assertTrue(context!!.containsKey(VISITOR_ID_CONTEXT_KEY))
}

@Test
fun emitting_an_event_writes_to_file() = runTest {
val eventStorage = EventStorageImpl(mockContext)
Expand Down

0 comments on commit 85d1826

Please sign in to comment.