diff --git a/packages/core/android/build.gradle b/packages/core/android/build.gradle index 72d09314b..d9bcd40d4 100644 --- a/packages/core/android/build.gradle +++ b/packages/core/android/build.gradle @@ -138,6 +138,9 @@ android { } repositories { + maven{ + url "https://oss.sonatype.org/content/repositories/snapshots/" + } mavenCentral() google() maven { url "https://jitpack.io" } @@ -171,10 +174,10 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compileOnly "com.squareup.okhttp3:okhttp:3.12.13" - implementation "com.datadoghq:dd-sdk-android-rum:2.3.0" - implementation "com.datadoghq:dd-sdk-android-logs:2.3.0" - implementation "com.datadoghq:dd-sdk-android-trace:2.3.0" - implementation "com.datadoghq:dd-sdk-android-webview:2.3.0" + implementation "com.datadoghq:dd-sdk-android-rum:2.4.0-SNAPSHOT" + implementation "com.datadoghq:dd-sdk-android-logs:2.4.0-SNAPSHOT" + implementation "com.datadoghq:dd-sdk-android-trace:2.4.0-SNAPSHOT" + implementation "com.datadoghq:dd-sdk-android-webview:2.4.0-SNAPSHOT" 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" diff --git a/packages/react-native-session-replay/android/build.gradle b/packages/react-native-session-replay/android/build.gradle index 7a3585d48..9e7a30aa7 100644 --- a/packages/react-native-session-replay/android/build.gradle +++ b/packages/react-native-session-replay/android/build.gradle @@ -138,6 +138,9 @@ android { } repositories { + maven{ + url "https://oss.sonatype.org/content/repositories/snapshots/" + } mavenCentral() google() maven { url "https://jitpack.io" } @@ -169,7 +172,7 @@ dependencies { api "com.facebook.react:react-android:$reactNativeVersion" } implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "com.datadoghq:dd-sdk-android-session-replay:2.3.0" + implementation "com.datadoghq:dd-sdk-android-session-replay:2.4.0-SNAPSHOT" testImplementation "org.junit.platform:junit-platform-launcher:1.6.2" testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2" diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt index c415e9734..ad1dee845 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt @@ -13,6 +13,8 @@ import com.datadog.android.sessionreplay.ExtensionSupport import com.datadog.android.sessionreplay.SessionReplayPrivacy import com.datadog.android.sessionreplay.internal.recorder.OptionSelectorDetector import com.datadog.android.sessionreplay.internal.recorder.mapper.WireframeMapper +import com.datadog.reactnative.sessionreplay.mappers.ReactMaskInputTextMapper +import com.datadog.reactnative.sessionreplay.mappers.ReactMaskTextMapper import com.datadog.reactnative.sessionreplay.mappers.ReactTextMapper import com.datadog.reactnative.sessionreplay.mappers.ReactViewGroupMapper import com.facebook.react.bridge.ReactContext @@ -34,10 +36,20 @@ internal class ReactNativeSessionReplayExtensionSupport( ReactViewGroup::class.java to ReactViewGroupMapper(), ReactTextView::class.java to ReactTextMapper(reactContext, uiManagerModule), ReactEditText::class.java to ReactTextMapper(reactContext, uiManagerModule) - ).mapValues{ - it.value as WireframeMapper - } - ) + ), + SessionReplayPrivacy.MASK to mapOf( + ReactViewGroup::class.java to ReactViewGroupMapper(), + ReactTextView::class.java to ReactMaskTextMapper(reactContext, uiManagerModule), + ReactEditText::class.java to ReactMaskTextMapper(reactContext, uiManagerModule) + ), + SessionReplayPrivacy.MASK_USER_INPUT to mapOf( + ReactViewGroup::class.java to ReactViewGroupMapper(), + ReactTextView::class.java to ReactMaskInputTextMapper(reactContext, uiManagerModule), + ReactEditText::class.java to ReactMaskInputTextMapper(reactContext, uiManagerModule) + ) + ).mapValues { + it.value as Map, WireframeMapper> + } } override fun getOptionSelectorDetectors(): List { diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskInputTextMapper.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskInputTextMapper.kt new file mode 100644 index 000000000..fe4807a4b --- /dev/null +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskInputTextMapper.kt @@ -0,0 +1,54 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.reactnative.sessionreplay.mappers + +import android.widget.TextView +import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback +import com.datadog.android.sessionreplay.internal.recorder.MappingContext +import com.datadog.android.sessionreplay.internal.recorder.mapper.MaskInputTextViewMapper +import com.datadog.android.sessionreplay.model.MobileSegment +import com.datadog.reactnative.sessionreplay.NoopTextPropertiesResolver +import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver +import com.datadog.reactnative.sessionreplay.TextPropertiesResolver +import com.datadog.reactnative.sessionreplay.utils.TextViewUtils +import com.facebook.react.bridge.ReactContext +import com.facebook.react.uimanager.UIManagerModule + +internal class ReactMaskInputTextMapper( + private val reactTextPropertiesResolver: TextPropertiesResolver = + NoopTextPropertiesResolver(), + private val textViewUtils: TextViewUtils = TextViewUtils() +): MaskInputTextViewMapper() { + + internal constructor( + reactContext: ReactContext, + uiManagerModule: UIManagerModule? + ): this( + reactTextPropertiesResolver = if (uiManagerModule == null) { + NoopTextPropertiesResolver() + } else { + ReactTextPropertiesResolver( + reactContext = reactContext, + uiManagerModule = uiManagerModule + ) + } + ) + + override fun map( + view: TextView, + mappingContext: MappingContext, + asyncJobStatusCallback: AsyncJobStatusCallback + ): List { + return textViewUtils.mapTextViewToWireframes( + mapper = this, + view = view, + mappingContext = mappingContext, + asyncJobStatusCallback = asyncJobStatusCallback, + reactTextPropertiesResolver = reactTextPropertiesResolver + ) + } +} diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskTextMapper.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskTextMapper.kt new file mode 100644 index 000000000..64da95e48 --- /dev/null +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskTextMapper.kt @@ -0,0 +1,54 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.reactnative.sessionreplay.mappers + +import android.widget.TextView +import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback +import com.datadog.android.sessionreplay.internal.recorder.MappingContext +import com.datadog.android.sessionreplay.internal.recorder.mapper.MaskTextViewMapper +import com.datadog.android.sessionreplay.model.MobileSegment +import com.datadog.reactnative.sessionreplay.NoopTextPropertiesResolver +import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver +import com.datadog.reactnative.sessionreplay.TextPropertiesResolver +import com.datadog.reactnative.sessionreplay.utils.TextViewUtils +import com.facebook.react.bridge.ReactContext +import com.facebook.react.uimanager.UIManagerModule + +internal class ReactMaskTextMapper( + private val reactTextPropertiesResolver: TextPropertiesResolver = + NoopTextPropertiesResolver(), + private val textViewUtils: TextViewUtils = TextViewUtils() +): MaskTextViewMapper() { + + internal constructor( + reactContext: ReactContext, + uiManagerModule: UIManagerModule? + ): this( + reactTextPropertiesResolver = if (uiManagerModule == null) { + NoopTextPropertiesResolver() + } else { + ReactTextPropertiesResolver( + reactContext = reactContext, + uiManagerModule = uiManagerModule + ) + } + ) + + override fun map( + view: TextView, + mappingContext: MappingContext, + asyncJobStatusCallback: AsyncJobStatusCallback + ): List { + return textViewUtils.mapTextViewToWireframes( + mapper = this, + view = view, + mappingContext = mappingContext, + asyncJobStatusCallback = asyncJobStatusCallback, + reactTextPropertiesResolver = reactTextPropertiesResolver + ) + } +} diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt index 6b5330912..888875e60 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt @@ -7,7 +7,6 @@ package com.datadog.reactnative.sessionreplay.mappers import android.widget.TextView -import androidx.annotation.VisibleForTesting import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback import com.datadog.android.sessionreplay.internal.recorder.MappingContext import com.datadog.android.sessionreplay.internal.recorder.mapper.TextViewMapper @@ -15,12 +14,14 @@ import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.reactnative.sessionreplay.NoopTextPropertiesResolver import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver import com.datadog.reactnative.sessionreplay.TextPropertiesResolver +import com.datadog.reactnative.sessionreplay.utils.TextViewUtils import com.facebook.react.bridge.ReactContext import com.facebook.react.uimanager.UIManagerModule internal class ReactTextMapper( private val reactTextPropertiesResolver: TextPropertiesResolver = - NoopTextPropertiesResolver() + NoopTextPropertiesResolver(), + private val textViewUtils: TextViewUtils = TextViewUtils() ): TextViewMapper() { internal constructor( @@ -42,31 +43,12 @@ internal class ReactTextMapper( mappingContext: MappingContext, asyncJobStatusCallback: AsyncJobStatusCallback ): List { - val result = mutableListOf() - val wireframes = mapOnSuperclass(view, mappingContext, asyncJobStatusCallback) - val pixelDensity = mappingContext.systemInformation.screenDensity - - wireframes.forEach { originalWireframe -> - if (originalWireframe !is MobileSegment.Wireframe.TextWireframe) { - result.add(originalWireframe) - } else { - result.add(reactTextPropertiesResolver.addReactNativeProperties( - originalWireframe = originalWireframe, - view = view, - pixelDensity = pixelDensity, - )) - } - } - - return result - } - - @VisibleForTesting - internal fun mapOnSuperclass( - textView: TextView, - mappingContext: MappingContext, - asyncJobStatusCallback: AsyncJobStatusCallback - ): List { - return super.map(textView, mappingContext, asyncJobStatusCallback) + return textViewUtils.mapTextViewToWireframes( + mapper = this, + view = view, + mappingContext = mappingContext, + asyncJobStatusCallback = asyncJobStatusCallback, + reactTextPropertiesResolver = reactTextPropertiesResolver + ) } } diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtils.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtils.kt new file mode 100644 index 000000000..c3d3fb11e --- /dev/null +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtils.kt @@ -0,0 +1,61 @@ +/* + * + * * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * * This product includes software developed at Datadog (https://www.datadoghq.com/). + * * Copyright 2016-Present Datadog, Inc. + * + */ + +package com.datadog.reactnative.sessionreplay.utils + +import android.widget.TextView +import androidx.annotation.VisibleForTesting +import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback +import com.datadog.android.sessionreplay.internal.recorder.MappingContext +import com.datadog.android.sessionreplay.internal.recorder.mapper.WireframeMapper +import com.datadog.android.sessionreplay.model.MobileSegment +import com.datadog.reactnative.sessionreplay.TextPropertiesResolver + +internal class TextViewUtils { + internal fun mapTextViewToWireframes( + mapper: WireframeMapper, + view: TextView, + mappingContext: MappingContext, + asyncJobStatusCallback: AsyncJobStatusCallback, + reactTextPropertiesResolver: TextPropertiesResolver + ): List { + val result = mutableListOf() + val pixelDensity = mappingContext.systemInformation.screenDensity + + val wireframes = mapOnSuperclass( + mapper = mapper, + textView = view, + mappingContext = mappingContext, + asyncJobStatusCallback = asyncJobStatusCallback + ) + + wireframes.forEach { originalWireframe -> + if (originalWireframe !is MobileSegment.Wireframe.TextWireframe) { + result.add(originalWireframe) + } else { + result.add(reactTextPropertiesResolver.addReactNativeProperties( + originalWireframe = originalWireframe, + view = view, + pixelDensity = pixelDensity, + )) + } + } + + return wireframes + } + + @VisibleForTesting + internal fun mapOnSuperclass( + mapper: WireframeMapper, + textView: TextView, + mappingContext: MappingContext, + asyncJobStatusCallback: AsyncJobStatusCallback + ): List { + return mapper.map(textView, mappingContext, asyncJobStatusCallback) + } +} diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt index 93c931c03..d393d30da 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt @@ -8,6 +8,8 @@ package com.datadog.reactnative.sessionreplay import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.SessionReplayPrivacy +import com.datadog.reactnative.sessionreplay.mappers.ReactMaskInputTextMapper +import com.datadog.reactnative.sessionreplay.mappers.ReactMaskTextMapper import com.datadog.reactnative.sessionreplay.mappers.ReactTextMapper import com.datadog.reactnative.sessionreplay.mappers.ReactViewGroupMapper import com.facebook.react.bridge.NativeModule @@ -76,6 +78,40 @@ internal class ReactNativeSessionReplayExtensionSupportTest { .isInstanceOf(ReactTextMapper::class.java) } + @Test + fun `M get mask input mappers W getCustomViewMappers()`() { + // When + val customViewMappers = testedExtensionSupport.getCustomViewMappers() + val maskUserInputMappers = customViewMappers[SessionReplayPrivacy.MASK_USER_INPUT] + + // Then + check(maskUserInputMappers != null) + assertThat(maskUserInputMappers).hasSize(3) + assertThat(maskUserInputMappers[ReactViewGroup::class.java]) + .isInstanceOf(ReactViewGroupMapper::class.java) + assertThat(maskUserInputMappers[ReactTextView::class.java]) + .isInstanceOf(ReactMaskInputTextMapper::class.java) + assertThat(maskUserInputMappers[ReactEditText::class.java]) + .isInstanceOf(ReactMaskInputTextMapper::class.java) + } + + @Test + fun `M get mask mappers W getCustomViewMappers()`() { + // When + val customViewMappers = testedExtensionSupport.getCustomViewMappers() + val maskMappers = customViewMappers[SessionReplayPrivacy.MASK] + + // Then + check(maskMappers != null) + assertThat(maskMappers).hasSize(3) + assertThat(maskMappers[ReactViewGroup::class.java]) + .isInstanceOf(ReactViewGroupMapper::class.java) + assertThat(maskMappers[ReactTextView::class.java]) + .isInstanceOf(ReactMaskTextMapper::class.java) + assertThat(maskMappers[ReactEditText::class.java]) + .isInstanceOf(ReactMaskTextMapper::class.java) + } + @Test fun `M return null W getUiManagerModule() { cannot get uiManagerModule }`() { // Given diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ColorUtilsTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/ColorUtilsTest.kt similarity index 91% rename from packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ColorUtilsTest.kt rename to packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/ColorUtilsTest.kt index fc8ae3ac8..6580cf61c 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ColorUtilsTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/ColorUtilsTest.kt @@ -4,9 +4,8 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.reactnative.sessionreplay +package com.datadog.reactnative.sessionreplay.utils -import com.datadog.reactnative.sessionreplay.utils.formatAsRgba import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/DrawableUtilsTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/DrawableUtilsTest.kt similarity index 96% rename from packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/DrawableUtilsTest.kt rename to packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/DrawableUtilsTest.kt index 5e2668bc2..f71c351d7 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/DrawableUtilsTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/DrawableUtilsTest.kt @@ -4,12 +4,11 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.reactnative.sessionreplay +package com.datadog.reactnative.sessionreplay.utils import android.graphics.drawable.ColorDrawable import android.graphics.drawable.InsetDrawable import android.graphics.drawable.LayerDrawable -import com.datadog.reactnative.sessionreplay.utils.DrawableUtils import com.facebook.react.views.view.ReactViewBackgroundDrawable import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapperTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtilsTest.kt similarity index 72% rename from packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapperTest.kt rename to packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtilsTest.kt index 29ff84190..abb70aa2d 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapperTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtilsTest.kt @@ -4,7 +4,7 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.reactnative.sessionreplay.mappers +package com.datadog.reactnative.sessionreplay.utils import android.content.res.Resources import android.graphics.Typeface @@ -15,6 +15,7 @@ import com.datadog.android.sessionreplay.internal.recorder.MappingContext import com.datadog.android.sessionreplay.internal.recorder.SystemInformation import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver +import com.datadog.reactnative.sessionreplay.mappers.ReactTextMapper import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat @@ -23,10 +24,10 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.Extensions import org.mockito.Mock +import org.mockito.Mockito.spy import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.eq -import org.mockito.kotlin.spy import org.mockito.kotlin.whenever import org.mockito.quality.Strictness @@ -35,8 +36,8 @@ import org.mockito.quality.Strictness ExtendWith(ForgeExtension::class) ) @MockitoSettings(strictness = Strictness.LENIENT) -internal class ReactTextMapperTest { - private lateinit var testedMapper: ReactTextMapper +internal class TextViewUtilsTest { + private lateinit var testedUtils: TextViewUtils @Mock private lateinit var mockReactTextPropertiesResolver: ReactTextPropertiesResolver @@ -62,6 +63,9 @@ internal class ReactTextMapperTest { @Mock private lateinit var mockTextWireframe: MobileSegment.Wireframe.TextWireframe + @Mock + private lateinit var mockReactTextMapper: ReactTextMapper + @BeforeEach fun `set up`(forge: Forge) { whenever(mockResources.displayMetrics).thenReturn(mockDisplayMetrics) @@ -71,19 +75,7 @@ internal class ReactTextMapperTest { whenever(mockTextView.text).thenReturn(forge.aString()) whenever(mockTextView.typeface).thenReturn(Typeface.SANS_SERIF) - whenever( - mockReactTextPropertiesResolver.addReactNativeProperties( - originalWireframe = eq(mockTextWireframe), - view = eq(mockTextView), - pixelDensity = eq(0f) - ) - ).thenReturn(mockTextWireframe) - - testedMapper = spy( - ReactTextMapper( - reactTextPropertiesResolver = mockReactTextPropertiesResolver - ) - ) + testedUtils = spy(TextViewUtils()) } @Test @@ -92,17 +84,22 @@ internal class ReactTextMapperTest { ) { // Given whenever( - testedMapper.mapOnSuperclass( + testedUtils.mapOnSuperclass( + mapper = eq(mockReactTextMapper), textView = eq(mockTextView), mappingContext = eq(mockMappingContext), asyncJobStatusCallback = eq(mockAsyncJobStatusCallback) ) - ).thenReturn( - listOf(mockImageWireframe) - ) + ).thenReturn(listOf(mockImageWireframe)) // When - val result = testedMapper.map(mockTextView, mockMappingContext, mockAsyncJobStatusCallback) + val result = testedUtils.mapTextViewToWireframes( + mapper = mockReactTextMapper, + view = mockTextView, + mappingContext = mockMappingContext, + asyncJobStatusCallback = mockAsyncJobStatusCallback, + reactTextPropertiesResolver = mockReactTextPropertiesResolver + ) // Then assertThat(result).contains(mockImageWireframe) @@ -112,28 +109,21 @@ internal class ReactTextMapperTest { fun `M return textWireframe W map()`() { // Given whenever( - testedMapper.mapOnSuperclass( + testedUtils.mapOnSuperclass( + mapper = eq(mockReactTextMapper), textView = eq(mockTextView), mappingContext = eq(mockMappingContext), asyncJobStatusCallback = eq(mockAsyncJobStatusCallback) ) - ).thenReturn( - listOf(mockTextWireframe) - ) - - whenever( - mockReactTextPropertiesResolver.addReactNativeProperties( - originalWireframe = eq(mockTextWireframe), - view = eq(mockTextView), - pixelDensity = eq(0f) - ) - ).thenReturn(mockTextWireframe) + ).thenReturn(listOf(mockTextWireframe)) // When - val result = testedMapper.map( - mockTextView, - mockMappingContext, - mockAsyncJobStatusCallback + val result = testedUtils.mapTextViewToWireframes( + mapper = mockReactTextMapper, + view = mockTextView, + mappingContext = mockMappingContext, + asyncJobStatusCallback = mockAsyncJobStatusCallback, + reactTextPropertiesResolver = mockReactTextPropertiesResolver )[0] as MobileSegment.Wireframe.TextWireframe // Then