diff --git a/embrace-android-sdk/config/detekt/baseline.xml b/embrace-android-sdk/config/detekt/baseline.xml index fe32198fdc..e4dc7afdbc 100644 --- a/embrace-android-sdk/config/detekt/baseline.xml +++ b/embrace-android-sdk/config/detekt/baseline.xml @@ -7,6 +7,6 @@ DataClassShouldBeImmutable:LegacyExceptionError.kt$LegacyExceptionError$@Json(name = "c") var occurrences: Int = 0 DataClassShouldBeImmutable:LegacyExceptionError.kt$LegacyExceptionError$@Json(name = "rep") var exceptionErrors: MutableList<LegacyExceptionErrorInfo> = mutableListOf() LongParameterList:FakeModuleInitBootstrapper.kt$( fakeEmbLogger: FakeEmbLogger = FakeEmbLogger(), fakeInitModule: FakeInitModule = FakeInitModule(), fakeOpenTelemetryModule: FakeOpenTelemetryModule = FakeOpenTelemetryModule(), coreModuleSupplier: CoreModuleSupplier = { _, _, _ -> FakeCoreModule() }, systemServiceModuleSupplier: SystemServiceModuleSupplier = { _, _ -> FakeSystemServiceModule() }, androidServicesModuleSupplier: AndroidServicesModuleSupplier = { _, _, _ -> FakeAndroidServicesModule() }, workerThreadModuleSupplier: WorkerThreadModuleSupplier = { _ -> FakeWorkerThreadModule() }, storageModuleSupplier: StorageModuleSupplier = { _, _, _ -> FakeStorageModule() }, essentialServiceModuleSupplier: EssentialServiceModuleSupplier = { _, _, _, _, _, _, _, _, _, _ -> FakeEssentialServiceModule() }, dataSourceModuleSupplier: DataSourceModuleSupplier = { _, _, _, _, _, _, _, _ -> FakeDataSourceModule() }, dataCaptureServiceModuleSupplier: DataCaptureServiceModuleSupplier = { _, _, _, _, _, _, _ -> FakeDataCaptureServiceModule() }, deliveryModuleSupplier: DeliveryModuleSupplier = { _, _, _, _, _ -> FakeDeliveryModule() }, anrModuleSupplier: AnrModuleSupplier = { _, _, _, _ -> FakeAnrModule() }, customerLogModuleSupplier: CustomerLogModuleSupplier = { _, _, _, _, _, _, _, _ -> FakeCustomerLogModule() }, nativeModuleSupplier: NativeModuleSupplier = { _, _, _, _, _, _, _ -> FakeNativeModule() }, dataContainerModuleSupplier: DataContainerModuleSupplier = { _, _, _, _, _ -> FakeDataContainerModule() }, sessionModuleSupplier: SessionModuleSupplier = { _, _, _, _, _, _, _, _, _, _, _, _, _ -> FakeSessionModule() }, crashModuleSupplier: CrashModuleSupplier = { _, _, _, _, _, _, _, _, _, _, _ -> FakeCrashModule() }, payloadModuleSupplier: PayloadModuleSupplier = { _, _, _, _, _, _, _, _, _ -> FakePayloadModule() } ) - TooManyFunctions:EmbraceImpl.kt$EmbraceImpl : UserApi + TooManyFunctions:EmbraceImpl.kt$EmbraceImpl : UserApiSessionApi diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceImpl.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceImpl.kt index f1603c0ff7..af87015203 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceImpl.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceImpl.kt @@ -19,6 +19,7 @@ import io.embrace.android.embracesdk.internal.IdGenerator.Companion.generateW3CT import io.embrace.android.embracesdk.internal.Systrace.endSynchronous import io.embrace.android.embracesdk.internal.Systrace.startSynchronous import io.embrace.android.embracesdk.internal.api.delegate.SdkCallChecker +import io.embrace.android.embracesdk.internal.api.delegate.SessionApiDelegate import io.embrace.android.embracesdk.internal.api.delegate.UserApiDelegate import io.embrace.android.embracesdk.internal.spans.EmbraceTracer import io.embrace.android.embracesdk.internal.utils.getSafeStackTrace @@ -45,8 +46,9 @@ internal class EmbraceImpl @JvmOverloads constructor( private val bootstrapper: ModuleInitBootstrapper = ModuleInitBootstrapper(), private val sdkCallChecker: SdkCallChecker = SdkCallChecker(bootstrapper.initModule.logger, bootstrapper.initModule.telemetryService), - private val userApiDelegate: UserApiDelegate = UserApiDelegate(bootstrapper, sdkCallChecker) -) : UserApi by userApiDelegate { + private val userApiDelegate: UserApiDelegate = UserApiDelegate(bootstrapper, sdkCallChecker), + private val sessionApiDelegate: SessionApiDelegate = SessionApiDelegate(bootstrapper, sdkCallChecker) +) : UserApi by userApiDelegate, SessionApi by sessionApiDelegate { @JvmField val tracer: EmbraceTracer = bootstrapper.openTelemetryModule.embraceTracer @@ -329,33 +331,6 @@ internal class EmbraceImpl @JvmOverloads constructor( } } - /** - * Adds a property to the current session. - */ - fun addSessionProperty(key: String, value: String, permanent: Boolean): Boolean { - if (sdkCallChecker.check("add_session_property")) { - return sessionPropertiesService?.addProperty(key, value, permanent) ?: false - } - return false - } - - /** - * Removes a property from the current session. - */ - fun removeSessionProperty(key: String): Boolean { - if (sdkCallChecker.check("remove_session_property")) { - return sessionPropertiesService?.removeProperty(key) ?: false - } - return false - } - - fun getSessionProperties(): Map? { - if (sdkCallChecker.check("get_session_properties")) { - return sessionPropertiesService?.getProperties() - } - return null - } - /** * Starts a 'moment'. Moments are used for encapsulating particular activities within * the app, such as a user adding an item to their shopping cart. @@ -555,18 +530,6 @@ internal class EmbraceImpl @JvmOverloads constructor( } } - /** - * Ends the current session and starts a new one. - * - * - * Cleans all the user info on the device. - */ - fun endSession(clearUserInfo: Boolean) { - if (sdkCallChecker.check("end_session")) { - sessionOrchestrator?.endSessionWithManual(clearUserInfo) - } - } - fun getDeviceId(): String = when { sdkCallChecker.check("get_device_id") -> preferencesService?.deviceIdentifier diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegate.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegate.kt new file mode 100644 index 0000000000..5deabeb8b6 --- /dev/null +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegate.kt @@ -0,0 +1,56 @@ +package io.embrace.android.embracesdk.internal.api.delegate + +import io.embrace.android.embracesdk.SessionApi +import io.embrace.android.embracesdk.injection.ModuleInitBootstrapper +import io.embrace.android.embracesdk.injection.embraceImplInject + +internal class SessionApiDelegate( + bootstrapper: ModuleInitBootstrapper, + private val sdkCallChecker: SdkCallChecker +) : SessionApi { + + private val sessionPropertiesService by embraceImplInject(sdkCallChecker) { + bootstrapper.sessionModule.sessionPropertiesService + } + private val sessionOrchestrator by embraceImplInject(sdkCallChecker) { bootstrapper.sessionModule.sessionOrchestrator } + + /** + * Adds a property to the current session. + */ + override fun addSessionProperty(key: String, value: String, permanent: Boolean): Boolean { + if (sdkCallChecker.check("add_session_property")) { + return sessionPropertiesService?.addProperty(key, value, permanent) ?: false + } + return false + } + + /** + * Removes a property from the current session. + */ + override fun removeSessionProperty(key: String): Boolean { + if (sdkCallChecker.check("remove_session_property")) { + return sessionPropertiesService?.removeProperty(key) ?: false + } + return false + } + + override fun getSessionProperties(): Map? { + if (sdkCallChecker.check("get_session_properties")) { + return sessionPropertiesService?.getProperties() + } + return null + } + + override fun endSession() = endSession(false) + + /** + * Ends the current session and starts a new one. + * + * Cleans all the user info on the device. + */ + override fun endSession(clearUserInfo: Boolean) { + if (sdkCallChecker.check("end_session")) { + sessionOrchestrator?.endSessionWithManual(clearUserInfo) + } + } +} diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/FakeSessionPropertiesService.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/FakeSessionPropertiesService.kt index e310ac74d8..b88adfc56c 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/FakeSessionPropertiesService.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/FakeSessionPropertiesService.kt @@ -3,15 +3,20 @@ package io.embrace.android.embracesdk import io.embrace.android.embracesdk.session.properties.SessionPropertiesService internal class FakeSessionPropertiesService : SessionPropertiesService { + + var props: MutableMap = mutableMapOf() + override fun addProperty(originalKey: String, originalValue: String, permanent: Boolean): Boolean { - TODO("Not yet implemented") + props[originalKey] = originalValue + return true } override fun removeProperty(originalKey: String): Boolean { - TODO("Not yet implemented") + props.remove(originalKey) + return true } - override fun getProperties(): Map = emptyMap() + override fun getProperties(): Map = props override fun populateCurrentSession(): Boolean = true } diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegateTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegateTest.kt new file mode 100644 index 0000000000..cc3f3bfcd0 --- /dev/null +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/internal/api/delegate/SessionApiDelegateTest.kt @@ -0,0 +1,66 @@ +package io.embrace.android.embracesdk.internal.api.delegate + +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.embrace.android.embracesdk.Embrace +import io.embrace.android.embracesdk.FakeSessionPropertiesService +import io.embrace.android.embracesdk.fakes.FakeEmbLogger +import io.embrace.android.embracesdk.fakes.FakeSessionOrchestrator +import io.embrace.android.embracesdk.fakes.FakeTelemetryService +import io.embrace.android.embracesdk.fakes.fakeModuleInitBootstrapper +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +internal class SessionApiDelegateTest { + + private lateinit var delegate: SessionApiDelegate + private lateinit var orchestrator: FakeSessionOrchestrator + private lateinit var sessionPropertiesService: FakeSessionPropertiesService + + @Before + fun setUp() { + val moduleInitBootstrapper = fakeModuleInitBootstrapper() + moduleInitBootstrapper.init(ApplicationProvider.getApplicationContext(), Embrace.AppFramework.NATIVE, 0) + orchestrator = moduleInitBootstrapper.sessionModule.sessionOrchestrator as FakeSessionOrchestrator + sessionPropertiesService = moduleInitBootstrapper.sessionModule.sessionPropertiesService as FakeSessionPropertiesService + + val sdkCallChecker = SdkCallChecker(FakeEmbLogger(), FakeTelemetryService()) + sdkCallChecker.started.set(true) + delegate = SessionApiDelegate(moduleInitBootstrapper, sdkCallChecker) + } + + @Test + fun `add session property`() { + delegate.addSessionProperty("test", "value", false) + assertEquals("value", sessionPropertiesService.props["test"]) + } + + @Test + fun `remove session property`() { + delegate.addSessionProperty("test", "value", false) + delegate.removeSessionProperty("test") + assertNull(sessionPropertiesService.props["test"]) + } + + @Test + fun `get session properties`() { + sessionPropertiesService.props["key"] = "value" + assertEquals(mapOf("key" to "value"), delegate.getSessionProperties()) + } + + @Test + fun `end session`() { + delegate.endSession() + assertEquals(1, orchestrator.manualEndCount) + } + + @Test + fun `end session clear user info`() { + delegate.endSession(true) + assertEquals(1, orchestrator.manualEndCount) + } +}