Skip to content

Commit

Permalink
NAVAND-1472: do not always relaunch timer when routes are updated
Browse files Browse the repository at this point in the history
  • Loading branch information
dzinad committed Sep 3, 2023
1 parent cdc8ce5 commit 1c6af44
Show file tree
Hide file tree
Showing 21 changed files with 1,137 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import com.mapbox.navigation.core.directions.session.RoutesUpdatedResult
import com.mapbox.navigation.core.routerefresh.RouteRefreshExtra
import com.mapbox.navigation.instrumentation_tests.R
import com.mapbox.navigation.instrumentation_tests.activity.EmptyTestActivity
import com.mapbox.navigation.instrumentation_tests.utils.DelayedResponseModifier
import com.mapbox.navigation.instrumentation_tests.utils.DynamicResponseModifier
import com.mapbox.navigation.instrumentation_tests.utils.http.MockDirectionsRefreshHandler
import com.mapbox.navigation.instrumentation_tests.utils.http.MockDirectionsRequestHandler
import com.mapbox.navigation.instrumentation_tests.utils.http.MockRoutingTileEndpointErrorRequestHandler
import com.mapbox.navigation.instrumentation_tests.utils.http.NthAttemptHandler
import com.mapbox.navigation.instrumentation_tests.utils.location.MockLocationReplayerRule
import com.mapbox.navigation.instrumentation_tests.utils.location.stayOnPosition
import com.mapbox.navigation.instrumentation_tests.utils.readRawFileText
import com.mapbox.navigation.testing.ui.BaseTest
import com.mapbox.navigation.testing.ui.http.MockRequestHandler
Expand All @@ -31,13 +33,15 @@ import com.mapbox.navigation.testing.ui.utils.coroutines.getSuccessfulResultOrTh
import com.mapbox.navigation.testing.ui.utils.coroutines.requestRoutes
import com.mapbox.navigation.testing.ui.utils.coroutines.routesUpdates
import com.mapbox.navigation.testing.ui.utils.coroutines.sdkTest
import com.mapbox.navigation.testing.ui.utils.coroutines.setNavigationRoutesAndWaitForAlternativesUpdate
import com.mapbox.navigation.testing.ui.utils.coroutines.setNavigationRoutesAndWaitForUpdate
import com.mapbox.navigation.testing.ui.utils.getMapboxAccessTokenFromResources
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.withTimeout
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -174,6 +178,193 @@ class RouteRefreshOnDemandTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::
)
}

@Test
fun route_refresh_on_demand_after_alternatives_change_between_attempts() = sdkTest {
createMapboxNavigation(createRouteRefreshOptionsWithInvalidInterval(5_000))
mockWebServerRule.requestHandlers.add(
MockDirectionsRequestHandler(
"driving-traffic",
readRawFileText(activity, R.raw.route_response_route_refresh),
twoCoordinates
)
)
val refreshHandler = MockDirectionsRefreshHandler(
"route_response_route_refresh",
readRawFileText(activity, R.raw.route_response_route_refresh_annotations),
)
refreshHandler.jsonResponseModifier = DynamicResponseModifier()
mockWebServerRule.requestHandlers.add(NthAttemptHandler(refreshHandler, 1))
val observer = TestObserver()

mapboxNavigation.routeRefreshController.registerRouteRefreshStateObserver(observer)
mapboxNavigation.startTripSession()
val routeOptions = generateRouteOptions(twoCoordinates)
val requestedRoutes = mapboxNavigation.requestRoutes(routeOptions)
.getSuccessfulResultOrThrowException()
.routes
val initialRoutes = requestedRoutes.take(1)
mapboxNavigation.setNavigationRoutesAndWaitForUpdate(initialRoutes)

delay(7000) // in-between attempts

// add alternatives
mapboxNavigation.setNavigationRoutesAndWaitForAlternativesUpdate(requestedRoutes)

val refreshes = mutableListOf<RoutesUpdatedResult>()
mapboxNavigation.registerRoutesObserver {
if (it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REFRESH &&
it.navigationRoutes.map { it.id } == requestedRoutes.map { it.id }) {
refreshes.add(it)
}
}
mapboxNavigation.routeRefreshController.requestImmediateRouteRefresh()

delay(4000)
assertEquals(1, refreshes.size) // 1 refresh from refresh on demand

withTimeout(2500) { // 5s interval, 1.5s accuracy
while (refreshes.size < 2) {
delay(100)
}
}
assertEquals(2, refreshes.size)

assertEquals(
listOf(
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_CANCELED,
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_FINISHED_SUCCESS,
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_FINISHED_SUCCESS,
),
observer.getStatesSnapshot()
)
}

