package com.contentsquare.rn.csq import com.contentsquare.CSQ import com.contentsquare.rn.utils.ReactNativeUiThreadUtil import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.slot import io.mockk.unmockkAll import io.mockk.verify import org.junit.After import org.junit.Before import org.junit.Test class CSQErrorTrackingTest { private val mockReactNativeUiThreadUtil: ReactNativeUiThreadUtil = mockk() private lateinit var underTest: CSQErrorTracking @Before fun setup() { val slot = slot() every { mockReactNativeUiThreadUtil.runOnUiThread(capture(slot)) } answers { slot.captured.run() Unit } underTest = CSQErrorTracking(mockReactNativeUiThreadUtil) } @After fun tearDown() { unmockkAll() } @Test fun `setUrlMaskingPatterns should execute on UI thread`() { // Given val mockPatterns = listOf("https://example.com/*", "https://test.com/api/*") mockkStatic(CSQ::class) every { CSQ.setUrlMaskingPatterns(mockPatterns) } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.setUrlMaskingPatterns(mockPatterns) // Then assert(isExecutedOnUiThread) { "setUrlMaskingPatterns should be executed on UI thread" } } @Test fun `setUrlMaskingPatterns should handle empty list`() { // Given val emptyPatterns = emptyList() mockkStatic(CSQ::class) every { CSQ.setUrlMaskingPatterns(emptyPatterns) } returns Unit // When underTest.setUrlMaskingPatterns(emptyPatterns) // Then verify(exactly = 1) { CSQ.setUrlMaskingPatterns(emptyPatterns) } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } @Test fun `triggerNativeCrash should throw RuntimeException with expected message`() { // When & Then try { underTest.triggerNativeCrash() assert(false) { "Expected RuntimeException to be thrown" } } catch (e: RuntimeException) { assert(e.message == "This is purposely triggered native crash.") { "Exception message should match expected crash message" } } } @Test fun `triggerNativeCrash should not interact with UI thread util`() { // Given var uiThreadCalled = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { uiThreadCalled = true firstArg().run() } // When & Then try { underTest.triggerNativeCrash() assert(false) { "Expected RuntimeException to be thrown" } } catch (e: RuntimeException) { // Expected } assert(!uiThreadCalled) { "triggerNativeCrash should not use UI thread util" } } }