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

feat: add reset method to reset userId and deviceId #48

Merged
merged 5 commits into from
Jul 26, 2022
Merged
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
8 changes: 8 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'

testImplementation 'io.mockk:mockk:1.10.6'
testImplementation project(':core')
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand All @@ -77,3 +78,10 @@ dependencies {
tasks.dokkaHtmlPartial.configure {
failOnWarning.set(true)
}

tasks.withType(Test) {
useJUnitPlatform()
testLogging {
showStandardStreams = true
}
}
19 changes: 18 additions & 1 deletion android/src/main/java/com/amplitude/android/Amplitude.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ open class Amplitude(
internal var lastEventId: Long = 0
var lastEventTime: Long = -1
private var previousSessionId: Long = -1
private lateinit var androidContextPlugin: AndroidContextPlugin

override fun build() {
val storageDirectory = (configuration as Configuration).context.getDir("${FileStorage.STORAGE_PREFIX}-${configuration.instanceName}", Context.MODE_PRIVATE)
Expand Down Expand Up @@ -53,12 +54,28 @@ open class Amplitude(
lastEventTime = storage.read(Storage.Constants.LAST_EVENT_TIME) ?. let {
it.toLong()
} ?: -1
add(AndroidContextPlugin())
androidContextPlugin = AndroidContextPlugin()
add(androidContextPlugin)
add(AndroidLifecyclePlugin())
}
add(AmplitudeDestination())
}

/**
* Reset identity:
* - reset userId to "null"
* - reset deviceId via AndroidContextPlugin
* @return the Amplitude instance
*/
override fun reset(): Amplitude {
this.setUserId(null)
amplitudeScope.launch(amplitudeDispatcher) {
idContainer.identityManager.editIdentity().setDeviceId(null).commit()
liuyang1520 marked this conversation as resolved.
Show resolved Hide resolved
androidContextPlugin.initializeDeviceId(configuration as Configuration)
liuyang1520 marked this conversation as resolved.
Show resolved Hide resolved
}
return this
}

fun onEnterForeground(timestamp: Long) {
amplitudeScope.launch(amplitudeDispatcher) {
startNewSessionIfNeeded(timestamp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AndroidContextPlugin : Plugin {
return event
}

private fun initializeDeviceId(configuration: Configuration) {
fun initializeDeviceId(configuration: Configuration) {
yuhao900914 marked this conversation as resolved.
Show resolved Hide resolved
val deviceId = amplitude.store.deviceId
if (deviceId != null && validDeviceId(deviceId) && !deviceId.endsWith("S")) {
return
Expand Down
62 changes: 62 additions & 0 deletions android/src/test/java/com/amplitude/android/AmplitudeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.amplitude.android

import android.app.Application
import android.content.Context
import com.amplitude.android.plugins.AndroidLifecyclePlugin
import com.amplitude.core.utilities.InMemoryStorageProvider
import com.amplitude.id.IMIdentityStorageProvider
import com.amplitude.id.IdentityConfiguration
import com.amplitude.id.IdentityContainer
import io.mockk.mockk
import io.mockk.mockkStatic
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class AmplitudeTest {
private var context: Context? = null
private var amplitude: Amplitude? = null

@BeforeEach
fun setUp() {
context = mockk<Application>(relaxed = true)
mockkStatic(AndroidLifecyclePlugin::class)
val configuration = IdentityConfiguration(
"testInstance",
identityStorageProvider = IMIdentityStorageProvider()
)
IdentityContainer.getInstance(configuration)
amplitude = Amplitude(
Configuration(
apiKey = "api-key",
context = context!!,
instanceName = "testInstance",
storageProvider = InMemoryStorageProvider()
)
)
}

@Test
fun amplitude_reset_wipesUserIdDeviceId() {
runBlocking {
val job = launch {
amplitude?.setUserId("test user")
amplitude?.setDeviceId("test device")
}
job.join()
}
Assertions.assertEquals("test user", amplitude?.store?.userId)
Assertions.assertEquals("test device", amplitude?.store?.deviceId)

runBlocking {
val job = launch {
amplitude?.reset()
}
job.join()
}
Assertions.assertNull(amplitude?.store?.userId)
Assertions.assertNotEquals("test device", amplitude?.store?.deviceId)
}
}
13 changes: 13 additions & 0 deletions core/src/main/java/com/amplitude/core/Amplitude.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import java.util.UUID
import java.util.concurrent.Executors

/**
Expand Down Expand Up @@ -183,6 +184,18 @@ open class Amplitude internal constructor(
return this
}

/**
liuyang1520 marked this conversation as resolved.
Show resolved Hide resolved
* Reset identity:
* - reset userId to "null"
* - reset deviceId to random UUID
* @return the Amplitude instance
*/
open fun reset(): Amplitude {
this.setUserId(null)
this.setDeviceId(UUID.randomUUID().toString() + "R")
return this
}

/**
* Identify a group. You can modify group properties by calling this api.
*
Expand Down
24 changes: 24 additions & 0 deletions core/src/test/kotlin/com/amplitude/core/AmplitudeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.BeforeEach
Expand Down Expand Up @@ -329,4 +330,27 @@ internal class AmplitudeTest {
assertTrue(callbackCalled)
}
}

@Nested
inner class TestReset {
@Test
fun `test reset`() {
val mockPlugin = spyk(StubPlugin())
amplitude.add(mockPlugin)

amplitude.setUserId("user_id")
amplitude.setDeviceId("device_id")
amplitude.reset()
amplitude.track("test event")

val track = slot<BaseEvent>()
verify { mockPlugin.track(capture(track)) }

track.captured.let {
assertEquals(null, it.userId)
assertNotEquals("device_id", it.deviceId)
assertEquals("test event", it.eventType)
}
}
}
}