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 dfbd31165..482699eac 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 @@ -32,12 +32,12 @@ internal class ReactNativeSessionReplayExtensionSupport( return mapOf( SessionReplayPrivacy.ALLOW to mapOf( - ReactViewGroup::class.java to ReactViewGroupMapper(logger), - ReactTextView::class.java to ReactTextMapper(logger, reactContext, uiManagerModule), - ReactEditText::class.java to ReactTextMapper(logger, reactContext, uiManagerModule) - ).map{ - it.key to it.value as WireframeMapper - }.toMap(), + ReactViewGroup::class.java to ReactViewGroupMapper(), + ReactTextView::class.java to ReactTextMapper(reactContext, uiManagerModule), + ReactEditText::class.java to ReactTextMapper(reactContext, uiManagerModule) + ).mapValues{ + it.value as WireframeMapper + } ) } diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolver.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolver.kt index 4cbb3c6d6..174039169 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolver.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolver.kt @@ -9,11 +9,11 @@ package com.datadog.reactnative.sessionreplay import android.view.Gravity import android.widget.TextView import androidx.annotation.VisibleForTesting -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.reactnative.sessionreplay.extensions.convertToDensityNormalized import com.datadog.reactnative.sessionreplay.utils.DrawableUtils import com.datadog.reactnative.sessionreplay.utils.ReactViewBackgroundDrawableUtils +import com.datadog.reactnative.sessionreplay.utils.ReflectionUtils import com.datadog.reactnative.sessionreplay.utils.formatAsRgba import com.facebook.react.bridge.ReactContext import com.facebook.react.uimanager.UIManagerModule @@ -22,13 +22,11 @@ import com.facebook.react.views.view.ReactViewBackgroundDrawable import java.util.Locale internal class ReactTextPropertiesResolver( - logger: InternalLogger, - reactContext: ReactContext, - uiManagerModule: UIManagerModule?, - private val shadowNodeWrapper: ShadowNodeWrapper = - ShadowNodeWrapper(logger, reactContext, uiManagerModule), + private val reactContext: ReactContext, + private val uiManagerModule: UIManagerModule, + private val reflectionUtils: ReflectionUtils = ReflectionUtils(), private val reactViewBackgroundDrawableUtils: ReactViewBackgroundDrawableUtils = - ReactViewBackgroundDrawableUtils(logger), + ReactViewBackgroundDrawableUtils(), private val drawableUtils: DrawableUtils = DrawableUtils() ): TextPropertiesResolver { override fun addReactNativeProperties( @@ -38,10 +36,14 @@ internal class ReactTextPropertiesResolver( ): MobileSegment.Wireframe.TextWireframe { val textWireframe = resolveDrawableProperties(view, pixelDensity, originalWireframe) - val isInitializedForView = shadowNodeWrapper.initialize(view.id) - if (!isInitializedForView) return textWireframe + val shadowNodeWrapper: ShadowNodeWrapper = + ShadowNodeWrapper.getShadowNodeWrapper( + reactContext = reactContext, + uiManagerModule = uiManagerModule, + reflectionUtils = reflectionUtils, + viewId = view.id) ?: return textWireframe - val textStyle = resolveTextStyle(textWireframe, pixelDensity) + val textStyle = resolveTextStyle(textWireframe, pixelDensity, shadowNodeWrapper) val textPosition = textWireframe.textPosition val padding = textPosition?.padding val alignment = resolveTextAlignment(view, textWireframe) @@ -106,13 +108,14 @@ internal class ReactTextPropertiesResolver( private fun resolveTextStyle( textWireframe: MobileSegment.Wireframe.TextWireframe, pixelsDensity: Float, + shadowNodeWrapper: ShadowNodeWrapper ): MobileSegment.TextStyle { - val fontFamily = getFontFamily() + val fontFamily = getFontFamily(shadowNodeWrapper) ?: textWireframe.textStyle.family - val fontSize = getFontSize() + val fontSize = getFontSize(shadowNodeWrapper) ?.convertToDensityNormalized(pixelsDensity) ?: textWireframe.textStyle.size - val fontColor = getTextColor() + val fontColor = getTextColor(shadowNodeWrapper) ?: textWireframe.textStyle.color return MobileSegment.TextStyle( @@ -122,7 +125,7 @@ internal class ReactTextPropertiesResolver( ) } - private fun getTextColor(): String? { + private fun getTextColor(shadowNodeWrapper: ShadowNodeWrapper): String? { val resolvedColor = shadowNodeWrapper .getDeclaredShadowNodeField(COLOR_FIELD_NAME) as Int? if (resolvedColor != null) { @@ -132,7 +135,7 @@ internal class ReactTextPropertiesResolver( return null } - private fun getFontSize(): Long? { + private fun getFontSize(shadowNodeWrapper: ShadowNodeWrapper): Long? { val textAttributes = shadowNodeWrapper .getDeclaredShadowNodeField(TEXT_ATTRIBUTES_FIELD_NAME) as? TextAttributes? if (textAttributes != null) { @@ -142,7 +145,7 @@ internal class ReactTextPropertiesResolver( return null } - private fun getFontFamily(): String? { + private fun getFontFamily(shadowNodeWrapper: ShadowNodeWrapper): String? { val fontFamily = shadowNodeWrapper .getDeclaredShadowNodeField(FONT_FAMILY_FIELD_NAME) as? String diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt index 2ef9b9db4..bf549daa2 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt @@ -8,7 +8,7 @@ package com.datadog.reactnative.sessionreplay -import com.datadog.android.api.InternalLogger +import androidx.annotation.VisibleForTesting import com.datadog.reactnative.sessionreplay.utils.ReflectionUtils import com.facebook.react.bridge.ReactContext import com.facebook.react.uimanager.ReactShadowNode @@ -17,48 +17,55 @@ import com.facebook.react.uimanager.UIManagerModule import java.util.concurrent.CountDownLatch internal class ShadowNodeWrapper( - private val logger: InternalLogger, - private val reactContext: ReactContext, - private val uiManagerModule: UIManagerModule?, - private val reflectionUtils: ReflectionUtils = ReflectionUtils(logger) + private val shadowNode: ReactShadowNode>?, + private val reflectionUtils: ReflectionUtils = ReflectionUtils() ) { - private var shadowNode: ReactShadowNode>? = null - - internal fun initialize(viewId: Int): Boolean { - shadowNode = getShadowNode(viewId) - return shadowNode != null - } - internal fun getDeclaredShadowNodeField(fieldName: String): Any? { - return reflectionUtils.getDeclaredField( - shadowNode?.javaClass?.superclass as Class<*>, - shadowNode, - fieldName - ) + return shadowNode?.let { + reflectionUtils.getDeclaredField( + shadowNode, + fieldName + ) + } } - private fun getShadowNode(viewId: Int): ReactShadowNode>? { - val countDownLatch = CountDownLatch(1) - var target: ReactShadowNode>? = null - val shadowNodeRunnable = Runnable { - val node = uiManagerModule?.resolveShadowNode(viewId) - if (node != null) { - target = node + internal companion object { + internal fun getShadowNodeWrapper( + reactContext: ReactContext, + uiManagerModule: UIManagerModule, + reflectionUtils: ReflectionUtils, + viewId: Int + ): ShadowNodeWrapper? { + val countDownLatch = CountDownLatch(1) + var target: ReactShadowNode>? = null + + val shadowNodeRunnable = Runnable { + val node = resolveShadowNode(reflectionUtils, uiManagerModule, viewId) + if (node != null) { + target = node + } + countDownLatch.countDown() } - } - synchronized(this) { + reactContext.runOnNativeModulesQueueThread(shadowNodeRunnable) countDownLatch.await() - return target + + if (target == null) { + return null + } + + return ShadowNodeWrapper(reflectionUtils = reflectionUtils, shadowNode = target) } - } - private fun UIManagerModule.resolveShadowNode(tag: Int): ReactShadowNode>? { - javaClass.getDeclaredField("mUIImplementation").let { - it.isAccessible = true - val value = it.get(this) as UIImplementation - return value.resolveShadowNode(tag) + private fun resolveShadowNode(reflectionUtils: ReflectionUtils, uiManagerModule: UIManagerModule, tag: Int): ReactShadowNode>? { + val uiManagerImplementation = reflectionUtils.getDeclaredField(uiManagerModule, UI_IMPLEMENTATION_FIELD_NAME) as UIImplementation? + ?: return null + + return uiManagerImplementation.resolveShadowNode(tag) } + + @VisibleForTesting + internal const val UI_IMPLEMENTATION_FIELD_NAME = "mUIImplementation" } } 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 751e283ab..6b5330912 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 @@ -8,7 +8,6 @@ package com.datadog.reactnative.sessionreplay.mappers import android.widget.TextView import androidx.annotation.VisibleForTesting -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback import com.datadog.android.sessionreplay.internal.recorder.MappingContext import com.datadog.android.sessionreplay.internal.recorder.mapper.TextViewMapper @@ -19,32 +18,24 @@ import com.datadog.reactnative.sessionreplay.TextPropertiesResolver import com.facebook.react.bridge.ReactContext import com.facebook.react.uimanager.UIManagerModule -internal class ReactTextMapper(): TextViewMapper() { - private var reactTextPropertiesResolver: TextPropertiesResolver = +internal class ReactTextMapper( + private val reactTextPropertiesResolver: TextPropertiesResolver = NoopTextPropertiesResolver() +): TextViewMapper() { internal constructor( - logger: InternalLogger, reactContext: ReactContext, uiManagerModule: UIManagerModule? - ): this() { - if (uiManagerModule == null) { - this.reactTextPropertiesResolver = NoopTextPropertiesResolver() + ): this( + reactTextPropertiesResolver = if (uiManagerModule == null) { + NoopTextPropertiesResolver() } else { - this.reactTextPropertiesResolver = ReactTextPropertiesResolver( - logger = logger, + ReactTextPropertiesResolver( reactContext = reactContext, uiManagerModule = uiManagerModule ) } - } - - @VisibleForTesting - internal constructor( - reactTextPropertiesResolver: TextPropertiesResolver - ): this() { - this.reactTextPropertiesResolver = reactTextPropertiesResolver - } + ) override fun map( view: TextView, diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt index 0202ca130..260939884 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt @@ -6,7 +6,6 @@ package com.datadog.reactnative.sessionreplay.mappers -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback import com.datadog.android.sessionreplay.internal.recorder.MappingContext import com.datadog.android.sessionreplay.internal.recorder.mapper.BaseWireframeMapper @@ -17,9 +16,8 @@ import com.datadog.reactnative.sessionreplay.utils.ReactViewBackgroundDrawableUt import com.facebook.react.views.view.ReactViewGroup internal class ReactViewGroupMapper( - logger: InternalLogger, private val reactViewBackgroundDrawableUtils: ReactViewBackgroundDrawableUtils = - ReactViewBackgroundDrawableUtils(logger), + ReactViewBackgroundDrawableUtils(), private val drawableUtils: DrawableUtils = DrawableUtils() ) : BaseWireframeMapper(), diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt index bb6778416..fabacf4ba 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt @@ -6,15 +6,13 @@ package com.datadog.reactnative.sessionreplay.utils -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.reactnative.sessionreplay.extensions.convertToDensityNormalized import com.facebook.react.uimanager.Spacing import com.facebook.react.views.view.ReactViewBackgroundDrawable internal class ReactViewBackgroundDrawableUtils( - logger: InternalLogger, - private val reflectionUtils: ReflectionUtils = ReflectionUtils(logger) + private val reflectionUtils: ReflectionUtils = ReflectionUtils() ) { internal fun resolveShapeAndBorder( drawable: ReactViewBackgroundDrawable, @@ -43,7 +41,6 @@ internal class ReactViewBackgroundDrawableUtils( backgroundDrawable: ReactViewBackgroundDrawable, ): Int? { return reflectionUtils.getDeclaredField( - backgroundDrawable.javaClass, backgroundDrawable, COLOR_FIELD_NAME ) as Int? diff --git a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReflectionUtils.kt b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReflectionUtils.kt index 77236adde..3e518c165 100644 --- a/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReflectionUtils.kt +++ b/packages/react-native-session-replay/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReflectionUtils.kt @@ -6,13 +6,11 @@ package com.datadog.reactnative.sessionreplay.utils -import com.datadog.android.api.InternalLogger import java.lang.reflect.Field -internal class ReflectionUtils( - private val logger: InternalLogger -) { - internal fun getDeclaredField(className: Class<*>, instance: Any?, fieldName: String): Any? { +internal class ReflectionUtils { + internal fun getDeclaredField(instance: Any, fieldName: String): Any? { + val className = instance.javaClass val declaredField = searchForField(className, fieldName) ?: return null declaredField.let { @@ -22,25 +20,17 @@ internal class ReflectionUtils( } private fun searchForField(className: Class<*>, fieldName: String): Field? { - try { + val isFieldDefinedForClass = className.declaredFields.firstOrNull{ it.name == fieldName } != null + val hasSuperclass = className.superclass != null + + if (isFieldDefinedForClass) { return className.getDeclaredField(fieldName) - } catch (e: NoSuchFieldException) { - if (className.superclass != null) { - searchForField(className.superclass, fieldName) - } else { - logger.log( - level = InternalLogger.Level.WARN, - target = InternalLogger.Target.MAINTAINER, - messageBuilder = { RESOLVE_FIELD_ERROR }, - throwable = e - ) - } } - return null - } + if (hasSuperclass) { + return searchForField(className.superclass, fieldName) + } - private companion object { - private const val RESOLVE_FIELD_ERROR = "Failed to resolve the declared field via reflection." + return null } } 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 83d283b2f..d1d23f522 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 @@ -77,7 +77,7 @@ internal class ReactNativeSessionReplayExtensionSupportTest { } @Test - fun `M return null W getCustomViewMappers() { cannot get uiManagerModule }`() { + fun `M return null W getUiManagerModule() { cannot get uiManagerModule }`() { // Given whenever(mockReactContext.getNativeModule(any>())) .thenThrow(IllegalStateException()) diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolverTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolverTest.kt index a9d4d4ee0..11438b17d 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolverTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolverTest.kt @@ -7,17 +7,21 @@ package com.datadog.reactnative.sessionreplay import android.widget.TextView -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.COLOR_FIELD_NAME import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.FONT_FAMILY_FIELD_NAME +import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.MONOSPACE_FAMILY_NAME import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.TEXT_ATTRIBUTES_FIELD_NAME +import com.datadog.reactnative.sessionreplay.ShadowNodeWrapper.Companion.UI_IMPLEMENTATION_FIELD_NAME import com.datadog.reactnative.sessionreplay.utils.DrawableUtils import com.datadog.reactnative.sessionreplay.utils.ReactViewBackgroundDrawableUtils +import com.datadog.reactnative.sessionreplay.utils.ReflectionUtils import com.datadog.reactnative.sessionreplay.utils.formatAsRgba import com.datadog.reactnative.tools.unit.forge.ForgeConfigurator import com.datadog.tools.unit.GenericAssert.Companion.assertThat import com.facebook.react.bridge.ReactContext +import com.facebook.react.uimanager.ReactShadowNode +import com.facebook.react.uimanager.UIImplementation import com.facebook.react.uimanager.UIManagerModule import com.facebook.react.views.text.TextAttributes import com.facebook.react.views.view.ReactViewBackgroundDrawable @@ -33,6 +37,7 @@ import org.junit.jupiter.api.extension.Extensions import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.whenever import org.mockito.quality.Strictness @@ -58,9 +63,6 @@ internal class ReactTextPropertiesResolverTest { @Mock lateinit var mockTextView: TextView - @Mock - lateinit var mockLogger: InternalLogger - @Mock lateinit var mockDrawableUtils: DrawableUtils @@ -73,25 +75,50 @@ internal class ReactTextPropertiesResolverTest { @Mock lateinit var mockShadowNodeWrapper: ShadowNodeWrapper + @Mock + lateinit var mockReflectionUtils: ReflectionUtils + @Forgery private lateinit var fakeWireframe: MobileSegment.Wireframe.TextWireframe + @Mock + private lateinit var mockUiImplementation: UIImplementation + + @Mock + private lateinit var mockShadowNode: ReactShadowNode> + @BeforeEach fun `set up`(forge: Forge) { + whenever( + mockReflectionUtils.getDeclaredField(mockUiManagerModule, UI_IMPLEMENTATION_FIELD_NAME) + ).thenReturn(mockUiImplementation) + + whenever( + mockUiImplementation.resolveShadowNode( + eq(mockTextView.id) + ) + ).thenReturn(mockShadowNode) + + whenever(mockReactContext.runOnNativeModulesQueueThread(any())).thenAnswer { + (it.arguments[0] as Runnable).run() + } + testedResolver = ReactTextPropertiesResolver( - logger = mockLogger, reactContext = mockReactContext, uiManagerModule = mockUiManagerModule, - shadowNodeWrapper = mockShadowNodeWrapper, reactViewBackgroundDrawableUtils = mockReactViewBackgroundDrawableUtils, - drawableUtils = mockDrawableUtils + drawableUtils = mockDrawableUtils, + reflectionUtils = mockReflectionUtils ) } + // region addReactNativeProperties + @Test fun `M get original wireframe W addReactNativeProperties() { no react properties }`() { // Given whenever(mockTextView.background).thenReturn(null) + whenever(mockUiImplementation.resolveShadowNode(any())).thenReturn(null) // When val result = testedResolver.addReactNativeProperties(mockWireframe, mockTextView, 0f) @@ -145,15 +172,13 @@ internal class ReactTextPropertiesResolverTest { assertThat(result.border?.color).isEqualTo(formatAsRgba(fakeBorderColor)) } - // region addReactNativeProperties - @Test fun `M resolve font family W addReactNativeProperties()`() { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) + whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, FONT_FAMILY_FIELD_NAME)) + .thenReturn(MONOSPACE_FAMILY_NAME) + whenever(mockTextView.background).thenReturn(null) - whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(FONT_FAMILY_FIELD_NAME)) - .thenReturn(ReactTextPropertiesResolver.MONOSPACE_FAMILY_NAME) // When val result = testedResolver @@ -161,13 +186,12 @@ internal class ReactTextPropertiesResolverTest { // Then assertThat(result.textStyle.family) - .isEqualTo(ReactTextPropertiesResolver.MONOSPACE_FAMILY_NAME) + .isEqualTo(MONOSPACE_FAMILY_NAME) } @Test - fun `M fallback W addReactNativeProperties() { cant resolve fontFamily }`() { + fun `M fallback W addReactNativeProperties() { cannot resolve fontFamily }`() { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) whenever(mockTextView.background).thenReturn(null) whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(FONT_FAMILY_FIELD_NAME)) .thenReturn(null) @@ -185,10 +209,9 @@ internal class ReactTextPropertiesResolverTest { @IntForgery fakeTextSize: Int ) { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) - whenever(mockTextView.background).thenReturn(null) - whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(TEXT_ATTRIBUTES_FIELD_NAME)) + whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, TEXT_ATTRIBUTES_FIELD_NAME)) .thenReturn(mockTextAttributes) + whenever(mockTextView.background).thenReturn(null) whenever(mockTextAttributes.effectiveFontSize).thenReturn(fakeTextSize) // When @@ -199,11 +222,10 @@ internal class ReactTextPropertiesResolverTest { } @Test - fun `M fallback W addReactNativeProperties() { cant resolve fontSize }`( + fun `M fallback W addReactNativeProperties() { cannot resolve fontSize }`( @Mock mockTextAttributes: TextAttributes ) { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) whenever(mockTextView.background).thenReturn(null) whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(TEXT_ATTRIBUTES_FIELD_NAME)) .thenReturn(null) @@ -220,9 +242,8 @@ internal class ReactTextPropertiesResolverTest { @IntForgery fakeTextColor: Int ) { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) whenever(mockTextView.background).thenReturn(null) - whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(COLOR_FIELD_NAME)) + whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, COLOR_FIELD_NAME)) .thenReturn(fakeTextColor) // When @@ -233,9 +254,8 @@ internal class ReactTextPropertiesResolverTest { } @Test - fun `M fallback W addReactNativeProperties() { cant resolve fontColor }`() { + fun `M fallback W addReactNativeProperties() { cannot resolve fontColor }`() { // Given - whenever(mockShadowNodeWrapper.initialize(mockTextView.id)).thenReturn(true) whenever(mockTextView.background).thenReturn(null) whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(COLOR_FIELD_NAME)) .thenReturn(null) diff --git a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapperTest.kt b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapperTest.kt index b8e1dcf80..61ac82e98 100644 --- a/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapperTest.kt +++ b/packages/react-native-session-replay/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapperTest.kt @@ -9,7 +9,6 @@ package com.datadog.reactnative.sessionreplay.mappers import android.graphics.drawable.ColorDrawable -import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback import com.datadog.android.sessionreplay.internal.recorder.MappingContext import com.datadog.android.sessionreplay.internal.recorder.SystemInformation @@ -39,9 +38,6 @@ import org.mockito.quality.Strictness internal class ReactViewGroupMapperTest { private lateinit var testedMapper: ReactViewGroupMapper - @Mock - private lateinit var mockLogger: InternalLogger - @Mock private lateinit var mockReactViewBackgroundDrawableUtils: ReactViewBackgroundDrawableUtils @@ -75,7 +71,6 @@ internal class ReactViewGroupMapperTest { whenever(mockSystemInformation.screenDensity).thenReturn(0f) testedMapper = ReactViewGroupMapper( - logger = mockLogger, reactViewBackgroundDrawableUtils = mockReactViewBackgroundDrawableUtils, drawableUtils = mockDrawableUtils )