package com.contentsquare.rn.utils import android.app.Activity import android.view.View import android.webkit.WebView import androidx.test.ext.junit.runners.AndroidJUnit4 import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.UIManager import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.UIManagerModule import com.facebook.react.views.view.ReactViewGroup import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.verify import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) @Config(manifest = Config.NONE) class ReactNativeViewFinderTest { // mocks private val mockWebViewTag = 999 private val mockInvalidWebViewTag = 666 private val mockViewTag = 123 private val mockInvalidViewTag = 456 private val mockActivity = mockk() private val mockWebView = mockk() private val mockView = mockk() private val mockChild1 = mockk() private val mockChild2 = mockk() private val mockFoundReactViewGroup = mockk() private val mockUIManagerModule = mockk() /// ?? private val mockReactApplicationContext = mockk() private val mockReactNativeUiThreadUtil = mockk() private val mockUIManager = mockk() @Before fun setup() { every { mockChild1.childCount } returns 0 every { mockChild2.childCount } returns 2 every { mockChild2.getChildAt(0) } returns mockWebView every { mockChild2.getChildAt(1) } returns mockk() every { mockFoundReactViewGroup.childCount } returns 3 every { mockFoundReactViewGroup.getChildAt(0) } returns mockk() every { mockFoundReactViewGroup.getChildAt(1) } returns mockChild1 every { mockFoundReactViewGroup.getChildAt(2) } returns mockChild2 every { mockUIManagerModule.resolveView(mockWebViewTag) } returns mockFoundReactViewGroup every { mockUIManagerModule.resolveView(mockInvalidWebViewTag) } returns null every { mockUIManagerModule.resolveView(mockViewTag) } returns mockView every { mockUIManagerModule.resolveView(mockInvalidViewTag) } returns null every { mockReactApplicationContext.currentActivity } returns mockActivity every { hint(UIManagerModule::class) mockReactApplicationContext.getNativeModule(UIManagerModule::class.java) } returns mockUIManagerModule every { mockReactNativeUiThreadUtil.isOnUiThread } returns true } // non-mocks private val underTest = ReactNativeViewFinder(mockReactNativeUiThreadUtil) @Test fun `Given valid webViewTag, When find webView, Then return webView`() { var foundWebView: WebView? = null mockkStatic(UIManagerHelper::class) val listener = ReactNativeViewFinder.OnWebViewFoundListener { webView -> foundWebView = webView } every { UIManagerHelper.getUIManager( any(), any() ) } returns mockUIManager every { mockUIManager.resolveView(any()) } returns mockWebView underTest.findWebView(mockReactApplicationContext, mockWebViewTag, listener) assertEquals( mockWebView, foundWebView ) } @Test fun `Given invalid webViewTag, When find webView, Then log error and do not call listener`() { mockkStatic(UIManagerHelper::class) every { UIManagerHelper.getUIManager( any(), any() ) } returns mockUIManager every { mockUIManager.resolveView(any()) } returns null val listener = mockk(relaxed = true) underTest.findWebView(mockReactApplicationContext, mockInvalidWebViewTag, listener) verify(exactly = 0) { listener.onWebViewFound(any()) } } @Test fun `Given valid viewTag, When find view, Then return view`() { var foundView: View? = null mockkStatic(UIManagerHelper::class) every { UIManagerHelper.getUIManager( any(), any() ) } returns mockUIManager every { mockUIManager.resolveView(any()) } returns mockView val listener = ReactNativeViewFinder.OnViewFoundListener { view -> foundView = view } underTest.findView(mockReactApplicationContext, mockViewTag, listener) assertEquals(mockView, foundView) } @Test fun `Given invalid viewTag, When find view, Then log error and do not call listener`() { mockkStatic(UIManagerHelper::class) every { UIManagerHelper.getUIManager( any(), any() ) } returns mockUIManager every { mockUIManager.resolveView(any()) } returns null val listener = mockk(relaxed = true) underTest.findView(mockReactApplicationContext, mockInvalidViewTag, listener) verify(exactly = 0) { listener.onViewFound(any()) } } }