package com.dxareactnative.navigation import com.dxareactnative.testutils.MockQualtricsLogRule import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableMap import com.qualtrics.dxa.ScreenChangeType import com.qualtrics.dxa.ScreenDetectionType import com.qualtrics.dxa.ScreenHierarchyElement import io.mockk.MockKAnnotations import io.mockk.clearAllMocks import io.mockk.every import io.mockk.impl.annotations.RelaxedMockK import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Before import org.junit.Rule import org.junit.Test class ScreenChangePayloadParserTest { @get:Rule val mockQualtricsLogRule = MockQualtricsLogRule() @RelaxedMockK private lateinit var mockScreenChangePayload: ReadableMap @RelaxedMockK private lateinit var mockScreenHierarchy: ReadableArray @RelaxedMockK private lateinit var mockScreenHierarchyElement1: ReadableMap @RelaxedMockK private lateinit var mockScreenHierarchyElement2: ReadableMap @RelaxedMockK private lateinit var mockScreenHierarchyElement3: ReadableMap private val validScreenHierarchy = listOf( ScreenHierarchyElement("Home", "drawer-navigator"), ScreenHierarchyElement("Search", "top-tabs-navigator"), ScreenHierarchyElement("ItemDetails", "screen"), ) private val validChangeType = ScreenChangeType.APPEAR private val validDetectionType = ScreenDetectionType.MANUAL @Before fun setup() { MockKAnnotations.init(this) every { mockScreenChangePayload.getArray("screenHierarchy") } returns mockScreenHierarchy every { mockScreenChangePayload.getString("changeType") } returns validChangeType.value every { mockScreenChangePayload.getString("detectionType") } returns validDetectionType.value every { mockScreenHierarchy.size() } returns 3 every { mockScreenHierarchy.getMap(0) } returns mockScreenHierarchyElement1 every { mockScreenHierarchy.getMap(1) } returns mockScreenHierarchyElement2 every { mockScreenHierarchy.getMap(2) } returns mockScreenHierarchyElement3 val validElement1 = validScreenHierarchy[0] every { mockScreenHierarchyElement1.getString("screenName") } returns validElement1.screenName every { mockScreenHierarchyElement1.getString("screenType") } returns validElement1.screenType val validElement2 = validScreenHierarchy[1] every { mockScreenHierarchyElement2.getString("screenName") } returns validElement2.screenName every { mockScreenHierarchyElement2.getString("screenType") } returns validElement2.screenType val validElement3 = validScreenHierarchy[2] every { mockScreenHierarchyElement3.getString("screenName") } returns validElement3.screenName every { mockScreenHierarchyElement3.getString("screenType") } returns validElement3.screenType } @After fun tearDown() { clearAllMocks() } @Test fun `GIVEN a valid screen change payload WHEN parsed THEN it parses correctly`() { val result = parseScreenChangePayload(mockScreenChangePayload) assertNotNull(result) val (screenHierarchy, changeType, detectionType) = result!! assertEquals(screenHierarchy, validScreenHierarchy) assertEquals(changeType, validChangeType) assertEquals(detectionType, validDetectionType) } @Test fun `GIVEN a null screen hierarchy WHEN parsed THEN result is null`() { every { mockScreenChangePayload.getArray("screenHierarchy") } returns null val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN an empty screen hierarchy WHEN parsed THEN result is null`() { every { mockScreenHierarchy.size() } returns 0 val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN a screen hierarchy with a null element WHEN parsed THEN result is null`() { every { mockScreenHierarchy.getMap(0) } returns null val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN a screen hierarchy element with a null screenName WHEN parsed THEN result is null`() { every { mockScreenHierarchyElement1.getString("screenName") } returns null val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN a screen hierarchy element with an empty screenName WHEN parsed THEN result is null`() { every { mockScreenHierarchyElement1.getString("screenName") } returns "" val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN a screen hierarchy element with a null screenType WHEN parsed THEN default screenType is used`() { every { mockScreenHierarchyElement1.getString("screenType") } returns null val result = parseScreenChangePayload(mockScreenChangePayload) val screenHierarchy = result!!.first assertEquals(screenHierarchy[0].screenName, validScreenHierarchy[0].screenName) assertEquals(screenHierarchy[0].screenType, "screen") } @Test fun `GIVEN a screen hierarchy element with a empty screenType WHEN parsed THEN default screenType is used`() { every { mockScreenHierarchyElement1.getString("screenType") } returns "" val result = parseScreenChangePayload(mockScreenChangePayload) val screenHierarchy = result!!.first assertEquals(screenHierarchy[0].screenName, validScreenHierarchy[0].screenName) assertEquals(screenHierarchy[0].screenType, "screen") } @Test fun `GIVEN a null changeType WHEN parsed THEN result is null`() { every { mockScreenChangePayload.getString("changeType") } returns null val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN an incorrect changeType WHEN parsed THEN result is null`() { every { mockScreenChangePayload.getString("changeType") } returns "xyz" val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN a null detectionType WHEN parsed THEN result is null`() { every { mockScreenChangePayload.getString("detectionType") } returns null val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } @Test fun `GIVEN an incorrect detectionType WHEN parsed THEN result is null`() { every { mockScreenChangePayload.getString("detectionType") } returns "xyz" val result = parseScreenChangePayload(mockScreenChangePayload) assertNull(result) } }