diff --git a/example/android/build.gradle b/example/android/build.gradle index 4dcd21c1c..0aa14077a 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -2,7 +2,6 @@ buildscript { ext { - RNNKotlinVersion = "1.5.31" buildToolsVersion = "33.0.0" minSdkVersion = 21 compileSdkVersion = 33 @@ -16,7 +15,7 @@ buildscript { mavenCentral() } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.21" classpath("com.android.tools.build:gradle:7.3.1") classpath("com.facebook.react:react-native-gradle-plugin") } diff --git a/packages/core/android/build.gradle b/packages/core/android/build.gradle index 493864754..10b8a18e7 100644 --- a/packages/core/android/build.gradle +++ b/packages/core/android/build.gradle @@ -12,7 +12,7 @@ buildscript { classpath 'com.android.tools.build:gradle:7.2.2' // noinspection DifferentKotlinGradleVersion classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.1" + classpath "org.jlleitschuh.gradle:ktlint-gradle:11.5.1" classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.18.0" classpath 'com.github.bjoernq:unmockplugin:0.7.9' } @@ -159,7 +159,10 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compileOnly "com.squareup.okhttp3:okhttp:3.12.13" - implementation "com.datadoghq:dd-sdk-android:1.19.2" + implementation "com.datadoghq:dd-sdk-android-rum:2.0.0" + implementation "com.datadoghq:dd-sdk-android-logs:2.0.0" + implementation "com.datadoghq:dd-sdk-android-trace:2.0.0" + implementation "com.datadoghq:dd-sdk-android-webview:2.0.0" testImplementation "org.junit.platform:junit-platform-launcher:1.6.2" testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2" testImplementation "org.junit.jupiter:junit-jupiter-engine:5.6.2" @@ -204,7 +207,6 @@ ktlint { outputToConsole.set(true) ignoreFailures.set(false) enableExperimentalRules.set(false) - additionalEditorconfigFile.set(file("${project.rootDir}/script/config/.editorconfig")) filter { exclude("**/generated/**") include("**/kotlin/**") diff --git a/packages/core/android/gradle.properties b/packages/core/android/gradle.properties index 0401e18b4..4f16df59e 100644 --- a/packages/core/android/gradle.properties +++ b/packages/core/android/gradle.properties @@ -1,4 +1,4 @@ -DdSdkReactNative_kotlinVersion=1.6.21 +DdSdkReactNative_kotlinVersion=1.7.21 DdSdkReactNative_compileSdkVersion=31 DdSdkReactNative_buildToolsVersion=31.0.0 DdSdkReactNative_targetSdkVersion=31 diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogSDKWrapper.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogSDKWrapper.kt index 8a501fecd..e2b5b89cc 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogSDKWrapper.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogSDKWrapper.kt @@ -9,24 +9,51 @@ package com.datadog.reactnative import android.content.Context import com.datadog.android.Datadog import com.datadog.android.core.configuration.Configuration -import com.datadog.android.core.configuration.Credentials +import com.datadog.android.log.Logs +import com.datadog.android.log.LogsConfiguration import com.datadog.android.privacy.TrackingConsent -import com.datadog.android.rum.GlobalRum +import com.datadog.android.rum.GlobalRumMonitor +import com.datadog.android.rum.Rum +import com.datadog.android.rum.RumConfiguration import com.datadog.android.rum.RumMonitor +import com.datadog.android.trace.Trace +import com.datadog.android.trace.TraceConfiguration +import com.datadog.android.webview.WebViewTracking internal class DatadogSDKWrapper : DatadogWrapper { + // lazy here is on purpose. The thing is that this class will be instantiated even before + // Sdk.initialize is called, but telemetry proxy can be created only after SDK is initialized. + private val telemetryProxy by lazy { Datadog._internalProxy() } + + // lazy here is on purpose. The thing is that this class will be instantiated even before + // Sdk.initialize is called, but webview proxy can be created only after SDK is initialized. + private val webViewProxy by lazy { + WebViewTracking._InternalWebViewProxy(Datadog.getInstance()) + } + override fun setVerbosity(level: Int) { Datadog.setVerbosity(level) } override fun initialize( context: Context, - credentials: Credentials, configuration: Configuration, consent: TrackingConsent ) { - Datadog.initialize(context, credentials, configuration, consent) + Datadog.initialize(context, configuration, consent) + } + + override fun enableRum(configuration: RumConfiguration) { + Rum.enable(configuration) + } + + override fun enableLogs(configuration: LogsConfiguration) { + Logs.enable(configuration) + } + + override fun enableTrace(configuration: TraceConfiguration) { + Trace.enable(configuration) } override fun setUserInfo( @@ -38,13 +65,10 @@ internal class DatadogSDKWrapper : DatadogWrapper { Datadog.setUserInfo(id, name, email, extraInfo) } - override fun registerRumMonitor(rumMonitor: RumMonitor) { - GlobalRum.registerIfAbsent(rumMonitor) - } - override fun addRumGlobalAttributes(attributes: Map) { + val rumMonitor = this.getRumMonitor() attributes.forEach { - GlobalRum.addAttribute(it.key, it.value) + rumMonitor.addAttribute(it.key, it.value) } } @@ -53,22 +77,38 @@ internal class DatadogSDKWrapper : DatadogWrapper { } override fun telemetryDebug(message: String) { - Datadog._internal._telemetry.debug(message) + // Do not initialize the telemetry proxy before SDK is initialized + if (isInitialized()) { + telemetryProxy._telemetry.debug(message) + } } override fun telemetryError(message: String, stack: String?, kind: String?) { - Datadog._internal._telemetry.error(message, stack, kind) + // Do not initialize the telemetry proxy before SDK is initialized + if (isInitialized()) { + telemetryProxy._telemetry.error(message, stack, kind) + } } override fun telemetryError(message: String, throwable: Throwable?) { - Datadog._internal._telemetry.error(message, throwable) + // Do not initialize the telemetry proxy before SDK is initialized + if (isInitialized()) { + telemetryProxy._telemetry.error(message, throwable) + } } override fun consumeWebviewEvent(message: String) { - Datadog._internal.consumeWebviewEvent(message) + // Do not initialize the webview proxy before SDK is initialized + if (isInitialized()) { + webViewProxy.consumeWebviewEvent(message) + } } override fun isInitialized(): Boolean { return Datadog.isInitialized() } + + override fun getRumMonitor(): RumMonitor { + return GlobalRumMonitor.get() + } } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogWrapper.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogWrapper.kt index 3c39e7303..94b9071c4 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogWrapper.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DatadogWrapper.kt @@ -8,9 +8,12 @@ package com.datadog.reactnative import android.content.Context import com.datadog.android.core.configuration.Configuration -import com.datadog.android.core.configuration.Credentials +import com.datadog.android.log.LogsConfiguration import com.datadog.android.privacy.TrackingConsent +import com.datadog.android.rum.GlobalRumMonitor +import com.datadog.android.rum.RumConfiguration import com.datadog.android.rum.RumMonitor +import com.datadog.android.trace.TraceConfiguration import java.lang.IllegalArgumentException /** @@ -45,11 +48,37 @@ interface DatadogWrapper { */ fun initialize( context: Context, - credentials: Credentials, configuration: Configuration, consent: TrackingConsent ) + /** + * Enables the RUM feature of the SDK. + * + * @param configuration the configuration for the RUM feature + */ + fun enableRum( + configuration: RumConfiguration + ) + + /** + * Enables the Logs feature of the SDK. + * + * @param configuration the configuration for the Logs feature + */ + fun enableLogs( + configuration: LogsConfiguration + ) + + /** + * Enables the Trace feature of the SDK. + * + * @param configuration the configuration for the Trace feature + */ + fun enableTrace( + configuration: TraceConfiguration + ) + /** * Sets the user information. * @@ -66,13 +95,6 @@ interface DatadogWrapper { extraInfo: Map ) - /** - * Registers a given monitor in [GlobalRum]. - * - * @param rumMonitor to register - */ - fun registerRumMonitor(rumMonitor: RumMonitor) - /** * Adds global attributes. * @@ -109,4 +131,9 @@ interface DatadogWrapper { * Returns whether the SDK is initialized. */ fun isInitialized(): Boolean + + /** + * Returns the RUM Monitor for the default SDK core. + */ + fun getRumMonitor(): RumMonitor } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdLogsImplementation.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdLogsImplementation.kt index 5dbcf41c8..f57b00ff8 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdLogsImplementation.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdLogsImplementation.kt @@ -20,9 +20,8 @@ class DdLogsImplementation( ) { private val reactNativeLogger: Logger by lazy { logger ?: Logger.Builder() - .setDatadogLogsEnabled(true) .setLogcatLogsEnabled(true) - .setLoggerName("DdLogs") + .setName("DdLogs") .build() } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdRumImplementation.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdRumImplementation.kt index 4fba8f88a..3764248d0 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdRumImplementation.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdRumImplementation.kt @@ -6,7 +6,6 @@ package com.datadog.reactnative -import com.datadog.android.rum.GlobalRum import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource @@ -19,7 +18,7 @@ import java.util.Locale * The entry point to use Datadog's RUM feature. */ @Suppress("TooManyFunctions") -class DdRumImplementation { +class DdRumImplementation(private val datadog: DatadogWrapper = DatadogSDKWrapper()) { /** * Start tracking a RUM View. * @param key The view unique key identifier. @@ -37,7 +36,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().startView( + datadog.getRumMonitor().startView( key = key, name = name, attributes = attributes @@ -55,7 +54,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().stopView( + datadog.getRumMonitor().stopView( key = key, attributes = attributes ) @@ -79,7 +78,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().startUserAction( + datadog.getRumMonitor().startAction( type = type.asRumActionType(), name = name, attributes = attributes @@ -104,7 +103,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().stopUserAction( + datadog.getRumMonitor().stopAction( type = type.asRumActionType(), name = name, attributes = attributes @@ -129,7 +128,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().addUserAction( + datadog.getRumMonitor().addAction( type = type.asRumActionType(), name = name, attributes = attributes @@ -157,7 +156,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().startResource( + datadog.getRumMonitor().startResource( key = key, method = method, url = url, @@ -193,7 +192,7 @@ class DdRumImplementation { } else { size.toLong() } - GlobalRum.get().stopResource( + datadog.getRumMonitor().stopResource( key = key, statusCode = statusCode.toInt(), kind = kind.asRumResourceKind(), @@ -223,7 +222,7 @@ class DdRumImplementation { val attributes = context.toHashMap().toMutableMap().apply { put(RumAttributes.INTERNAL_TIMESTAMP, timestampMs.toLong()) } - GlobalRum.get().addErrorWithStacktrace( + datadog.getRumMonitor().addErrorWithStacktrace( message = message, source = source.asErrorSource(), stacktrace = stacktrace, @@ -237,7 +236,7 @@ class DdRumImplementation { * @param name The name of the new custom timing attribute. Timings can be nested up to 8 levels deep. Names using more than 8 levels will be sanitized by SDK. */ fun addTiming(name: String, promise: Promise) { - GlobalRum.get().addTiming(name) + datadog.getRumMonitor().addTiming(name) promise.resolve(null) } @@ -245,7 +244,7 @@ class DdRumImplementation { * Stops the current RUM Session. */ fun stopSession(promise: Promise) { - GlobalRum.get().stopSession() + datadog.getRumMonitor().stopSession() promise.resolve(null) } @@ -253,12 +252,12 @@ class DdRumImplementation { * Adds result of evaluating a feature flag to the view. * Feature flag evaluations are local to the active view and are cleared when the view is stopped. * @param name The name of the feature flag - * @param value The value the feature flag evaluated to, encapsulated in a Map + * @param valueAsMap The value the feature flag evaluated to, encapsulated in a Map */ - fun addFeatureFlagEvaluation(name: String, value: ReadableMap, promise: Promise) { - val value = value.toHashMap()["value"] + fun addFeatureFlagEvaluation(name: String, valueAsMap: ReadableMap, promise: Promise) { + val value = valueAsMap.toHashMap()["value"] if (value != null) { - GlobalRum.get().addFeatureFlagEvaluation(name, value) + datadog.getRumMonitor().addFeatureFlagEvaluation(name, value) } promise.resolve(null) } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfiguration.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfiguration.kt index a3f8f667b..87db41ad5 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfiguration.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfiguration.kt @@ -29,7 +29,7 @@ package com.datadog.reactnative data class DdSdkConfiguration( val clientToken: String, val env: String, - val applicationId: String? = null, + val applicationId: String, val nativeCrashReportEnabled: Boolean? = null, val nativeLongTaskThresholdMs: Double? = null, val longTaskThresholdMs: Double? = null, diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfigurationExt.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfigurationExt.kt index 23e2593c9..f1507f190 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfigurationExt.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkConfigurationExt.kt @@ -6,7 +6,7 @@ package com.datadog.reactnative -import com.datadog.android.tracing.TracingHeaderType +import com.datadog.android.trace.TracingHeaderType import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableNativeMap @@ -15,7 +15,7 @@ internal fun ReadableMap.asDdSdkConfiguration(): DdSdkConfiguration { return DdSdkConfiguration( clientToken = getString("clientToken").orEmpty(), env = getString("env").orEmpty(), - applicationId = getString("applicationId"), + applicationId = getString("applicationId").orEmpty(), nativeCrashReportEnabled = getBoolean("nativeCrashReportEnabled"), nativeLongTaskThresholdMs = getDouble("nativeLongTaskThresholdMs"), longTaskThresholdMs = getDouble("longTaskThresholdMs"), @@ -63,7 +63,7 @@ internal fun DdSdkConfiguration.toReadableMap(): ReadableMap { val map = WritableNativeMap() map.putString("clientToken", clientToken) map.putString("env", env) - applicationId?.let { map.putString("applicationId", it) } + map.putString("applicationId", applicationId) nativeCrashReportEnabled?.let { map.putBoolean("nativeCrashReportEnabled", it) } nativeLongTaskThresholdMs?.let { map.putDouble("nativeLongTaskThresholdMs", it) } longTaskThresholdMs?.let { map.putDouble("longTaskThresholdMs", it) } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt index 3adcb9306..fac7489ab 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt @@ -11,22 +11,22 @@ import android.content.pm.PackageManager import android.util.Log import android.view.Choreographer import com.datadog.android.DatadogSite -import com.datadog.android._InternalProxy import com.datadog.android.core.configuration.BatchSize import com.datadog.android.core.configuration.Configuration -import com.datadog.android.core.configuration.Credentials import com.datadog.android.core.configuration.UploadFrequency -import com.datadog.android.core.configuration.VitalsUpdateFrequency import com.datadog.android.event.EventMapper +import com.datadog.android.log.LogsConfiguration import com.datadog.android.privacy.TrackingConsent -import com.datadog.android.rum.GlobalRum -import com.datadog.android.rum.RumMonitor +import com.datadog.android.rum.configuration.VitalsUpdateFrequency +import com.datadog.android.rum.RumConfiguration import com.datadog.android.rum.RumPerformanceMetric +import com.datadog.android.rum._RumInternalProxy import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ResourceEvent import com.datadog.android.rum.tracking.ActivityViewTrackingStrategy import com.datadog.android.telemetry.model.TelemetryConfigurationEvent -import com.datadog.android.tracing.TracingHeaderType +import com.datadog.android.trace.TraceConfiguration +import com.datadog.android.trace.TracingHeaderType import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReadableArray @@ -54,16 +54,21 @@ class DdSdkImplementation( */ fun initialize(configuration: ReadableMap, promise: Promise) { val ddSdkConfiguration = configuration.asDdSdkConfiguration() - val credentials = buildCredentials(ddSdkConfiguration) - val nativeConfiguration = buildConfiguration(ddSdkConfiguration) + val sdkConfiguration = buildSdkConfiguration(ddSdkConfiguration) + val rumConfiguration = buildRumConfiguration(ddSdkConfiguration) val trackingConsent = buildTrackingConsent(ddSdkConfiguration.trackingConsent) configureSdkVerbosity(ddSdkConfiguration) - datadog.initialize(appContext, credentials, nativeConfiguration, trackingConsent) + datadog.initialize(appContext, sdkConfiguration, trackingConsent) - datadog.registerRumMonitor(RumMonitor.Builder().build()) + datadog.enableRum(rumConfiguration) monitorJsRefreshRate(ddSdkConfiguration) + + datadog.enableTrace(TraceConfiguration.Builder().build()) + + datadog.enableLogs(LogsConfiguration.Builder().build()) + initialized.set(true) promise.resolve(null) @@ -165,55 +170,31 @@ class DdSdkImplementation( return packageInfo?.let { // we need to use the deprecated method because getLongVersionCode method is only // available from API 28 and above - @Suppress("DEPRECATION") it.versionName ?: it.versionCode.toString() + @Suppress("DEPRECATION") + it.versionName ?: it.versionCode.toString() } ?: DEFAULT_APP_VERSION } @Suppress("ComplexMethod", "LongMethod", "UnsafeCallOnNullableType") - private fun buildConfiguration(configuration: DdSdkConfiguration): Configuration { - val additionalConfig = configuration.additionalConfig?.toMutableMap() - - val versionSuffix = configuration.additionalConfig?.get(DD_VERSION_SUFFIX) as? String - if (versionSuffix != null && additionalConfig != null) { - val defaultVersion = getDefaultAppVersion() - additionalConfig.put(DD_VERSION, defaultVersion + versionSuffix) - } - + private fun buildRumConfiguration(configuration: DdSdkConfiguration): RumConfiguration { val configBuilder = - Configuration.Builder( - logsEnabled = true, - tracesEnabled = true, - crashReportsEnabled = configuration.nativeCrashReportEnabled - ?: false, - rumEnabled = true + RumConfiguration.Builder( + applicationId = configuration.applicationId ) - .setAdditionalConfiguration( - additionalConfig?.filterValues { it != null }?.mapValues { - it.value!! - } - ?: emptyMap() - ) if (configuration.sampleRate != null) { - configBuilder.sampleRumSessions(configuration.sampleRate.toFloat()) + configBuilder.setSessionSampleRate(configuration.sampleRate.toFloat()) } configBuilder.trackFrustrations(configuration.trackFrustrations ?: true) - configBuilder.trackBackgroundRumEvents(configuration.trackBackgroundEvents ?: false) + configBuilder.trackBackgroundEvents(configuration.trackBackgroundEvents ?: false) - configBuilder.useSite(buildSite(configuration.site)) configBuilder.setVitalsUpdateFrequency( buildVitalUpdateFrequency(configuration.vitalsUpdateFrequency) ) - configBuilder.setUploadFrequency( - buildUploadFrequency(configuration.uploadFrequency) - ) - configBuilder.setBatchSize( - buildBatchSize(configuration.batchSize) - ) val telemetrySampleRate = (configuration.telemetrySampleRate as? Number)?.toFloat() - telemetrySampleRate?.let { configBuilder.sampleTelemetry(it) } + telemetrySampleRate?.let { configBuilder.setTelemetrySampleRate(it) } val longTask = (configuration.nativeLongTaskThresholdMs as? Number)?.toLong() if (longTask != null) { @@ -231,25 +212,10 @@ class DdSdkImplementation( val interactionTracking = configuration.additionalConfig?.get(DD_NATIVE_INTERACTION_TRACKING) as? Boolean if (interactionTracking == false) { - configBuilder.disableInteractionTracking() - } - - @Suppress("UNCHECKED_CAST") - val firstPartyHosts = - (configuration.additionalConfig?.get(DD_FIRST_PARTY_HOSTS) as? ReadableArray) - ?.toArrayList() as? - List - if (firstPartyHosts != null) { - val firstPartyHostsWithHeaderTypes = buildFirstPartyHosts(firstPartyHosts) - - configBuilder.setFirstPartyHostsWithHeaderType(firstPartyHostsWithHeaderTypes) - } - - buildProxyConfiguration(configuration)?.let { (proxy, authenticator) -> - configBuilder.setProxy(proxy, authenticator) + configBuilder.disableUserInteractionTracking() } - configBuilder.setRumResourceEventMapper( + configBuilder.setResourceEventMapper( object : EventMapper { override fun map(event: ResourceEvent): ResourceEvent? { if (event.context?.additionalProperties?.containsKey(DD_DROP_RESOURCE) == @@ -262,7 +228,7 @@ class DdSdkImplementation( } ) - configBuilder.setRumActionEventMapper( + configBuilder.setActionEventMapper( object : EventMapper { override fun map(event: ActionEvent): ActionEvent? { if (event.context?.additionalProperties?.containsKey(DD_DROP_ACTION) == true @@ -274,7 +240,7 @@ class DdSdkImplementation( } ) - _InternalProxy.setTelemetryConfigurationEventMapper( + _RumInternalProxy.setTelemetryConfigurationEventMapper( configBuilder, object : EventMapper { override fun map( @@ -341,15 +307,52 @@ class DdSdkImplementation( return firstPartyHostsWithHeaderTypes } - private fun buildCredentials(configuration: DdSdkConfiguration): Credentials { + private fun buildSdkConfiguration(configuration: DdSdkConfiguration): Configuration { val serviceName = configuration.additionalConfig?.get(DD_SERVICE_NAME) as? String - return Credentials( + val configBuilder = Configuration.Builder( clientToken = configuration.clientToken, - envName = configuration.env, - rumApplicationId = configuration.applicationId, + env = configuration.env, variant = "", - serviceName = serviceName + service = serviceName ) + + val additionalConfig = configuration.additionalConfig?.toMutableMap() + val versionSuffix = configuration.additionalConfig?.get(DD_VERSION_SUFFIX) as? String + if (versionSuffix != null && additionalConfig != null) { + val defaultVersion = getDefaultAppVersion() + additionalConfig.put(DD_VERSION, defaultVersion + versionSuffix) + } + configBuilder.setAdditionalConfiguration( + additionalConfig?.filterValues { it != null }?.mapValues { + it.value!! + } + ?: emptyMap() + ) + + configBuilder.setCrashReportsEnabled(configuration.nativeCrashReportEnabled ?: false) + configBuilder.useSite(buildSite(configuration.site)) + configBuilder.setUploadFrequency( + buildUploadFrequency(configuration.uploadFrequency) + ) + configBuilder.setBatchSize( + buildBatchSize(configuration.batchSize) + ) + + buildProxyConfiguration(configuration)?.let { (proxy, authenticator) -> + configBuilder.setProxy(proxy, authenticator) + } + + @Suppress("UNCHECKED_CAST") + val firstPartyHosts = + (configuration.additionalConfig?.get(DD_FIRST_PARTY_HOSTS) as? ReadableArray) + ?.toArrayList() as? + List + if (firstPartyHosts != null) { + val firstPartyHostsWithHeaderTypes = buildFirstPartyHosts(firstPartyHosts) + configBuilder.setFirstPartyHostsWithHeaderType(firstPartyHostsWithHeaderTypes) + } + + return configBuilder.build() } internal fun buildTrackingConsent(trackingConsent: String?): TrackingConsent { @@ -435,8 +438,7 @@ class DdSdkImplementation( } private fun buildUploadFrequency(uploadFrequency: String?): UploadFrequency { - val uploadFrequency = uploadFrequency?.lowercase(Locale.US) - return when (uploadFrequency) { + return when (uploadFrequency?.lowercase(Locale.US)) { "rare" -> UploadFrequency.RARE "average" -> UploadFrequency.AVERAGE "frequent" -> UploadFrequency.FREQUENT @@ -489,7 +491,7 @@ class DdSdkImplementation( return { if (jsRefreshRateMonitoringEnabled && it > 0.0) { - GlobalRum.get() + datadog.getRumMonitor() ._getInternal() ?.updatePerformanceMetric(RumPerformanceMetric.JS_FRAME_TIME, it) } @@ -499,7 +501,7 @@ class DdSdkImplementation( ddSdkConfiguration.longTaskThresholdMs?.toLong() ?: 0L ) ) { - GlobalRum.get()._getInternal()?.addLongTask(it.toLong(), "javascript") + datadog.getRumMonitor()._getInternal()?.addLongTask(it.toLong(), "javascript") } } } diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdTraceImplementation.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdTraceImplementation.kt index c69b26ebe..7f47221f2 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdTraceImplementation.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdTraceImplementation.kt @@ -6,18 +6,26 @@ package com.datadog.reactnative -import com.datadog.android.tracing.AndroidTracer +import com.datadog.android.trace.AndroidTracer +import com.datadog.android.trace.Trace +import com.datadog.android.trace.TraceConfiguration import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap import io.opentracing.Span import io.opentracing.Tracer +import io.opentracing.util.GlobalTracer import java.util.concurrent.TimeUnit /** * The entry point to use Datadog's Trace feature. */ class DdTraceImplementation( - private val tracerProvider: () -> Tracer = { AndroidTracer.Builder().build() } + private val tracerProvider: () -> Tracer = { + val tracer = AndroidTracer.Builder().build() + GlobalTracer.registerIfAbsent(tracer) + + GlobalTracer.get() + } ) { private val spanMap: MutableMap = mutableMapOf() diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/NoOpViewTrackingStrategy.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/NoOpViewTrackingStrategy.kt index 198827a61..929857f0a 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/NoOpViewTrackingStrategy.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/NoOpViewTrackingStrategy.kt @@ -7,13 +7,14 @@ package com.datadog.reactnative import android.content.Context +import com.datadog.android.api.SdkCore import com.datadog.android.rum.tracking.ViewTrackingStrategy /** * No-op implementation of the [ViewTrackingStrategy]. */ object NoOpViewTrackingStrategy : ViewTrackingStrategy { - override fun register(context: Context) { + override fun register(sdkCore: SdkCore, context: Context) { // No-op } diff --git a/packages/core/android/src/oldarch/kotlin/com/datadog/reactnative/DdTrace.kt b/packages/core/android/src/oldarch/kotlin/com/datadog/reactnative/DdTrace.kt index 42687a692..7c26f4b75 100644 --- a/packages/core/android/src/oldarch/kotlin/com/datadog/reactnative/DdTrace.kt +++ b/packages/core/android/src/oldarch/kotlin/com/datadog/reactnative/DdTrace.kt @@ -16,7 +16,7 @@ import com.facebook.react.bridge.ReadableMap * The entry point to use Datadog's Trace feature. */ class DdTrace( - reactContext: ReactApplicationContext, + reactContext: ReactApplicationContext ) : ReactContextBaseJavaModule(reactContext) { private val implementation = DdTraceImplementation() diff --git a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdRumTest.kt b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdRumTest.kt index e1f12c5a5..b9c3797d2 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdRumTest.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdRumTest.kt @@ -6,19 +6,17 @@ package com.datadog.reactnative -import com.datadog.android.rum.GlobalRum import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.RumMonitor import com.datadog.android.rum.RumResourceKind import com.datadog.tools.unit.forge.BaseConfigurator -import com.datadog.tools.unit.getStaticValue -import com.datadog.tools.unit.setStaticValue import com.datadog.tools.unit.toReadableMap import com.facebook.react.bridge.Promise -import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.BoolForgery import fr.xgouchet.elmyr.annotation.DoubleForgery @@ -29,7 +27,6 @@ import fr.xgouchet.elmyr.annotation.StringForgeryType import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import java.util.Date -import java.util.concurrent.atomic.AtomicBoolean import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -55,6 +52,9 @@ internal class DdRumTest { @Mock lateinit var mockRumMonitor: RumMonitor + @Mock + lateinit var mockDatadog: DatadogWrapper + @Mock lateinit var mockPromise: Promise @@ -65,7 +65,7 @@ internal class DdRumTest { @BeforeEach fun `set up`(forge: Forge) { - GlobalRum.registerIfAbsent(mockRumMonitor) + whenever(mockDatadog.getRumMonitor()) doReturn mockRumMonitor fakeContext = forge.aMap { anAlphabeticalString() to aNullable { @@ -79,13 +79,11 @@ internal class DdRumTest { } } - testedDdRum = DdRumImplementation() + testedDdRum = DdRumImplementation(mockDatadog) } @AfterEach fun `tear down`() { - GlobalRum.javaClass.setStaticValue("monitor", mock()) - GlobalRum.javaClass.getStaticValue("isRegistered").set(false) } @Test @@ -133,12 +131,15 @@ internal class DdRumTest { // When testedDdRum.addAction( - type.name, name, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + type.name, + name, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then - verify(mockRumMonitor).addUserAction(type, name, updatedContext) + verify(mockRumMonitor).addAction(type, name, updatedContext) } @Test @@ -155,7 +156,7 @@ internal class DdRumTest { testedDdRum.addAction(type, name, fakeContext.toReadableMap(), fakeTimestamp, mockPromise) // Then - verify(mockRumMonitor).addUserAction(RumActionType.CUSTOM, name, updatedContext) + verify(mockRumMonitor).addAction(RumActionType.CUSTOM, name, updatedContext) } @Test @@ -170,12 +171,15 @@ internal class DdRumTest { // When testedDdRum.startAction( - type.name, name, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + type.name, + name, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then - verify(mockRumMonitor).startUserAction(type, name, updatedContext) + verify(mockRumMonitor).startAction(type, name, updatedContext) } @Test @@ -192,7 +196,7 @@ internal class DdRumTest { testedDdRum.startAction(type, name, fakeContext.toReadableMap(), fakeTimestamp, mockPromise) // Then - verify(mockRumMonitor).startUserAction(RumActionType.CUSTOM, name, updatedContext) + verify(mockRumMonitor).startAction(RumActionType.CUSTOM, name, updatedContext) } @Test @@ -207,12 +211,15 @@ internal class DdRumTest { // When testedDdRum.stopAction( - type.name, name, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + type.name, + name, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then - verify(mockRumMonitor).stopUserAction(type, name, updatedContext) + verify(mockRumMonitor).stopAction(type, name, updatedContext) } @Test @@ -229,7 +236,7 @@ internal class DdRumTest { testedDdRum.stopAction(type, name, fakeContext.toReadableMap(), fakeTimestamp, mockPromise) // Then - verify(mockRumMonitor).stopUserAction(RumActionType.CUSTOM, name, updatedContext) + verify(mockRumMonitor).stopAction(RumActionType.CUSTOM, name, updatedContext) } @Test @@ -245,8 +252,12 @@ internal class DdRumTest { // When testedDdRum.startResource( - key, method, url, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + key, + method, + url, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then @@ -364,8 +375,12 @@ internal class DdRumTest { // When testedDdRum.addError( - message, source.name, stackTrace, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + message, + source.name, + stackTrace, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then @@ -385,8 +400,12 @@ internal class DdRumTest { // When testedDdRum.addError( - message, source, stackTrace, fakeContext.toReadableMap(), - fakeTimestamp, mockPromise + message, + source, + stackTrace, + fakeContext.toReadableMap(), + fakeTimestamp, + mockPromise ) // Then @@ -400,7 +419,6 @@ internal class DdRumTest { @Test fun `M call addTiming W addTiming()`(@StringForgery timing: String) { - // When testedDdRum.addTiming(timing, mockPromise) @@ -410,7 +428,6 @@ internal class DdRumTest { @Test fun `M call stopSession W stopSession()`() { - // When testedDdRum.stopSession(mockPromise) diff --git a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt index 6ec62d4f6..2d2654384 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt @@ -12,24 +12,23 @@ import android.view.Choreographer import com.datadog.android.DatadogSite import com.datadog.android.core.configuration.BatchSize import com.datadog.android.core.configuration.Configuration -import com.datadog.android.core.configuration.Credentials import com.datadog.android.core.configuration.UploadFrequency -import com.datadog.android.core.configuration.VitalsUpdateFrequency import com.datadog.android.event.EventMapper -import com.datadog.android.plugin.DatadogPlugin +import com.datadog.android.log.LogsConfiguration import com.datadog.android.privacy.TrackingConsent -import com.datadog.android.rum.GlobalRum -import com.datadog.android.rum.RumMonitor +import com.datadog.android.rum.RumConfiguration import com.datadog.android.rum.RumPerformanceMetric import com.datadog.android.rum._RumInternalProxy +import com.datadog.android.rum.configuration.VitalsUpdateFrequency import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ResourceEvent import com.datadog.android.rum.tracking.ActivityViewTrackingStrategy import com.datadog.android.telemetry.model.TelemetryConfigurationEvent -import com.datadog.android.tracing.TracingHeaderType +import com.datadog.android.trace.TraceConfiguration +import com.datadog.android.trace.TracingHeaderType import com.datadog.tools.unit.GenericAssert.Companion.assertThat +import com.datadog.tools.unit.MockRumMonitor import com.datadog.tools.unit.forge.BaseConfigurator -import com.datadog.tools.unit.getStaticValue import com.datadog.tools.unit.setStaticValue import com.datadog.tools.unit.toReadableArray import com.datadog.tools.unit.toReadableJavaOnlyMap @@ -65,7 +64,6 @@ import fr.xgouchet.elmyr.junit5.ForgeExtension import java.net.InetSocketAddress import java.net.Proxy import java.util.Locale -import java.util.concurrent.atomic.AtomicBoolean import java.util.stream.Stream import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.AfterEach @@ -111,7 +109,7 @@ internal class DdSdkTest { lateinit var mockContext: ReactApplicationContext @Mock - lateinit var mockRumMonitor: RumMonitor + lateinit var mockRumMonitor: MockRumMonitor @Mock lateinit var mockRumInternalProxy: _RumInternalProxy @@ -133,7 +131,7 @@ internal class DdSdkTest { @BeforeEach fun `set up`() { - GlobalRum.registerIfAbsent(mockRumMonitor) + whenever(mockDatadog.getRumMonitor()) doReturn mockRumMonitor whenever(mockRumMonitor._getInternal()) doReturn mockRumInternalProxy doNothing().whenever(mockChoreographer).postFrameCallback(any()) @@ -156,8 +154,6 @@ internal class DdSdkTest { @AfterEach fun `tear down`() { GlobalState.globalAttributes.clear() - GlobalRum.javaClass.setStaticValue("monitor", mock()) - GlobalRum.javaClass.getStaticValue("isRegistered").set(false) } // region initialize / nativeCrashReportEnabled @@ -166,8 +162,10 @@ internal class DdSdkTest { fun `𝕄 initialize native SDK 𝕎 initialize() {nativeCrashReportEnabled=true}`() { // Given val bridgeConfiguration = fakeConfiguration.copy(nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -176,46 +174,38 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") + .hasFieldEqualTo("crashReportsEnabled", true) .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test fun `𝕄 initialize native SDK 𝕎 initialize() {nativeCrashReportEnabled=false}`() { // Given fakeConfiguration = fakeConfiguration.copy(nativeCrashReportEnabled = false, site = null) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -224,44 +214,38 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasFieldEqualTo("crashReportConfig", null) - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") + .hasFieldEqualTo("crashReportsEnabled", false) .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test fun `𝕄 initialize native SDK 𝕎 initialize() {nativeCrashReportEnabled=null}`() { // Given fakeConfiguration = fakeConfiguration.copy(nativeCrashReportEnabled = false, site = null) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -270,36 +254,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasFieldEqualTo("crashReportConfig", null) - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") + .hasFieldEqualTo("crashReportsEnabled", false) .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } // endregion @@ -309,8 +285,10 @@ internal class DdSdkTest { @Test fun `𝕄 initialize native with sample rate SDK 𝕎 initialize() {}`() { // Given - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() val expectedRumSampleRate = fakeConfiguration.sampleRate?.toFloat() ?: 100f // When @@ -320,36 +298,30 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - it.hasFieldEqualTo("samplingRate", expectedRumSampleRate) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("sampleRate", expectedRumSampleRate) + } } // endregion @@ -359,8 +331,10 @@ internal class DdSdkTest { @Test fun `𝕄 initialize native with telemetry sample rate SDK 𝕎 initialize() {}`() { // Given - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() val expectedTelemetrySampleRate = fakeConfiguration.telemetrySampleRate?.toFloat() ?: 20f // When @@ -370,36 +344,30 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - it.hasFieldEqualTo("telemetrySamplingRate", expectedTelemetrySampleRate) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("telemetrySampleRate", expectedTelemetrySampleRate) + } } // endregion @@ -410,8 +378,10 @@ internal class DdSdkTest { fun `𝕄 initialize native SDK 𝕎 initialize() {additionalConfig=null}`() { // Given fakeConfiguration = fakeConfiguration.copy(additionalConfig = null) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -420,39 +390,33 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo("additionalConfig", emptyMap()) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test fun `𝕄 initialize native SDK 𝕎 initialize() {additionalConfig=nonNull}`() { // Given - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -461,35 +425,27 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) } - .hasField("logsConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } // endregion @@ -502,8 +458,10 @@ internal class DdSdkTest { ) { // Given fakeConfiguration = fakeConfiguration.copy(site = null, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -512,42 +470,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.US1) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -557,8 +501,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("us1") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -567,42 +513,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.US1) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -612,8 +544,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("us3") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -622,42 +556,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.US3) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US3.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US3.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US3.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US3.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -667,8 +587,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("us5") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -677,42 +599,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.US5) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US5.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US5.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US5.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US5.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -722,8 +630,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("us1_fed") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -732,42 +642,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.US1_FED) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1_FED.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1_FED.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1_FED.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.US1_FED.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -777,8 +673,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("eu1") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -787,42 +685,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.EU1) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.EU1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.EU1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.EU1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.EU1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } @Test @@ -832,8 +716,10 @@ internal class DdSdkTest { // Given val site = forge.randomizeCase("ap1") fakeConfiguration = fakeConfiguration.copy(site = site, nativeCrashReportEnabled = true) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -842,42 +728,28 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { it.hasFieldEqualTo("needsClearTextHttp", false) it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + it.hasFieldEqualTo("site", DatadogSite.AP1) } - .hasField("logsConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.AP1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("tracesConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.AP1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("rumConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.AP1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } - .hasField("crashReportConfig") { - it.hasFieldEqualTo("endpointUrl", DatadogSite.AP1.intakeEndpoint) - it.hasFieldEqualTo("plugins", emptyList()) - } + .hasFieldEqualTo("clientToken", fakeConfiguration.clientToken) + .hasFieldEqualTo("env", fakeConfiguration.env) + .hasFieldEqualTo("variant", "") .hasFieldEqualTo( "additionalConfig", fakeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() ) - val credentials = credentialCaptor.firstValue - assertThat(credentials.clientToken).isEqualTo(fakeConfiguration.clientToken) - assertThat(credentials.envName).isEqualTo(fakeConfiguration.env) - assertThat(credentials.rumApplicationId).isEqualTo(fakeConfiguration.applicationId) - assertThat(credentials.variant).isEqualTo("") + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", fakeConfiguration.applicationId) } // endregion @@ -888,8 +760,10 @@ internal class DdSdkTest { fun `𝕄 initialize native SDK 𝕎 initialize() {trackingConsent=null}`() { // Given fakeConfiguration = fakeConfiguration.copy(trackingConsent = null) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -898,11 +772,12 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), eq(TrackingConsent.PENDING) ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } } @@ -913,8 +788,10 @@ internal class DdSdkTest { // Given val consent = forge.randomizeCase("PENDING") fakeConfiguration = fakeConfiguration.copy(trackingConsent = consent) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -923,11 +800,12 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), eq(TrackingConsent.PENDING) ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } } @@ -938,8 +816,10 @@ internal class DdSdkTest { // Given val consent = forge.randomizeCase("GRANTED") fakeConfiguration = fakeConfiguration.copy(trackingConsent = consent) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -948,11 +828,12 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), eq(TrackingConsent.GRANTED) ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } } @@ -963,8 +844,10 @@ internal class DdSdkTest { // Given val consent = forge.randomizeCase("NOT_GRANTED") fakeConfiguration = fakeConfiguration.copy(trackingConsent = consent) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -973,11 +856,12 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), + sdkConfigCaptor.capture(), eq(TrackingConsent.NOT_GRANTED) ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } } @@ -989,8 +873,10 @@ internal class DdSdkTest { ) { // Given val bridgeConfiguration = configuration.copy(additionalConfig = null) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -999,14 +885,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("viewTrackingStrategy", NoOpViewTrackingStrategy) } } @@ -1021,8 +908,10 @@ internal class DdSdkTest { DdSdkImplementation.DD_NATIVE_VIEW_TRACKING to false ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1031,14 +920,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("viewTrackingStrategy", NoOpViewTrackingStrategy) } } @@ -1053,8 +943,10 @@ internal class DdSdkTest { DdSdkImplementation.DD_NATIVE_VIEW_TRACKING to true ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1063,14 +955,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("viewTrackingStrategy", ActivityViewTrackingStrategy(false)) } } @@ -1085,8 +978,10 @@ internal class DdSdkTest { DdSdkImplementation.DD_NATIVE_INTERACTION_TRACKING to false ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1095,18 +990,16 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { - it.hasFieldWithClass( - "userActionTrackingStrategy", - "com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy" - ) + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("viewTrackingStrategy", NoOpViewTrackingStrategy) } } @@ -1118,8 +1011,10 @@ internal class DdSdkTest { val bridgeConfiguration = configuration.copy( trackFrustrations = true ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1128,18 +1023,16 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { - it.hasFieldEqualTo( - "trackFrustrations", - true - ) + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("trackFrustrations", true) } } @@ -1151,8 +1044,10 @@ internal class DdSdkTest { val bridgeConfiguration = configuration.copy( trackFrustrations = false ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1161,18 +1056,16 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { - it.hasFieldEqualTo( - "trackFrustrations", - false - ) + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("trackFrustrations", false) } } @@ -1186,8 +1079,10 @@ internal class DdSdkTest { DdSdkImplementation.DD_NATIVE_INTERACTION_TRACKING to true ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1196,19 +1091,16 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - verify(mockDatadog).registerRumMonitor(any()) - } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { - it.hasFieldWithClass( - "userActionTrackingStrategy", - "com.datadog.android.rum.internal" + - ".instrumentation.UserActionTrackingStrategyLegacy" - ) + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("userActionTracking", true) } } @@ -1222,8 +1114,10 @@ internal class DdSdkTest { DdSdkImplementation.DD_NATIVE_INTERACTION_TRACKING to null ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1232,21 +1126,19 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - verify(mockDatadog).registerRumMonitor(any()) - } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { - it.hasFieldWithClass( - "userActionTrackingStrategy", - "com.datadog.android.rum.internal" + - ".instrumentation.UserActionTrackingStrategyLegacy" - ) + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { + it.hasFieldEqualTo("userActionTracking", true) } } + @Test fun `𝕄 initialize native SDK 𝕎 initialize() {sdk verbosity}`( @Forgery configuration: DdSdkConfiguration, @@ -1303,20 +1195,40 @@ internal class DdSdkTest { DdSdkImplementation.DD_SERVICE_NAME to serviceName ) ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(credentialCaptor.firstValue.serviceName).isEqualTo(serviceName) + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(sdkConfigCaptor.firstValue) + .hasField("coreConfig") { + it.hasFieldEqualTo("needsClearTextHttp", false) + it.hasFieldEqualTo("firstPartyHostsWithHeaderTypes", emptyMap()) + } + .hasFieldEqualTo("clientToken", bridgeConfiguration.clientToken) + .hasFieldEqualTo("env", bridgeConfiguration.env) + .hasFieldEqualTo("variant", "") + .hasFieldEqualTo("service", serviceName) + .hasFieldEqualTo( + "additionalConfig", + bridgeConfiguration.additionalConfig?.filterValues { it != null }.orEmpty() + ) + assertThat(rumConfigCaptor.firstValue) + .hasFieldEqualTo("applicationId", bridgeConfiguration.applicationId) } @Test @@ -1330,21 +1242,27 @@ internal class DdSdkTest { val bridgeConfiguration = configuration.copy( nativeLongTaskThresholdMs = threshold ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { rumConfig -> + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { rumConfig -> rumConfig.hasField("longTaskTrackingStrategy") { longTaskTrackingStrategy -> longTaskTrackingStrategy .isInstanceOf( @@ -1365,21 +1283,27 @@ internal class DdSdkTest { val bridgeConfiguration = configuration.copy( nativeLongTaskThresholdMs = 0.0 ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { rumConfig -> + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { rumConfig -> rumConfig.doesNotHaveField("longTaskTrackingStrategy") } } @@ -1422,19 +1346,26 @@ internal class DdSdkTest { DdSdkImplementation.DD_FIRST_PARTY_HOSTS to firstPartyHosts.toReadableArray() ) ) - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { coreConfig -> coreConfig.hasFieldEqualTo( "firstPartyHostsWithHeaderTypes", @@ -1452,7 +1383,7 @@ internal class DdSdkTest { Pair( forge.aStringMatching("[a-z]+\\.[a-z]{3}"), setOf( - TracingHeaderType.DATADOG, + TracingHeaderType.DATADOG ) ) } @@ -1476,19 +1407,26 @@ internal class DdSdkTest { DdSdkImplementation.DD_FIRST_PARTY_HOSTS to firstPartyHosts.toReadableArray() ) ) - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { coreConfig -> coreConfig.hasFieldEqualTo( "firstPartyHostsWithHeaderTypes", @@ -1508,9 +1446,9 @@ internal class DdSdkTest { host, setOf( TracingHeaderType.DATADOG, - TracingHeaderType.B3, + TracingHeaderType.B3 ) - ), + ) ) val firstPartyHosts = mutableListOf() @@ -1518,7 +1456,7 @@ internal class DdSdkTest { mapOf( "match" to host, "propagatorTypes" to listOf( - TracingHeaderType.DATADOG.name.lowercase(), + TracingHeaderType.DATADOG.name.lowercase() ).toReadableArray() ).toReadableMap() ) @@ -1526,7 +1464,7 @@ internal class DdSdkTest { mapOf( "match" to host, "propagatorTypes" to listOf( - TracingHeaderType.B3.name.lowercase(), + TracingHeaderType.B3.name.lowercase() ).toReadableArray() ).toReadableMap() ) @@ -1537,19 +1475,26 @@ internal class DdSdkTest { DdSdkImplementation.DD_FIRST_PARTY_HOSTS to firstPartyHosts.toReadableArray() ) ) - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(sdkConfigCaptor.firstValue) .hasField("coreConfig") { coreConfig -> coreConfig.hasFieldEqualTo( "firstPartyHostsWithHeaderTypes", @@ -1567,10 +1512,12 @@ internal class DdSdkTest { ) { // Given val bridgeConfiguration = configuration.copy( - uploadFrequency = input, + uploadFrequency = input ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1579,15 +1526,19 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("coreConfig") { - it.hasFieldEqualTo("uploadFrequency", expectedUploadFrequency) + assertThat(sdkConfigCaptor.firstValue) + .hasField("coreConfig") { coreConfig -> + coreConfig.hasFieldEqualTo( + "uploadFrequency", + expectedUploadFrequency + ) } } @@ -1600,10 +1551,12 @@ internal class DdSdkTest { ) { // Given val bridgeConfiguration = configuration.copy( - batchSize = input, + batchSize = input ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1612,15 +1565,19 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("coreConfig") { - it.hasFieldEqualTo("batchSize", expectedBatchSize) + assertThat(sdkConfigCaptor.firstValue) + .hasField("coreConfig") { coreConfig -> + coreConfig.hasFieldEqualTo( + "batchSize", + expectedBatchSize + ) } } @@ -1632,10 +1589,12 @@ internal class DdSdkTest { // Given val trackBackgroundEvents = forge.aNullable { forge.aBool() } val bridgeConfiguration = configuration.copy( - trackBackgroundEvents = trackBackgroundEvents, + trackBackgroundEvents = trackBackgroundEvents ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1644,14 +1603,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("backgroundEventTracking", trackBackgroundEvents ?: false) } } @@ -1664,8 +1624,10 @@ internal class DdSdkTest { val bridgeConfiguration = configuration.copy( vitalsUpdateFrequency = "RARE" ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1674,14 +1636,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("vitalsMonitorUpdateFrequency", VitalsUpdateFrequency.RARE) } argumentCaptor { @@ -1700,8 +1663,10 @@ internal class DdSdkTest { vitalsUpdateFrequency = "NEVER", longTaskThresholdMs = 0.0 ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) @@ -1710,14 +1675,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("vitalsMonitorUpdateFrequency", VitalsUpdateFrequency.NEVER) } verifyZeroInteractions(mockChoreographer) @@ -1736,8 +1702,10 @@ internal class DdSdkTest { vitalsUpdateFrequency = fakeFrequency, longTaskThresholdMs = 0.0 ) - val credentialCaptor = argumentCaptor() - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() val frameDurationNs = threshold + frameDurationOverThreshold // When @@ -1747,14 +1715,15 @@ internal class DdSdkTest { inOrder(mockDatadog) { verify(mockDatadog).initialize( same(mockContext), - credentialCaptor.capture(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) + sdkConfigCaptor.capture(), + any() ) - verify(mockDatadog).registerRumMonitor(any()) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) } - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { it.hasFieldEqualTo("vitalsMonitorUpdateFrequency", VitalsUpdateFrequency.AVERAGE) } argumentCaptor { @@ -1787,7 +1756,7 @@ internal class DdSdkTest { // Given val bridgeConfiguration = configuration.copy( vitalsUpdateFrequency = "AVERAGE", - longTaskThresholdMs = (threshold / 1_000_000).toDouble(), + longTaskThresholdMs = (threshold / 1_000_000).toDouble() ) val frameDurationNs = threshold + frameDurationOverThreshold @@ -1824,7 +1793,7 @@ internal class DdSdkTest { // Given val bridgeConfiguration = configuration.copy( vitalsUpdateFrequency = "NEVER", - longTaskThresholdMs = (threshold / 1_000_000).toDouble(), + longTaskThresholdMs = (threshold / 1_000_000).toDouble() ) val frameDurationNs = threshold + frameDurationOverThreshold @@ -1866,19 +1835,26 @@ internal class DdSdkTest { DdSdkImplementation.DD_VERSION_SUFFIX to versionSuffix ) ) - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(sdkConfigCaptor.firstValue) .hasFieldEqualTo( "additionalConfig", mapOf( @@ -1919,22 +1895,31 @@ internal class DdSdkTest { reactNativeVersion = reactNativeVersion ) ) - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(bridgeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - eq(configuration.trackingConsent.asTrackingConsent()) - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { val configurationMapper = it - .getActualValue>("rumEventMapper") + .getActualValue>( + "telemetryConfigurationMapper" + ) val result = configurationMapper.map(telemetryConfigurationEvent)!! assertThat(result.telemetry.configuration.trackNativeErrors!!).isEqualTo( trackNativeErrors @@ -1964,25 +1949,32 @@ internal class DdSdkTest { @Test fun `𝕄 set a resource mapper that does not drop resources 𝕎 initialize() {}`( - @Forgery resourceEvent: ResourceEvent, + @Forgery resourceEvent: ResourceEvent ) { // Given - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - any() - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { val resourceMapper = it - .getActualValue>("rumEventMapper") + .getActualValue>("resourceEventMapper") val notDroppedEvent = resourceMapper.map(resourceEvent) assertThat(notDroppedEvent).isNotNull } @@ -1990,26 +1982,33 @@ internal class DdSdkTest { @Test fun `𝕄 set a resource mapper that drops flagged resources 𝕎 initialize() {}`( - @Forgery resourceEvent: ResourceEvent, + @Forgery resourceEvent: ResourceEvent ) { // Given - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() resourceEvent.context?.additionalProperties?.put("_dd.resource.drop_resource", true) // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - any() - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { val resourceMapper = it - .getActualValue>("rumEventMapper") + .getActualValue>("resourceEventMapper") val droppedEvent = resourceMapper.map(resourceEvent) assertThat(droppedEvent).isNull() } @@ -2021,25 +2020,32 @@ internal class DdSdkTest { @Test fun `𝕄 set a action mapper that does not drop actions 𝕎 initialize() {}`( - @Forgery actionEvent: ActionEvent, + @Forgery actionEvent: ActionEvent ) { // Given - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - any() - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { val actionMapper = it - .getActualValue>("rumEventMapper") + .getActualValue>("actionEventMapper") val notDroppedEvent = actionMapper.map(actionEvent) assertThat(notDroppedEvent).isNotNull } @@ -2047,26 +2053,33 @@ internal class DdSdkTest { @Test fun `𝕄 set a action mapper that drops flagged actions 𝕎 initialize() {}`( - @Forgery actionEvent: ActionEvent, + @Forgery actionEvent: ActionEvent ) { // Given - val configCaptor = argumentCaptor() + val sdkConfigCaptor = argumentCaptor() + val rumConfigCaptor = argumentCaptor() + val logsConfigCaptor = argumentCaptor() + val traceConfigCaptor = argumentCaptor() actionEvent.context?.additionalProperties?.put("_dd.action.drop_action", true) // When testedBridgeSdk.initialize(fakeConfiguration.toReadableJavaOnlyMap(), mockPromise) // Then - verify(mockDatadog).initialize( - same(mockContext), - any(), - configCaptor.capture(), - any() - ) - assertThat(configCaptor.firstValue) - .hasField("rumConfig") { + inOrder(mockDatadog) { + verify(mockDatadog).initialize( + same(mockContext), + sdkConfigCaptor.capture(), + any() + ) + verify(mockDatadog).enableRum(rumConfigCaptor.capture()) + verify(mockDatadog).enableTrace(traceConfigCaptor.capture()) + verify(mockDatadog).enableLogs(logsConfigCaptor.capture()) + } + assertThat(rumConfigCaptor.firstValue) + .hasField("featureConfiguration") { val actionMapper = it - .getActualValue>("rumEventMapper") + .getActualValue>("actionEventMapper") val droppedEvent = actionMapper.map(actionEvent) assertThat(droppedEvent).isNull() } @@ -2266,7 +2279,6 @@ internal class DdSdkTest { @Test fun `𝕄 build Granted consent 𝕎 buildTrackingConsent {granted}`(forge: Forge) { - // When val consent = testedBridgeSdk.buildTrackingConsent( forge.anElementFrom("granted", "GRANTED") @@ -2278,7 +2290,6 @@ internal class DdSdkTest { @Test fun `𝕄 build Pending consent 𝕎 buildTrackingConsent {pending}`(forge: Forge) { - // When val consent = testedBridgeSdk.buildTrackingConsent( forge.anElementFrom("pending", "PENDING") @@ -2290,7 +2301,6 @@ internal class DdSdkTest { @Test fun `𝕄 build Granted consent 𝕎 buildTrackingConsent {not_granted}`(forge: Forge) { - // When val consent = testedBridgeSdk.buildTrackingConsent( forge.anElementFrom("not_granted", "NOT_GRANTED") @@ -2302,7 +2312,6 @@ internal class DdSdkTest { @Test fun `𝕄 build default Pending consent 𝕎 buildTrackingConsent {any}`(forge: Forge) { - // When val consent = testedBridgeSdk.buildTrackingConsent( forge.anElementFrom(null, "some-type") @@ -2314,7 +2323,6 @@ internal class DdSdkTest { @Test fun `𝕄 call setTrackingConsent 𝕎 setTrackingConsent ()`(forge: Forge) { - // Given val consent = forge.anElementFrom("pending", "granted", "not_granted") @@ -2329,7 +2337,6 @@ internal class DdSdkTest { fun `𝕄 not build proxy config 𝕎 no proxy config specified`( @Forgery configuration: DdSdkConfiguration ) { - // Given val config = configuration.copy(additionalConfig = null) @@ -2520,7 +2527,7 @@ internal class DdSdkTest { return Stream.of( Arguments.of("SMALL", BatchSize.SMALL), Arguments.of("MEDIUM", BatchSize.MEDIUM), - Arguments.of("LARGE", BatchSize.LARGE), + Arguments.of("LARGE", BatchSize.LARGE) ) } @@ -2529,7 +2536,7 @@ internal class DdSdkTest { return Stream.of( Arguments.of("RARE", UploadFrequency.RARE), Arguments.of("AVERAGE", UploadFrequency.AVERAGE), - Arguments.of("FREQUENT", UploadFrequency.FREQUENT), + Arguments.of("FREQUENT", UploadFrequency.FREQUENT) ) } } diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/DdSdkConfigurationExt.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/DdSdkConfigurationExt.kt index 6e4e61b7e..ec19003cc 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/DdSdkConfigurationExt.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/DdSdkConfigurationExt.kt @@ -8,7 +8,7 @@ package com.datadog.tools.unit import com.datadog.android.core.configuration.BatchSize import com.datadog.android.core.configuration.UploadFrequency -import com.datadog.android.core.configuration.VitalsUpdateFrequency +import com.datadog.android.rum.configuration.VitalsUpdateFrequency import com.datadog.reactnative.ConfigurationForTelemetry import com.datadog.reactnative.DdSdkConfiguration import com.facebook.react.bridge.ReadableMap diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/MockRumMonitor.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/MockRumMonitor.kt new file mode 100644 index 000000000..d389be984 --- /dev/null +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/MockRumMonitor.kt @@ -0,0 +1,108 @@ +package com.datadog.tools.unit + +import com.datadog.android.rum.RumActionType +import com.datadog.android.rum.RumErrorSource +import com.datadog.android.rum.RumMonitor +import com.datadog.android.rum.RumResourceKind +import com.datadog.android.rum._RumInternalProxy + +class MockRumMonitor : RumMonitor { + override var debug = false + + override fun _getInternal(): _RumInternalProxy? { + return null + } + + override fun addAction( + type: RumActionType, + name: String, + attributes: Map + ) {} + + override fun addAttribute(key: String, value: Any?) {} + + override fun addError( + message: String, + source: RumErrorSource, + throwable: Throwable?, + attributes: Map + ) {} + + override fun addErrorWithStacktrace( + message: String, + source: RumErrorSource, + stacktrace: String?, + attributes: Map + ) {} + + override fun addFeatureFlagEvaluation(name: String, value: Any) {} + + override fun addTiming(name: String) {} + + override fun clearAttributes() {} + + override fun getAttributes(): Map { + return mapOf() + } + + override fun removeAttribute(key: String) {} + + override fun startAction( + type: RumActionType, + name: String, + attributes: Map + ) {} + + override fun startResource( + key: String, + method: String, + url: String, + attributes: Map + ) {} + + override fun startView( + key: Any, + name: String, + attributes: Map + ) {} + + override fun stopAction( + type: RumActionType, + name: String, + attributes: Map + ) {} + + override fun stopResource( + key: String, + statusCode: Int?, + size: Long?, + kind: RumResourceKind, + attributes: Map + ) {} + + override fun stopResourceWithError( + key: String, + statusCode: Int?, + message: String, + source: RumErrorSource, + stackTrace: String, + errorType: String?, + attributes: Map + ) {} + + override fun stopResourceWithError( + key: String, + statusCode: Int?, + message: String, + source: RumErrorSource, + throwable: Throwable, + attributes: Map + ) {} + + override fun stopSession() {} + + override fun stopView( + key: Any, + attributes: Map + ) {} +} diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/ReflectUtils.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/ReflectUtils.kt index 291c840f8..49beb4465 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/ReflectUtils.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/ReflectUtils.kt @@ -81,7 +81,6 @@ inline fun getStaticValue( * @param fieldName the name of the field */ inline fun Class.getStaticValue(fieldName: String): R { - val field = getDeclaredField(fieldName) // make it accessible diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ActionEventForgeryFactory.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ActionEventForgeryFactory.kt index e39a24f3c..994f28703 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ActionEventForgeryFactory.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ActionEventForgeryFactory.kt @@ -92,7 +92,7 @@ internal class ActionEventForgeryFactory : name = forge.anAlphabeticalString(), model = forge.anAlphabeticalString(), brand = forge.anAlphabeticalString(), - type = forge.aValueFrom(ActionEvent.DeviceType::class.java), + type = forge.aValueFrom(ActionEvent.DeviceType::class.java) ), context = ActionEvent.Context( additionalProperties = mutableMapOf() diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/DdSdkConfigurationForgeryFactory.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/DdSdkConfigurationForgeryFactory.kt index adb0e2587..5294931b1 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/DdSdkConfigurationForgeryFactory.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/DdSdkConfigurationForgeryFactory.kt @@ -17,7 +17,7 @@ class DdSdkConfigurationForgeryFactory : ForgeryFactory { return DdSdkConfiguration( clientToken = forge.aStringMatching("pub[a-f0-9]{32}"), env = forge.anAlphabeticalString(), - applicationId = forge.aNullable { getForgery().toString() }, + applicationId = forge.getForgery().toString(), nativeCrashReportEnabled = forge.aNullable { aBool() }, nativeLongTaskThresholdMs = forge.aNullable { aDouble(100.0, 5000.0) }, longTaskThresholdMs = forge.aDouble(0.0, 100.0), @@ -63,9 +63,9 @@ class DdSdkConfigurationForgeryFactory : ForgeryFactory { trackInteractions = forge.aBool(), trackNetworkRequests = forge.aBool(), reactVersion = forge.aString(), - reactNativeVersion = forge.aString(), + reactNativeVersion = forge.aString() ), - trackFrustrations = forge.aNullable { aBool() }, + trackFrustrations = forge.aNullable { aBool() } ) } } diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ResourceEventForgeryFactory.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ResourceEventForgeryFactory.kt index 6cfaf3930..dae18a67d 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ResourceEventForgeryFactory.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/ResourceEventForgeryFactory.kt @@ -100,7 +100,7 @@ internal class ResourceEventForgeryFactory : name = forge.anAlphabeticalString(), model = forge.anAlphabeticalString(), brand = forge.anAlphabeticalString(), - type = forge.aValueFrom(ResourceEvent.DeviceType::class.java), + type = forge.aValueFrom(ResourceEvent.DeviceType::class.java) ), context = ResourceEvent.Context( additionalProperties = mutableMapOf() diff --git a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/TelemetryConfigurationEventForgeryFactory.kt b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/TelemetryConfigurationEventForgeryFactory.kt index 7f56c3219..98a550338 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/TelemetryConfigurationEventForgeryFactory.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/tools/unit/forge/TelemetryConfigurationEventForgeryFactory.kt @@ -59,6 +59,7 @@ internal class TelemetryConfigurationEventForgeryFactory : forge.aNullable { aBool() }, forge.aNullable { aBool() }, forge.aNullable { aBool() }, + forge.aNullable { aBool() }, forge.aNullable { aString() }, forge.aNullable { aBool() }, forge.aNullable { aBool() },