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 CSQTrackingTest { private val mockReactNativeUiThreadUtil: ReactNativeUiThreadUtil = mockk() private lateinit var underTest: CSQTracking @Before fun setup() { val slot = slot() every { mockReactNativeUiThreadUtil.runOnUiThread(capture(slot)) } answers { slot.captured.run() Unit } underTest = CSQTracking(mockReactNativeUiThreadUtil) } @After fun tearDown() { unmockkAll() } @Test fun `stop should execute on UI thread`() { // Given mockkStatic(CSQ::class) every { CSQ.stop() } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.stop() // Then assert(isExecutedOnUiThread) { "stop should be executed on UI thread" } } @Test fun `stop should call CSQ stop`() { // Given mockkStatic(CSQ::class) every { CSQ.stop() } returns Unit // When underTest.stop() // Then verify(exactly = 1) { CSQ.stop() } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } @Test fun `pauseTracking should execute on UI thread`() { // Given mockkStatic(CSQ::class) every { CSQ.pauseTracking() } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.pauseTracking() // Then assert(isExecutedOnUiThread) { "pauseTracking should be executed on UI thread" } } @Test fun `pauseTracking should call CSQ pauseTracking`() { // Given mockkStatic(CSQ::class) every { CSQ.pauseTracking() } returns Unit // When underTest.pauseTracking() // Then verify(exactly = 1) { CSQ.pauseTracking() } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } @Test fun `resumeTracking should execute on UI thread`() { // Given mockkStatic(CSQ::class) every { CSQ.resumeTracking() } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.resumeTracking() // Then assert(isExecutedOnUiThread) { "resumeTracking should be executed on UI thread" } } @Test fun `resumeTracking should call CSQ resumeTracking`() { // Given mockkStatic(CSQ::class) every { CSQ.resumeTracking() } returns Unit // When underTest.resumeTracking() // Then verify(exactly = 1) { CSQ.resumeTracking() } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } @Test fun `addDynamicVar with String value should execute on UI thread`() { // Given val mockKey = "testKey" val mockValue = "testValue" mockkStatic(CSQ::class) every { CSQ.addDynamicVar(mockKey, mockValue) } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.addDynamicVar(mockKey, mockValue) // Then assert(isExecutedOnUiThread) { "addDynamicVar with String value should be executed on UI thread" } } @Test fun `addDynamicVar with String value should call CSQ addDynamicVar`() { // Given val mockKey = "testKey" val mockValue = "testValue" mockkStatic(CSQ::class) every { CSQ.addDynamicVar(mockKey, mockValue) } returns Unit // When underTest.addDynamicVar(mockKey, mockValue) // Then verify(exactly = 1) { CSQ.addDynamicVar(mockKey, mockValue) } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } @Test fun `addDynamicVar with Double value should execute on UI thread`() { // Given val mockKey = "testKey" val mockValue = 123.45 mockkStatic(CSQ::class) every { CSQ.addDynamicVar(mockKey, mockValue.toLong()) } returns Unit var isExecutedOnUiThread = false every { mockReactNativeUiThreadUtil.runOnUiThread(any()) } answers { isExecutedOnUiThread = true firstArg().run() } // When underTest.addDynamicVar(mockKey, mockValue) // Then assert(isExecutedOnUiThread) { "addDynamicVar with Double value should be executed on UI thread" } } @Test fun `addDynamicVar with Double should call CSQ addDynamicVar with Long conversion`() { // Given val mockKey = "testKey" val mockValue = 123.45 val expectedLongValue = mockValue.toLong() mockkStatic(CSQ::class) every { CSQ.addDynamicVar(mockKey, expectedLongValue) } returns Unit // When underTest.addDynamicVar(mockKey, mockValue) // Then verify(exactly = 1) { CSQ.addDynamicVar(mockKey, expectedLongValue) } verify(exactly = 1) { mockReactNativeUiThreadUtil.runOnUiThread(any()) } } }