diff --git a/libdirections-onboard/src/test/java/com/mapbox/navigation/route/onboard/task/RemoveTilesTaskTest.kt b/libdirections-onboard/src/test/java/com/mapbox/navigation/route/onboard/task/RemoveTilesTaskTest.kt index 82e34e73e2d..3286bf9e848 100644 --- a/libdirections-onboard/src/test/java/com/mapbox/navigation/route/onboard/task/RemoveTilesTaskTest.kt +++ b/libdirections-onboard/src/test/java/com/mapbox/navigation/route/onboard/task/RemoveTilesTaskTest.kt @@ -4,11 +4,16 @@ import com.mapbox.geojson.Point import com.mapbox.navigation.navigator.MapboxNativeNavigator import com.mapbox.navigation.route.onboard.OnOfflineTilesRemovedCallback import com.mapbox.navigation.testing.MainCoroutineRule +import com.mapbox.navigation.utils.thread.ThreadController import io.mockk.every import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.unmockkObject import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.InternalCoroutinesApi +import org.junit.After +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -31,6 +36,17 @@ class RemoveTilesTaskTest { @get:Rule var coroutineRule = MainCoroutineRule() + @Before + fun setUp() { + mockkObject(ThreadController) + every { ThreadController.IODispatcher } returns coroutineRule.testDispatcher + } + + @After + fun cleanUp() { + unmockkObject(ThreadController) + } + @Test fun checksOnRemoveIsCalledWhenTilesAreRemoved() = coroutineRule.runBlockingTest { every { navigator.removeTiles(tilePath, southwest, northeast) } returns 9L diff --git a/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt b/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt index a4c8573df5b..a5e19041a36 100644 --- a/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt +++ b/libnavigation-core/src/main/java/com/mapbox/navigation/core/MapboxNavigation.kt @@ -501,16 +501,21 @@ constructor( } ) - val bearings = mutableListOf>() + val bearings = mutableListOf?>() val originTolerance = routeOptions.bearingsList()?.getOrNull(0)?.getOrNull(1) ?: DEFAULT_REROUTE_BEARING_TOLERANCE val currentAngle = location.bearing.toDouble() bearings.add(listOf(currentAngle, originTolerance)) - bearings.addAll( - routeOptions.bearingsList()?.subList(index + 1, coordinates.size) ?: emptyList() - ) + val originalBearings = routeOptions.bearingsList() + if (originalBearings != null) { + bearings.addAll(originalBearings.subList(index + 1, coordinates.size)) + } else { + while (bearings.size < coordinates.size) { + bearings.add(null) + } + } optionsBuilder.bearingsList(bearings) diff --git a/libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt b/libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt index 6f51889d3f3..f12bd126fc6 100644 --- a/libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt +++ b/libnavigation-core/src/test/java/com/mapbox/navigation/core/MapboxNavigationTest.kt @@ -8,6 +8,7 @@ import com.mapbox.android.core.location.LocationEngineRequest import com.mapbox.annotation.navigation.module.MapboxNavigationModuleType import com.mapbox.api.directions.v5.models.DirectionsRoute import com.mapbox.api.directions.v5.models.RouteOptions +import com.mapbox.geojson.Point import com.mapbox.navigation.base.options.MapboxOnboardRouterConfig import com.mapbox.navigation.base.options.NavigationOptions import com.mapbox.navigation.base.route.Router @@ -20,6 +21,7 @@ import com.mapbox.navigation.core.fasterroute.FasterRouteDetector import com.mapbox.navigation.core.fasterroute.FasterRouteObserver import com.mapbox.navigation.core.module.NavigationModuleProvider import com.mapbox.navigation.core.trip.service.TripService +import com.mapbox.navigation.core.trip.session.OffRouteObserver import com.mapbox.navigation.core.trip.session.TripSession import com.mapbox.navigation.utils.extensions.inferDeviceLocale import com.mapbox.navigation.utils.timer.MapboxTimer @@ -34,6 +36,7 @@ import java.util.Locale import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.InternalCoroutinesApi import org.junit.After +import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.BeforeClass @@ -65,6 +68,9 @@ class MapboxNavigationTest { private lateinit var mapboxNavigation: MapboxNavigation companion object { + private const val DEFAULT_REROUTE_BEARING_TOLERANCE = 90.0 + private const val DEFAULT_REROUTE_BEARING_ANGLE = 11f + @BeforeClass @JvmStatic fun initialize() { @@ -212,6 +218,74 @@ class MapboxNavigationTest { verify(exactly = 0) { fasterRouteObserver.onFasterRouteAvailable(routes[0]) } } + @Test + fun reRoute_called() { + val offRouteObserverSlot = slot() + verify { tripSession.registerOffRouteObserver(capture(offRouteObserverSlot)) } + + offRouteObserverSlot.captured.onOffRouteStateChanged(true) + + verify(exactly = 1) { directionsSession.requestRoutes(any(), any()) } + } + + @Test + fun reRoute_called_with_null_bearings() { + val routeOptions = provideRouteOptionsWithCoordinates() + every { directionsSession.getRouteOptions() } returns routeOptions + + val offRouteObserverSlot = slot() + verify { tripSession.registerOffRouteObserver(capture(offRouteObserverSlot)) } + + offRouteObserverSlot.captured.onOffRouteStateChanged(true) + + val optionsSlot = slot() + verify(exactly = 1) { directionsSession.requestRoutes(capture(optionsSlot), any()) } + + val expectedBearings = listOf( + listOf(DEFAULT_REROUTE_BEARING_ANGLE.toDouble(), DEFAULT_REROUTE_BEARING_TOLERANCE), + null, + null, + null + ) + val actualBearings = optionsSlot.captured.bearingsList() + + assertEquals(expectedBearings, actualBearings) + } + + @Test + fun reRoute_called_with_bearings() { + val routeOptions = provideRouteOptionsWithCoordinatesAndBearings() + every { directionsSession.getRouteOptions() } returns routeOptions + + val offRouteObserverSlot = slot() + verify { tripSession.registerOffRouteObserver(capture(offRouteObserverSlot)) } + + offRouteObserverSlot.captured.onOffRouteStateChanged(true) + + val optionsSlot = slot() + verify(exactly = 1) { directionsSession.requestRoutes(capture(optionsSlot), any()) } + + val expectedBearings = listOf( + listOf(DEFAULT_REROUTE_BEARING_ANGLE.toDouble(), 10.0), + listOf(20.0, 20.0), + listOf(30.0, 30.0), + listOf(40.0, 40.0) + ) + val actualBearings = optionsSlot.captured.bearingsList() + + assertEquals(expectedBearings, actualBearings) + } + + @Test + fun reRoute_not_called() { + val offRouteObserverSlot = slot() + verify { tripSession.registerOffRouteObserver(capture(offRouteObserverSlot)) } + + offRouteObserverSlot.captured.onOffRouteStateChanged(false) + + verify(exactly = 0) { directionsSession.requestRoutes(any(), any()) } + } + private fun mockTripService() { every { NavigationComponentProvider.createTripService( @@ -232,7 +306,7 @@ class MapboxNavigationTest { private fun mockLocation() { every { location.longitude } returns -122.789876 every { location.latitude } returns 37.657483 - every { location.bearing } returns 10f + every { location.bearing } returns DEFAULT_REROUTE_BEARING_ANGLE } private fun mockDirectionSession() { @@ -256,6 +330,7 @@ class MapboxNavigationTest { } returns tripSession every { tripSession.getEnhancedLocation() } returns location every { tripSession.getRouteProgress() } returns routeProgress + every { tripSession.getRawLocation() } returns location } private fun provideDefaultRouteOptionsBuilder() = @@ -268,6 +343,27 @@ class MapboxNavigationTest { .geometries("") .requestUuid("") + private fun provideRouteOptionsWithCoordinates() = + provideDefaultRouteOptionsBuilder() + .coordinates(listOf( + Point.fromLngLat(1.0, 1.0), + Point.fromLngLat(1.0, 1.0), + Point.fromLngLat(1.0, 1.0), + Point.fromLngLat(1.0, 1.0))) + .build() + + private fun provideRouteOptionsWithCoordinatesAndBearings() = + provideRouteOptionsWithCoordinates() + .toBuilder() + .bearingsList(listOf( + listOf(10.0, 10.0), + listOf(20.0, 20.0), + listOf(30.0, 30.0), + listOf(40.0, 40.0), + listOf(50.0, 50.0), + listOf(60.0, 60.0))) + .build() + @After fun tearDown() { unmockkObject(NavigationModuleProvider)