@Test
fun route_refresh_on_demand_after_reroute() = sdkTest {
createMapboxNavigation(createRouteRefreshOptionsWithInvalidInterval(5_000))
setupMockRequestHandlers(baseRefreshHandler)

val observer = TestObserver()

mapboxNavigation.routeRefreshController.registerRouteRefreshStateObserver(observer)
mapboxNavigation.startTripSession()
val routeOptions = generateRouteOptions(twoCoordinates)
val requestedRoutes = mapboxNavigation.requestRoutes(routeOptions)
.getSuccessfulResultOrThrowException()
.routes
val offRouteLocation = mockLocationUpdatesRule.generateLocationUpdate {
latitude = twoCoordinates[0].latitude() + 0.002
longitude = twoCoordinates[0].longitude() + 0.001
}

mockWebServerRule.requestHandlers.clear()
mockWebServerRule.requestHandlers.add(
MockDirectionsRequestHandler(
"driving-traffic",
readRawFileText(activity, R.raw.route_response_reroute_for_refresh),
listOf(
Point.fromLngLat(offRouteLocation.longitude, offRouteLocation.latitude),
twoCoordinates[1]
)
)
)
mockWebServerRule.requestHandlers.add(
MockDirectionsRefreshHandler(
"route_response_reroute_for_refresh",
readRawFileText(activity, R.raw.route_response_reroute_for_refresh_refreshed)
)
)

mapboxNavigation.setNavigationRoutesAndWaitForUpdate(requestedRoutes)

delay(1000)
// off-route
stayOnPosition(offRouteLocation.latitude, offRouteLocation.longitude, 120f) {
val reroute = mapboxNavigation.routesUpdates().first {
it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REROUTE
}

mapboxNavigation.routeRefreshController.requestImmediateRouteRefresh()

val refresh = withTimeout(3000) {
mapboxNavigation.routesUpdates().first { it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REFRESH }
}
assertEquals(reroute.navigationRoutes.map { it.id }, refresh.navigationRoutes.map { it.id })

assertEquals(
listOf(
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_FINISHED_SUCCESS,
),
observer.getStatesSnapshot()
)
}
}

@Test
fun routes_are_updated_while_refresh_on_demand_request_is_in_progress() = sdkTest {
createMapboxNavigation(createRouteRefreshOptionsWithInvalidInterval(100_000))
mockWebServerRule.requestHandlers.add(
MockDirectionsRequestHandler(
"driving-traffic",
readRawFileText(activity, R.raw.route_response_route_refresh),
twoCoordinates
)
)
val refreshHandler = MockDirectionsRefreshHandler(
"route_response_route_refresh",
readRawFileText(activity, R.raw.route_response_route_refresh_annotations),
)
refreshHandler.jsonResponseModifier = DelayedResponseModifier(3000, DynamicResponseModifier())
mockWebServerRule.requestHandlers.add(refreshHandler)
val observer = TestObserver()

mapboxNavigation.routeRefreshController.registerRouteRefreshStateObserver(observer)
mapboxNavigation.startTripSession()
val routeOptions = generateRouteOptions(twoCoordinates)
val requestedRoutes = mapboxNavigation.requestRoutes(routeOptions)
.getSuccessfulResultOrThrowException()
.routes
val initialRoutes = requestedRoutes.take(1)
mapboxNavigation.setNavigationRoutesAndWaitForUpdate(initialRoutes)

val refreshes = mutableListOf<RoutesUpdatedResult>()
mapboxNavigation.registerRoutesObserver {
if (it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REFRESH) {
refreshes.add(it)
}
}

mapboxNavigation.routeRefreshController.requestImmediateRouteRefresh()

delay(1000)
mapboxNavigation.setNavigationRoutesAndWaitForAlternativesUpdate(requestedRoutes)

delay(3000)
assertEquals(0, refreshes.size)

mapboxNavigation.routeRefreshController.requestImmediateRouteRefresh()
val refreshedRoutes = withTimeout(7000) {// 2 routes with delay 3s each
mapboxNavigation.routesUpdates().first {
it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REFRESH
}.navigationRoutes
}
assertEquals(requestedRoutes.map { it.id }, refreshedRoutes.map { it.id })

assertEquals(
listOf(
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_CANCELED,
RouteRefreshExtra.REFRESH_STATE_STARTED,
RouteRefreshExtra.REFRESH_STATE_FINISHED_SUCCESS,
),
observer.getStatesSnapshot()
)
}

private fun createMapboxNavigation(routeRefreshOptions: RouteRefreshOptions) {
mapboxNavigation = MapboxNavigationProvider.create(
NavigationOptions.Builder(activity)
Expand Down
Loading

0 comments on commit 1c6af44

Please sign in to comment.